diff --git a/CHANGELOG.md b/CHANGELOG.md index a34782ea3c..0b80d16db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ # MULTISIG UPGRADE Temporary section for maintaining breaking changes from individual PRs, which will be consolidated into a single changelog entry when the feature branch is merged into `dev`. +- **Breaking change (code, wire, consensus)**: `sov_accounts::CallMessage` gains three variants — `AddCredentialToAddress { address, credential }`, `RemoveCredentialFromAddress { address, credential }`, and `RotateCredentialOnAddress { address, old_credential, new_credential }` — and is now generic in `S: Spec`. The enum's wire format changes, which changes the chain hash. All three new variants require `context.sender() == address` (callers can only modify credentials on the address they are currently signing as); `InsertCredentialId` semantics are unchanged. `Rotate` is functionally equivalent to a `Remove` + `Add` collapsed into a single call for key rotation. There is no orphan guard on remove. - #2688 **Breaking change(code, state, consensus)**: The transaction formats have changed in this version. This is a consensus breaking change and requires coordinating an upgrade using `--stop-at-rollup-height`, and using sov-rollup-manager for full resyncs from this point onwards for existing rollups. This fixes Credential ID malleability that allowed the same set of signed bytes to be replayed for different credentials, across V0 and V1 (multisig) transactions and with different V1 multisig parameters. * The on-chain transaction data has changed, and multisig transactions now explicitly include the multisig id as part of the signed bytes. * Previous signatures are no longer valid. Clients will need to upgrade to our latest SDKs to be able to sign transactions in the new format. diff --git a/crates/fuzz/fuzz_targets/accounts_call_random.rs b/crates/fuzz/fuzz_targets/accounts_call_random.rs index f6cfa6498c..43997b82ba 100644 --- a/crates/fuzz/fuzz_targets/accounts_call_random.rs +++ b/crates/fuzz/fuzz_targets/accounts_call_random.rs @@ -9,9 +9,10 @@ use sov_test_utils::storage::SimpleStorageManager; use sov_test_utils::TestStorageSpec; type S = sov_test_utils::TestSpec; +type FuzzInput<'a> = (&'a [u8], Vec<(Context, CallMessage)>); // Check arbitrary, random calls -fuzz_target!(|input: (&[u8], Vec<(Context, CallMessage)>)| { +fuzz_target!(|input: FuzzInput| { let storage_manager = SimpleStorageManager::::new(); let storage = storage_manager.create_storage(); let mut state = StateCheckpoint::new(storage, &MockKernel::::default(), None); diff --git a/crates/fuzz/fuzz_targets/accounts_parse_call_message.rs b/crates/fuzz/fuzz_targets/accounts_parse_call_message.rs index 267724873b..de15cfe2e4 100644 --- a/crates/fuzz/fuzz_targets/accounts_parse_call_message.rs +++ b/crates/fuzz/fuzz_targets/accounts_parse_call_message.rs @@ -3,8 +3,10 @@ use libfuzzer_sys::fuzz_target; use sov_accounts::CallMessage; -fuzz_target!(|input: CallMessage| { +type S = sov_test_utils::TestSpec; + +fuzz_target!(|input: CallMessage| { let json = serde_json::to_vec(&input).unwrap(); - let msg = serde_json::from_slice::(&json).unwrap(); + let msg = serde_json::from_slice::>(&json).unwrap(); assert_eq!(input, msg); }); diff --git a/crates/fuzz/fuzz_targets/accounts_parse_call_message_random.rs b/crates/fuzz/fuzz_targets/accounts_parse_call_message_random.rs index d49dbf8cf6..05b4c428bd 100644 --- a/crates/fuzz/fuzz_targets/accounts_parse_call_message_random.rs +++ b/crates/fuzz/fuzz_targets/accounts_parse_call_message_random.rs @@ -3,6 +3,8 @@ use libfuzzer_sys::fuzz_target; use sov_accounts::CallMessage; +type S = sov_test_utils::TestSpec; + fuzz_target!(|input: &[u8]| { - serde_json::from_slice::(input).ok(); + serde_json::from_slice::>(input).ok(); }); diff --git a/crates/module-system/module-implementations/integration-tests/tests/stf_blueprint/operator/auth_eip712.rs b/crates/module-system/module-implementations/integration-tests/tests/stf_blueprint/operator/auth_eip712.rs index cd4e152d2c..5b6940971e 100644 --- a/crates/module-system/module-implementations/integration-tests/tests/stf_blueprint/operator/auth_eip712.rs +++ b/crates/module-system/module-implementations/integration-tests/tests/stf_blueprint/operator/auth_eip712.rs @@ -175,9 +175,9 @@ pub fn sign_utx_in_place>( } /// Signs a V1 (multisig) unsigned transaction with the given private key using EIP712. -/// The credential_address is computed from the provided multisig. `target_address` is -/// forwarded into the signed `UnsignedTransactionV1`; pass `None` to match pre-target -/// routing or `Some(X)` to sign for a specific target account. +/// The credential_address is computed from the provided multisig. +/// `target_address` is forwarded into the signed `UnsignedTransactionV1`; +/// pass `None` to match pre-target routing or `Some(X)` to sign for a specific target account. pub fn sign_utx_v1_in_place>( utx: &UnsignedTransactionV0, multisig: &Multisig<::PublicKey>, diff --git a/crates/module-system/module-implementations/sov-accounts/README.md b/crates/module-system/module-implementations/sov-accounts/README.md index c5e4f66632..fcff4b0a5d 100644 --- a/crates/module-system/module-implementations/sov-accounts/README.md +++ b/crates/module-system/module-implementations/sov-accounts/README.md @@ -16,6 +16,19 @@ addresses and records which credentials may act for which addresses. the `CallMessage::InsertCredentialId(..)` message. This writes an `account_owners` authorization, not a credential-indexed account entry. +1. It is possible to explicitly authorize a credential for the caller's own + address with `CallMessage::AddCredentialToAddress { address, credential }`, + revoke such an authorization with + `CallMessage::RemoveCredentialFromAddress { address, credential }`, and + atomically swap one credential for another with + `CallMessage::RotateCredentialOnAddress { address, old_credential, new_credential }`. + All three calls require `message.address == context.sender()`: callers can + only modify credentials on the address they are currently signing as. The + V1 signing path's `target_address` field lets a caller signing with a + credential authorized for multiple addresses select which one to act as. + There is no orphan guard on remove — revoking the last credential leaves + the address unspendable via `account_owners`. + 1. It is possible to query the `sov-accounts` module using the `get_account` method and get the legacy/custom mapped address corresponding to the given credential id. @@ -56,13 +69,14 @@ authorization has a stored account entry. ### Account-credential authorization map ```text -account_owners[(address, credential_id)] = true +account_owners[(address, credential_id)] = true | false ``` -This state map records authorization. A present entry means the credential is -authorized to sign transactions that execute as the given address. The key is -the exact `(address, credential_id)` pair, so this relation does not provide a -credential-only lookup by itself. +This state map records authorization overrides. `true` means the credential is +authorized to sign transactions that execute as the given address. `false` +explicitly revokes fallback authorization for that pair, including stateless +canonical fallback. The key is the exact `(address, credential_id)` pair, so +this relation does not provide a credential-only lookup by itself. This relation answers "may this credential act as this address?" once the target address is known. It is not a replacement for the credential-to-account map, diff --git a/crates/module-system/module-implementations/sov-accounts/src/call.rs b/crates/module-system/module-implementations/sov-accounts/src/call.rs index 7af211009d..ea05cb8927 100644 --- a/crates/module-system/module-implementations/sov-accounts/src/call.rs +++ b/crates/module-system/module-implementations/sov-accounts/src/call.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Context as _}; +use anyhow::{anyhow, bail, Context as _}; use schemars::JsonSchema; use sov_modules_api::macros::{serialize, UniversalWallet}; use sov_modules_api::{Context, CredentialId, Spec, StateReader, TxState}; @@ -9,8 +9,9 @@ use crate::{AccountOwnerKey, Accounts}; /// Represents the available call messages for interacting with the sov-accounts module. #[derive(Debug, PartialEq, Eq, Clone, JsonSchema, UniversalWallet)] #[serialize(Borsh, Serde)] +#[schemars(bound = "S::Address: ::schemars::JsonSchema", rename = "CallMessage")] #[serde(rename_all = "snake_case")] -pub enum CallMessage { +pub enum CallMessage { /// Authorizes `credential_id` as a signer for the caller's address. /// Fails if the credential has a legacy/custom account mapping or is /// already authorized for the caller's address. @@ -18,6 +19,45 @@ pub enum CallMessage { /// The credential id being authorized. CredentialId, ), + + /// Authorizes `credential` to sign transactions that execute as `address`. + /// The caller must currently be signing as `address`. Fails if the tuple + /// is already authorized. + AddCredentialToAddress { + /// The address whose credential set is being extended. Must equal + /// `context.sender()`. + address: S::Address, + /// The credential being authorized for `address`. + credential: CredentialId, + }, + + /// Revokes `credential` from `address`. The caller must currently be + /// signing as `address`. No orphan guard: revoking the last credential + /// succeeds and leaves `address` unspendable via this map. + RemoveCredentialFromAddress { + /// The address whose credential set is being reduced. Must equal + /// `context.sender()`. + address: S::Address, + /// The credential being revoked from `address`. + credential: CredentialId, + }, + + /// Atomically swaps `old_credential` for `new_credential` on `address`. + /// Functionally equivalent to a `RemoveCredentialFromAddress` followed by + /// an `AddCredentialToAddress`, collapsed into a single call so the + /// caller does not have to authorize two transactions during a rotation. + /// The caller must currently be signing as `address`. + RotateCredentialOnAddress { + /// The address whose credential set is being rotated. Must equal + /// `context.sender()`. + address: S::Address, + /// The credential being revoked from `address`. Must be currently + /// authorized. + old_credential: CredentialId, + /// The credential being authorized for `address`. Must not already + /// be authorized. + new_credential: CredentialId, + }, } impl Accounts { @@ -27,11 +67,7 @@ impl Accounts { context: &Context, state: &mut impl TxState, ) -> anyhow::Result<()> { - if !self.enable_custom_account_mappings.get(state)?.expect( - "`enable_custom_account_mappings` should not be None; it must be set at genesis.", - ) { - bail!("Custom account mappings are disabled"); - } + self.ensure_custom_account_mappings_enabled(state)?; self.exit_if_credential_exists(&new_credential_id, context.sender(), state)?; @@ -39,6 +75,116 @@ impl Accounts { Ok(()) } + pub(crate) fn add_credential_to_address( + &mut self, + address: S::Address, + credential: CredentialId, + context: &Context, + state: &mut impl TxState, + ) -> anyhow::Result<()> { + self.ensure_custom_account_mappings_enabled(state)?; + self.ensure_caller_owns(&address, context)?; + self.ensure_credential_not_authorized(&address, &credential, state)?; + + self.authorize_credential(&address, &credential, state)?; + Ok(()) + } + + pub(crate) fn remove_credential_from_address( + &mut self, + address: S::Address, + credential: CredentialId, + context: &Context, + state: &mut impl TxState, + ) -> anyhow::Result<()> { + self.ensure_custom_account_mappings_enabled(state)?; + self.ensure_caller_owns(&address, context)?; + + anyhow::ensure!( + self.is_authorized_for(&address, &credential, state) + .map_err(|err| anyhow!("Error raised while checking authorization: {err:?}"))?, + "CredentialId is not authorized for this address" + ); + + self.revoke_credential(&address, &credential, state)?; + Ok(()) + } + + pub(crate) fn rotate_credential_on_address( + &mut self, + address: S::Address, + old_credential: CredentialId, + new_credential: CredentialId, + context: &Context, + state: &mut impl TxState, + ) -> anyhow::Result<()> { + self.ensure_custom_account_mappings_enabled(state)?; + self.ensure_caller_owns(&address, context)?; + + anyhow::ensure!( + self.is_authorized_for(&address, &old_credential, state) + .map_err(|err| anyhow!("Error raised while checking authorization: {err:?}"))?, + "CredentialId is not authorized for this address" + ); + self.ensure_credential_not_authorized(&address, &new_credential, state)?; + + self.revoke_credential(&address, &old_credential, state)?; + self.authorize_credential(&address, &new_credential, state)?; + Ok(()) + } + + fn revoke_credential( + &mut self, + address: &S::Address, + credential: &CredentialId, + state: &mut impl TxState, + ) -> anyhow::Result<()> { + let key = AccountOwnerKey::new(*address, *credential); + // Write `false` explicitly so a subsequent fallback (legacy + // `accounts` mapping or canonical address) cannot re-authorize the + // tuple. + self.account_owners.set(&key, &false, state)?; + + if self + .accounts + .get(credential, state) + .map_err(|err| anyhow!("Error raised while getting account: {err:?}"))? + .is_some_and(|account| account.addr == *address) + { + self.accounts.delete(credential, state)?; + } + + Ok(()) + } + + fn ensure_custom_account_mappings_enabled( + &self, + state: &mut impl StateReader, + ) -> anyhow::Result<()> { + if !self + .enable_custom_account_mappings + .get(state) + .map_err(|err| anyhow!("Error reading enable_custom_account_mappings: {err:?}"))? + .expect( + "`enable_custom_account_mappings` should not be None; it must be set at genesis.", + ) + { + bail!("Custom account mappings are disabled"); + } + Ok(()) + } + + /// Enforces that the caller is signing as `address`. The upstream + /// authorization path has already verified the caller controls a + /// credential authorized for `context.sender()`. + fn ensure_caller_owns(&self, address: &S::Address, context: &Context) -> anyhow::Result<()> { + anyhow::ensure!( + context.sender() == address, + "Caller is not authorized to modify credentials for this address" + ); + Ok(()) + } + fn exit_if_credential_exists( &self, new_credential_id: &CredentialId, @@ -52,11 +198,22 @@ impl Accounts { .is_none(), "New CredentialId already exists" ); + self.ensure_credential_not_authorized(address, new_credential_id, state)?; + Ok(()) + } + + fn ensure_credential_not_authorized( + &self, + address: &S::Address, + credential: &CredentialId, + state: &mut impl StateReader, + ) -> anyhow::Result<()> { anyhow::ensure!( - self.account_owners - .get(&AccountOwnerKey::new(*address, *new_credential_id), state) + !self + .account_owners + .get(&AccountOwnerKey::new(*address, *credential), state) .context("Failed to read account owner")? - .is_none(), + .unwrap_or(false), "CredentialId already authorized for this address" ); Ok(()) diff --git a/crates/module-system/module-implementations/sov-accounts/src/capabilities.rs b/crates/module-system/module-implementations/sov-accounts/src/capabilities.rs index 30de1f7103..8189ca82c2 100644 --- a/crates/module-system/module-implementations/sov-accounts/src/capabilities.rs +++ b/crates/module-system/module-implementations/sov-accounts/src/capabilities.rs @@ -49,7 +49,7 @@ impl Accounts { } /// Returns `true` if `credential_id` has an explicit `account_owners` - /// authorization for `address`. + /// authorization for `address` via explicit `account_owners` state. pub fn is_authorized>( &self, address: &S::Address, @@ -59,7 +59,7 @@ impl Accounts { Ok(self .account_owners .get(&AccountOwnerKey::new(*address, *credential_id), state)? - .is_some()) + .unwrap_or(false)) } /// Returns `true` if `credential_id` is authorized to act as `address`. @@ -75,15 +75,17 @@ impl Accounts { credential_id: &CredentialId, state: &mut ST, ) -> Result { - if let Some(account) = self.accounts.get(credential_id, state)? { - return Ok(account.addr == *address); + if let Some(is_authorized) = self + .account_owners + .get(&AccountOwnerKey::new(*address, *credential_id), state)? + { + return Ok(is_authorized); } - let canonical_address: S::Address = (*credential_id).into(); - if canonical_address == *address { - return Ok(true); + if let Some(account) = self.accounts.get(credential_id, state)? { + return Ok(account.addr == *address); } - self.is_authorized(address, credential_id, state) + Ok(S::Address::from(*credential_id) == *address) } } diff --git a/crates/module-system/module-implementations/sov-accounts/src/fuzz.rs b/crates/module-system/module-implementations/sov-accounts/src/fuzz.rs index 2abc5e43a3..8e6ac3d2c3 100644 --- a/crates/module-system/module-implementations/sov-accounts/src/fuzz.rs +++ b/crates/module-system/module-implementations/sov-accounts/src/fuzz.rs @@ -3,9 +3,28 @@ use sov_modules_api::{CryptoSpec, DaSpec, Module, Spec, StateCheckpoint}; use crate::{Account, AccountConfig, AccountData, Accounts, CallMessage}; -impl<'a> Arbitrary<'a> for CallMessage { +impl<'a, S> Arbitrary<'a> for CallMessage +where + S: Spec, + S::Address: Arbitrary<'a>, +{ fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { - Ok(Self::InsertCredentialId(u.arbitrary()?)) + match u.int_in_range(0..=3)? { + 0 => Ok(Self::InsertCredentialId(u.arbitrary()?)), + 1 => Ok(Self::AddCredentialToAddress { + address: u.arbitrary()?, + credential: u.arbitrary()?, + }), + 2 => Ok(Self::RemoveCredentialFromAddress { + address: u.arbitrary()?, + credential: u.arbitrary()?, + }), + _ => Ok(Self::RotateCredentialOnAddress { + address: u.arbitrary()?, + old_credential: u.arbitrary()?, + new_credential: u.arbitrary()?, + }), + } } } diff --git a/crates/module-system/module-implementations/sov-accounts/src/lib.rs b/crates/module-system/module-implementations/sov-accounts/src/lib.rs index 247ff3e718..5b6e7f42e4 100644 --- a/crates/module-system/module-implementations/sov-accounts/src/lib.rs +++ b/crates/module-system/module-implementations/sov-accounts/src/lib.rs @@ -34,9 +34,7 @@ pub struct Account { pub addr: S::Address, } -/// Composite key for [`Accounts::account_owners`]. A present entry -/// `(address, credential_id)` means `credential_id` is authorized to sign -/// transactions that execute as `address`. +/// Composite key for [`Accounts::account_owners`]. #[derive( borsh::BorshDeserialize, borsh::BorshSerialize, Debug, Clone, Copy, PartialEq, Eq, Hash, )] @@ -98,8 +96,9 @@ pub struct Accounts { #[state] enable_custom_account_mappings: StateValue, - /// Authorization set: a present entry means `credential_id` may sign as - /// `address`. + /// Authorization overrides. `Some(true)` means `credential_id` may sign as + /// `address`; `Some(false)` explicitly revokes fallback authorization for + /// the pair. #[state] pub(crate) account_owners: StateMap, bool>, } @@ -109,7 +108,7 @@ impl Module for Accounts { type Config = AccountConfig; - type CallMessage = call::CallMessage; + type CallMessage = call::CallMessage; type Event = (); @@ -132,8 +131,27 @@ impl Module for Accounts { ) -> Result<(), Self::Error> { match msg { call::CallMessage::InsertCredentialId(new_credential_id) => { - Ok(self.insert_credential_id(new_credential_id, context, state)?) + self.insert_credential_id(new_credential_id, context, state) } + call::CallMessage::AddCredentialToAddress { + address, + credential, + } => self.add_credential_to_address(address, credential, context, state), + call::CallMessage::RemoveCredentialFromAddress { + address, + credential, + } => self.remove_credential_from_address(address, credential, context, state), + call::CallMessage::RotateCredentialOnAddress { + address, + old_credential, + new_credential, + } => self.rotate_credential_on_address( + address, + old_credential, + new_credential, + context, + state, + ), } } } diff --git a/crates/module-system/module-implementations/sov-accounts/src/tests.rs b/crates/module-system/module-implementations/sov-accounts/src/tests.rs index 8db2d82b8f..5af4f877cc 100644 --- a/crates/module-system/module-implementations/sov-accounts/src/tests.rs +++ b/crates/module-system/module-implementations/sov-accounts/src/tests.rs @@ -55,14 +55,71 @@ fn test_response_deserialization_on_wrong_hrp() { fn test_display_accounts_call() { #[derive(Debug, Clone, PartialEq, borsh::BorshSerialize, UniversalWallet)] enum RuntimeCall { - Accounts(CallMessage), + Accounts(CallMessage), } - let msg = RuntimeCall::Accounts(CallMessage::InsertCredentialId([1; 32].into())); - + let insert_msg = RuntimeCall::Accounts(CallMessage::InsertCredentialId([1; 32].into())); let schema = Schema::of_single_type::().unwrap(); assert_eq!( r#"Accounts.InsertCredentialId(0x0101010101010101010101010101010101010101010101010101010101010101)"#, - schema.display(0, &borsh::to_vec(&msg).unwrap()).unwrap(), + schema + .display(0, &borsh::to_vec(&insert_msg).unwrap()) + .unwrap(), + ); + + let addr_bytes: [u8; 28] = core::array::from_fn(|i| (i + 1) as u8); + let address = ::Address::from(addr_bytes); + + let add_msg = RuntimeCall::Accounts(CallMessage::AddCredentialToAddress { + address, + credential: [2; 32].into(), + }); + let rendered = schema + .display(0, &borsh::to_vec(&add_msg).unwrap()) + .unwrap(); + assert!( + rendered.starts_with("Accounts.AddCredentialToAddress"), + "unexpected render: {rendered}" + ); + assert!( + rendered.contains("0x0202020202020202020202020202020202020202020202020202020202020202"), + "render missing credential: {rendered}" + ); + + let remove_msg = RuntimeCall::Accounts(CallMessage::RemoveCredentialFromAddress { + address, + credential: [3; 32].into(), + }); + let rendered = schema + .display(0, &borsh::to_vec(&remove_msg).unwrap()) + .unwrap(); + assert!( + rendered.starts_with("Accounts.RemoveCredentialFromAddress"), + "unexpected render: {rendered}" + ); + assert!( + rendered.contains("0x0303030303030303030303030303030303030303030303030303030303030303"), + "render missing credential: {rendered}" + ); + + let rotate_msg = RuntimeCall::Accounts(CallMessage::RotateCredentialOnAddress { + address, + old_credential: [4; 32].into(), + new_credential: [5; 32].into(), + }); + let rendered = schema + .display(0, &borsh::to_vec(&rotate_msg).unwrap()) + .unwrap(); + assert!( + rendered.starts_with("Accounts.RotateCredentialOnAddress"), + "unexpected render: {rendered}" + ); + assert!( + rendered.contains("0x0404040404040404040404040404040404040404040404040404040404040404"), + "render missing old_credential: {rendered}" + ); + assert!( + rendered.contains("0x0505050505050505050505050505050505050505050505050505050505050505"), + "render missing new_credential: {rendered}" ); } diff --git a/crates/module-system/module-implementations/sov-accounts/tests/integration/main.rs b/crates/module-system/module-implementations/sov-accounts/tests/integration/main.rs index 5877fe75f5..59e0f974fe 100644 --- a/crates/module-system/module-implementations/sov-accounts/tests/integration/main.rs +++ b/crates/module-system/module-implementations/sov-accounts/tests/integration/main.rs @@ -673,10 +673,25 @@ fn make_v1_tx( multisig: &sov_modules_api::Multisig<<::CryptoSpec as CryptoSpec>::PublicKey>, inner_credential: sov_modules_api::CredentialId, target_address: Option<::Address>, +) -> Version1 { + make_v1_tx_with_call( + multisig, + CallMessage::InsertCredentialId(inner_credential), + target_address, + 0, + ) +} + +/// Builds an unsigned V1 tx carrying the given accounts call. +fn make_v1_tx_with_call( + multisig: &sov_modules_api::Multisig<<::CryptoSpec as CryptoSpec>::PublicKey>, + call: CallMessage, + target_address: Option<::Address>, + generation: u64, ) -> Version1 { UnsignedTransactionV0::::new_with_details( - TestAccountsRuntimeCall::Accounts(CallMessage::InsertCredentialId(inner_credential)), - sov_modules_api::capabilities::UniquenessData::Generation(0), + TestAccountsRuntimeCall::Accounts(call), + sov_modules_api::capabilities::UniquenessData::Generation(generation), default_test_tx_details::(), ) .to_multisig_tx(multisig.clone(), target_address) @@ -885,3 +900,936 @@ fn test_v1_target_tamper_breaks_signature() { }), }); } + +/// An existing owner can authorize a second credential for their own address +/// via `AddCredentialToAddress` (V0 path, sender == address). +#[test] +fn test_add_credential_to_address_by_owner() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let new_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>(CallMessage::AddCredentialToAddress { + address: owner_address, + credential: new_credential, + }), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!( + accounts + .is_authorized(&owner_address, &new_credential, state) + .unwrap(), + "new credential should be authorized for owner's address" + ); + }), + }); +} + +/// A brand-new user (no genesis entry, no prior `account_owners` entry) can +/// authorize a credential for their own default address. The simple +/// `sender == address` rule subsumes the bootstrap case: `sender` is the +/// user's default address because the resolver returns the default for an +/// unknown credential. +#[test] +fn test_add_credential_to_address_bootstrap() { + let ( + TestData { + non_registered_account: fresh_user, + .. + }, + mut runner, + ) = setup(); + let fresh_address = fresh_user.address(); + let extra_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: fresh_user.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: fresh_address, + credential: extra_credential, + }, + ), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(accounts + .is_authorized(&fresh_address, &extra_credential, state) + .unwrap()); + }), + }); +} + +/// A caller cannot add a credential for an address that isn't their own. +/// Under the resolver, `context.sender()` is the caller's resolved address; +/// the handler rejects if `message.address != context.sender()`. Uses two +/// users whose canonical (`hash(pubkey).into()`) addresses equal their funded +/// addresses so V0 gas reservation succeeds and the handler actually runs. +#[test] +fn test_add_credential_to_address_non_owner_rejected() { + let attacker = TestUser::::generate_with_default_balance(); + let victim = TestUser::::generate_with_default_balance(); + let victim_address = victim.address(); + + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![attacker.clone(), victim]); + let genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + let attacker_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: attacker.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: victim_address, + credential: attacker_credential, + }, + ), + assert: Box::new(move |result, state| { + match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Caller is not authorized to modify credentials for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + } + // Confirm the attacker's credential was never written under the victim. + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&victim_address, &attacker_credential, state) + .unwrap()); + }), + }); +} + +/// Adding a tuple that already exists fails cleanly. +#[test] +fn test_add_credential_duplicate_rejected() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential, + }, + )); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>(CallMessage::AddCredentialToAddress { + address: owner_address, + credential, + }), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "CredentialId already authorized for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + }), + }); +} + +/// The owner can revoke a credential from their own address. +#[test] +fn test_remove_credential_from_address_by_owner() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let kept_credential = TestPrivateKey::generate().pub_key().credential_id(); + let removed_credential = TestPrivateKey::generate().pub_key().credential_id(); + + // Authorize both credentials for the owner. + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: kept_credential, + }, + )); + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: removed_credential, + }, + )); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RemoveCredentialFromAddress { + address: owner_address, + credential: removed_credential, + }, + ), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&owner_address, &removed_credential, state) + .unwrap()); + assert!( + accounts + .is_authorized(&owner_address, &kept_credential, state) + .unwrap(), + "unrelated authorization should survive the revocation" + ); + }), + }); +} + +/// Removing a credential from its own canonical address writes an explicit +/// denial, because there is no legacy map entry to delete for that fallback. +#[test] +fn test_remove_canonical_credential_blocks_fallback_authorization() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let owner_credential = owner.credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RemoveCredentialFromAddress { + address: owner_address, + credential: owner_credential, + }, + ), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized_for(&owner_address, &owner_credential, state) + .unwrap()); + }), + }); +} + +/// A caller cannot revoke a credential from an address they don't own. Uses +/// two canonical-address users (no custom credential_id) so the V0 gas path +/// resolves correctly to the funded address. +#[test] +fn test_remove_credential_non_owner_rejected() { + let attacker = TestUser::::generate_with_default_balance(); + let victim = TestUser::::generate_with_default_balance(); + let victim_address = victim.address(); + let victim_credential = victim.credential_id(); + + // Seed victim's `(address, credential)` so the attacker's revoke attempt + // targets a real tuple. Otherwise the handler would fail on the tuple + // check before the ownership check, hiding the bug we care about. + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![attacker.clone(), victim]); + let mut genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + genesis.accounts.accounts.push(AccountData { + credential_id: victim_credential, + address: victim_address, + }); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + runner.execute_transaction(TransactionTestCase { + input: attacker.create_plain_message::>( + CallMessage::RemoveCredentialFromAddress { + address: victim_address, + credential: victim_credential, + }, + ), + assert: Box::new(move |result, state| { + match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Caller is not authorized to modify credentials for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + } + // Victim's authorization is unaffected. + let accounts = Accounts::::default(); + assert!(accounts + .is_authorized(&victim_address, &victim_credential, state) + .unwrap()); + }), + }); +} + +/// Attempting to remove a tuple that doesn't exist fails cleanly. +#[test] +fn test_remove_credential_not_authorized_rejected() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let ghost_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RemoveCredentialFromAddress { + address: owner_address, + credential: ghost_credential, + }, + ), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "CredentialId is not authorized for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + }), + }); +} + +/// Removing the last credential succeeds (no orphan guard) and leaves the +/// address unspendable via `account_owners`: a subsequent V1 tx with +/// `target_address = Some(orphaned)` signed by the revoked credential is +/// skipped at the resolver. +#[test] +fn test_remove_last_credential_orphans_address() { + let MultisigEnv { + keys, + multisig, + credential_id: multisig_credential_id, + user: multisig_user, + } = make_multisig_env(); + let alice = TestUser::::generate_with_default_balance(); + let alice_address = alice.address(); + + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![multisig_user, alice]); + let mut genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + // Seed `(alice_address, multisig_credential_id)` so the multisig can route + // to Alice's address before we revoke. + genesis.accounts.accounts.push(AccountData { + credential_id: multisig_credential_id, + address: alice_address, + }); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + // Revoke the only credential authorizing the multisig for Alice. + let mut revoke_tx = make_v1_tx_with_call( + &multisig, + CallMessage::RemoveCredentialFromAddress { + address: alice_address, + credential: multisig_credential_id, + }, + Some(alice_address), + 0, + ); + sign_v1(&mut revoke_tx, &keys[0]); + sign_v1(&mut revoke_tx, &keys[1]); + + runner.execute_transaction(TransactionTestCase { + input: submit_v1(revoke_tx), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&alice_address, &multisig_credential_id, state) + .unwrap()); + }), + }); + + // Orphan confirmed: trying to route to Alice again is rejected at the + // resolver (skipped, not reverted). + let follow_up_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut orphan_tx = make_v1_tx_with_call( + &multisig, + CallMessage::InsertCredentialId(follow_up_credential), + Some(alice_address), + 1, + ); + sign_v1(&mut orphan_tx, &keys[0]); + sign_v1(&mut orphan_tx, &keys[1]); + + runner.execute_transaction(TransactionTestCase { + input: submit_v1(orphan_tx), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Skipped(SkippedTxContents { error, .. }) => { + let msg = error.to_string(); + assert!( + msg.contains("not authorized for target address"), + "expected resolver skip; got: {msg}" + ); + } + other => panic!("expected skipped tx, got {other:?}"), + }), + }); +} + +/// End-to-end multisig rotation M1 → M2 while preserving the original +/// address. Exercises `AddCredentialToAddress` + `RemoveCredentialFromAddress` +/// via V1 + `target_address`. +#[test] +fn test_multisig_key_rotation() { + use sov_modules_api::Multisig; + + // M1 is the incumbent 2-of-3 multisig. M2 is the rotated key set, fully + // disjoint so credential_id_1 and credential_id_2 cannot collide. + let keys_1 = [ + TestPrivateKey::generate(), + TestPrivateKey::generate(), + TestPrivateKey::generate(), + ]; + let keys_2 = [ + TestPrivateKey::generate(), + TestPrivateKey::generate(), + TestPrivateKey::generate(), + ]; + let multisig_1 = Multisig::new(2, keys_1.iter().map(|k| k.pub_key()).collect()); + let multisig_2 = Multisig::new(2, keys_2.iter().map(|k| k.pub_key()).collect()); + let credential_id_1 = + multisig_1.credential_id::<<::CryptoSpec as CryptoSpec>::Hasher>(); + let credential_id_2 = + multisig_2.credential_id::<<::CryptoSpec as CryptoSpec>::Hasher>(); + + let multisig_user = + TestUser::generate_with_default_balance().add_credential_id(credential_id_1); + let target_address = multisig_user.address(); + + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![multisig_user]); + let genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + // 1. M1 authorizes M2 for the shared address X. + let mut add_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::AddCredentialToAddress { + address: target_address, + credential: credential_id_2, + }, + Some(target_address), + 0, + ); + sign_v1(&mut add_tx, &keys_1[0]); + sign_v1(&mut add_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(add_tx), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(accounts + .is_authorized(&target_address, &credential_id_1, state) + .unwrap()); + assert!(accounts + .is_authorized(&target_address, &credential_id_2, state) + .unwrap()); + }), + }); + + // 2. M1 revokes itself from X. + let mut remove_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::RemoveCredentialFromAddress { + address: target_address, + credential: credential_id_1, + }, + Some(target_address), + 1, + ); + sign_v1(&mut remove_tx, &keys_1[0]); + sign_v1(&mut remove_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(remove_tx), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&target_address, &credential_id_1, state) + .unwrap()); + assert!(accounts + .is_authorized(&target_address, &credential_id_2, state) + .unwrap()); + }), + }); + + // 3. M2 signs a routine tx targeting X — should succeed. + let follow_up_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut m2_tx = make_v1_tx_with_call( + &multisig_2, + CallMessage::InsertCredentialId(follow_up_credential), + Some(target_address), + 0, + ); + sign_v1(&mut m2_tx, &keys_2[0]); + sign_v1(&mut m2_tx, &keys_2[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(m2_tx), + assert: Box::new(move |result, _state| { + assert!( + result.tx_receipt.is_successful(), + "M2 should now control X; got {:?}", + result.tx_receipt + ); + }), + }); + + // 4. M1 signs another tx targeting X — should be skipped (no longer + // authorized). + let orphan_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut m1_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::InsertCredentialId(orphan_credential), + Some(target_address), + 2, + ); + sign_v1(&mut m1_tx, &keys_1[0]); + sign_v1(&mut m1_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(m1_tx), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Skipped(SkippedTxContents { error, .. }) => { + let msg = error.to_string(); + assert!( + msg.contains("not authorized for target address"), + "expected resolver skip after rotation; got: {msg}" + ); + } + other => panic!("expected skipped tx after rotation, got {other:?}"), + }), + }); +} + +/// With `enable_custom_account_mappings = false`, both new call variants are +/// rejected by the same guard that already rejects `InsertCredentialId`. +#[test] +fn test_feature_flag_gates_new_variants() { + let (user, mut runner) = setup_with_disable_custom_account_mappings(); + let user_address = user.address(); + let credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: user.create_plain_message::>(CallMessage::AddCredentialToAddress { + address: user_address, + credential, + }), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Custom account mappings are disabled" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + }), + }); + + runner.execute_transaction(TransactionTestCase { + input: user.create_plain_message::>( + CallMessage::RemoveCredentialFromAddress { + address: user_address, + credential, + }, + ), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Custom account mappings are disabled" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + }), + }); +} + +/// `RotateCredentialOnAddress` atomically replaces an authorized credential +/// with a new one. The old tuple is deleted; the new tuple is written; a +/// separate unrelated authorization on the same address is untouched. +#[test] +fn test_rotate_credential_by_owner() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let old_credential = TestPrivateKey::generate().pub_key().credential_id(); + let new_credential = TestPrivateKey::generate().pub_key().credential_id(); + let unrelated_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: old_credential, + }, + )); + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: unrelated_credential, + }, + )); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RotateCredentialOnAddress { + address: owner_address, + old_credential, + new_credential, + }, + ), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&owner_address, &old_credential, state) + .unwrap()); + assert!(accounts + .is_authorized(&owner_address, &new_credential, state) + .unwrap()); + assert!( + accounts + .is_authorized(&owner_address, &unrelated_credential, state) + .unwrap(), + "unrelated authorization must survive rotation" + ); + }), + }); +} + +/// Attempting to rotate out a credential that isn't authorized fails and +/// leaves state untouched. +#[test] +fn test_rotate_credential_old_not_authorized_rejected() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let ghost_credential = TestPrivateKey::generate().pub_key().credential_id(); + let new_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RotateCredentialOnAddress { + address: owner_address, + old_credential: ghost_credential, + new_credential, + }, + ), + assert: Box::new(move |result, state| { + match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "CredentialId is not authorized for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + } + // The revert must leave the new tuple unwritten. + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&owner_address, &new_credential, state) + .unwrap()); + }), + }); +} + +/// Attempting to rotate in a credential that is already authorized fails +/// without revoking the old credential. +#[test] +fn test_rotate_credential_new_already_authorized_rejected() { + let ( + TestData { + non_registered_account: owner, + .. + }, + mut runner, + ) = setup(); + let owner_address = owner.address(); + let old_credential = TestPrivateKey::generate().pub_key().credential_id(); + let new_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: old_credential, + }, + )); + runner.execute(owner.create_plain_message::>( + CallMessage::AddCredentialToAddress { + address: owner_address, + credential: new_credential, + }, + )); + + runner.execute_transaction(TransactionTestCase { + input: owner.create_plain_message::>( + CallMessage::RotateCredentialOnAddress { + address: owner_address, + old_credential, + new_credential, + }, + ), + assert: Box::new(move |result, state| { + match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "CredentialId already authorized for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + } + // The old credential must still be authorized — the revert rolls + // back the delete. + let accounts = Accounts::::default(); + assert!(accounts + .is_authorized(&owner_address, &old_credential, state) + .unwrap()); + assert!(accounts + .is_authorized(&owner_address, &new_credential, state) + .unwrap()); + }), + }); +} + +/// A caller cannot rotate credentials on an address they don't own. +#[test] +fn test_rotate_credential_non_owner_rejected() { + let attacker = TestUser::::generate_with_default_balance(); + let victim = TestUser::::generate_with_default_balance(); + let victim_address = victim.address(); + let victim_credential = victim.credential_id(); + + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![attacker.clone(), victim]); + let mut genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + genesis.accounts.accounts.push(AccountData { + credential_id: victim_credential, + address: victim_address, + }); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + let attacker_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: attacker.create_plain_message::>( + CallMessage::RotateCredentialOnAddress { + address: victim_address, + old_credential: victim_credential, + new_credential: attacker_credential, + }, + ), + assert: Box::new(move |result, state| { + match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Caller is not authorized to modify credentials for this address" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + } + let accounts = Accounts::::default(); + assert!(accounts + .is_authorized(&victim_address, &victim_credential, state) + .unwrap()); + assert!(!accounts + .is_authorized(&victim_address, &attacker_credential, state) + .unwrap()); + }), + }); +} + +/// `RotateCredentialOnAddress` is gated by the same feature flag as the +/// other write variants. +#[test] +fn test_rotate_credential_feature_flag_gated() { + let (user, mut runner) = setup_with_disable_custom_account_mappings(); + let user_address = user.address(); + let old_credential = TestPrivateKey::generate().pub_key().credential_id(); + let new_credential = TestPrivateKey::generate().pub_key().credential_id(); + + runner.execute_transaction(TransactionTestCase { + input: user.create_plain_message::>( + CallMessage::RotateCredentialOnAddress { + address: user_address, + old_credential, + new_credential, + }, + ), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Reverted(contents) => { + assert_eq!( + contents.reason.to_string(), + "Custom account mappings are disabled" + ); + } + other => panic!("Expected reverted transaction, got {other:?}"), + }), + }); +} + +/// Multisig rotation M1 → M2 in a single atomic `RotateCredentialOnAddress` +/// call, collapsing the two-step Add+Remove dance. +#[test] +fn test_multisig_key_rotation_atomic() { + use sov_modules_api::Multisig; + + let keys_1 = [ + TestPrivateKey::generate(), + TestPrivateKey::generate(), + TestPrivateKey::generate(), + ]; + let keys_2 = [ + TestPrivateKey::generate(), + TestPrivateKey::generate(), + TestPrivateKey::generate(), + ]; + let multisig_1 = Multisig::new(2, keys_1.iter().map(|k| k.pub_key()).collect()); + let multisig_2 = Multisig::new(2, keys_2.iter().map(|k| k.pub_key()).collect()); + let credential_id_1 = + multisig_1.credential_id::<<::CryptoSpec as CryptoSpec>::Hasher>(); + let credential_id_2 = + multisig_2.credential_id::<<::CryptoSpec as CryptoSpec>::Hasher>(); + + let multisig_user = + TestUser::generate_with_default_balance().add_credential_id(credential_id_1); + let target_address = multisig_user.address(); + + let genesis_config = + HighLevelOptimisticGenesisConfig::generate().add_accounts(vec![multisig_user]); + let genesis = GenesisConfig::from_minimal_config(genesis_config.into()); + let mut runner: TestRunner = + TestRunner::new_with_genesis(genesis.into_genesis_params(), RT::default()); + + let mut rotate_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::RotateCredentialOnAddress { + address: target_address, + old_credential: credential_id_1, + new_credential: credential_id_2, + }, + Some(target_address), + 0, + ); + sign_v1(&mut rotate_tx, &keys_1[0]); + sign_v1(&mut rotate_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(rotate_tx), + assert: Box::new(move |result, state| { + assert!(result.tx_receipt.is_successful()); + let accounts = Accounts::::default(); + assert!(!accounts + .is_authorized(&target_address, &credential_id_1, state) + .unwrap()); + assert!(accounts + .is_authorized(&target_address, &credential_id_2, state) + .unwrap()); + }), + }); + + // M1 cannot bypass the revocation by omitting target_address and falling + // back to its canonical address. + let stale_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut m1_target_none_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::InsertCredentialId(stale_credential), + None, + 1, + ); + sign_v1(&mut m1_target_none_tx, &keys_1[0]); + sign_v1(&mut m1_target_none_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(m1_target_none_tx), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Skipped(SkippedTxContents { error, .. }) => { + let msg = error.to_string(); + assert!( + msg.contains("not authorized for resolved address"), + "expected resolver skip after target-less rotation fallback; got: {msg}" + ); + } + other => panic!("expected skipped tx after target-less fallback, got {other:?}"), + }), + }); + + // M2 now controls X. + let follow_up_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut m2_tx = make_v1_tx_with_call( + &multisig_2, + CallMessage::InsertCredentialId(follow_up_credential), + Some(target_address), + 0, + ); + sign_v1(&mut m2_tx, &keys_2[0]); + sign_v1(&mut m2_tx, &keys_2[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(m2_tx), + assert: Box::new(move |result, _state| { + assert!( + result.tx_receipt.is_successful(), + "M2 should now control X after atomic rotation; got {:?}", + result.tx_receipt + ); + }), + }); + + // M1 can no longer act as X. + let orphan_credential = TestPrivateKey::generate().pub_key().credential_id(); + let mut m1_tx = make_v1_tx_with_call( + &multisig_1, + CallMessage::InsertCredentialId(orphan_credential), + Some(target_address), + 1, + ); + sign_v1(&mut m1_tx, &keys_1[0]); + sign_v1(&mut m1_tx, &keys_1[1]); + runner.execute_transaction(TransactionTestCase { + input: submit_v1(m1_tx), + assert: Box::new(move |result, _state| match result.tx_receipt { + TxEffect::Skipped(SkippedTxContents { error, .. }) => { + let msg = error.to_string(); + assert!( + msg.contains("not authorized for target address"), + "expected resolver skip after rotation; got: {msg}" + ); + } + other => panic!("expected skipped tx after rotation, got {other:?}"), + }), + }); +} diff --git a/crates/module-system/module-schemas/schemas/sov-accounts.json b/crates/module-system/module-schemas/schemas/sov-accounts.json index a4d990f3cf..42878d0d1f 100644 --- a/crates/module-system/module-schemas/schemas/sov-accounts.json +++ b/crates/module-system/module-schemas/schemas/sov-accounts.json @@ -15,9 +15,128 @@ } }, "additionalProperties": false + }, + { + "description": "Authorizes `credential` to sign transactions that execute as `address`. The caller must currently be signing as `address`. Fails if the tuple is already authorized.", + "type": "object", + "required": [ + "add_credential_to_address" + ], + "properties": { + "add_credential_to_address": { + "type": "object", + "required": [ + "address", + "credential" + ], + "properties": { + "address": { + "description": "The address whose credential set is being extended. Must equal `context.sender()`.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "credential": { + "description": "The credential being authorized for `address`.", + "allOf": [ + { + "$ref": "#/definitions/CredentialId" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Revokes `credential` from `address`. The caller must currently be signing as `address`. No orphan guard: revoking the last credential succeeds and leaves `address` unspendable via this map.", + "type": "object", + "required": [ + "remove_credential_from_address" + ], + "properties": { + "remove_credential_from_address": { + "type": "object", + "required": [ + "address", + "credential" + ], + "properties": { + "address": { + "description": "The address whose credential set is being reduced. Must equal `context.sender()`.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "credential": { + "description": "The credential being revoked from `address`.", + "allOf": [ + { + "$ref": "#/definitions/CredentialId" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Atomically swaps `old_credential` for `new_credential` on `address`. Functionally equivalent to a `RemoveCredentialFromAddress` followed by an `AddCredentialToAddress`, collapsed into a single call so the caller does not have to authorize two transactions during a rotation. The caller must currently be signing as `address`.", + "type": "object", + "required": [ + "rotate_credential_on_address" + ], + "properties": { + "rotate_credential_on_address": { + "type": "object", + "required": [ + "address", + "new_credential", + "old_credential" + ], + "properties": { + "address": { + "description": "The address whose credential set is being rotated. Must equal `context.sender()`.", + "allOf": [ + { + "$ref": "#/definitions/Address" + } + ] + }, + "new_credential": { + "description": "The credential being authorized for `address`. Must not already be authorized.", + "allOf": [ + { + "$ref": "#/definitions/CredentialId" + } + ] + }, + "old_credential": { + "description": "The credential being revoked from `address`. Must be currently authorized.", + "allOf": [ + { + "$ref": "#/definitions/CredentialId" + } + ] + } + } + } + }, + "additionalProperties": false } ], "definitions": { + "Address": { + "description": "Address", + "type": "string", + "pattern": "^sov1[a-zA-Z0-9]+$" + }, "CredentialId": { "description": "32 bytes in hexadecimal format, with `0x` prefix.", "type": "string", diff --git a/crates/module-system/sov-address/src/evm/address.rs b/crates/module-system/sov-address/src/evm/address.rs index 500aa32f1d..5a19743165 100644 --- a/crates/module-system/sov-address/src/evm/address.rs +++ b/crates/module-system/sov-address/src/evm/address.rs @@ -1,5 +1,5 @@ use crate::evm::public_key::EthereumPublicKey; -use crate::{MultiAddress, Not28Bytes}; +use crate::{MultiAddress, Not28Bytes, TryDecodeCredentialId}; use alloy_primitives::{Address, AddressError}; use borsh::{BorshDeserialize, BorshSerialize}; use k256::elliptic_curve::sec1::ToEncodedPoint; @@ -145,6 +145,21 @@ pub type MultiAddressEvm = MultiAddress; impl BasicAddress for EthereumAddress {} impl Not28Bytes for EthereumAddress {} +impl TryDecodeCredentialId for EthereumAddress { + fn try_decode_credential_id(credential_id: CredentialId) -> Option { + // EVM credentials pack a 20-byte address into the low 20 bytes of + // the 32-byte credential (see `EthereumAddress::as_credential_id`). + // Credentials derived from native public-key hashes have essentially + // random bytes in that leading 12-byte slot. + let bytes: &[u8] = credential_id.0.as_ref(); + if bytes[..12] == [0u8; 12] { + Some(Self::from(credential_id)) + } else { + None + } + } +} + #[cfg(test)] mod tests { use std::str::FromStr; @@ -152,10 +167,30 @@ mod tests { use borsh::{BorshDeserialize, BorshSerialize}; use sov_modules_api::configurable_spec::ConfigurableSpec; use sov_modules_api::execution_mode::Native; - use sov_modules_api::Spec; - use sov_test_utils::{MockDaSpec, MockZkvm}; use super::*; + + #[test] + fn credential_from_evm_address_roundtrips_to_vm_multi_address() { + let eth_addr = + EthereumAddress::from_str("0x71334bf1710D12c9f689cC819476fA589F08C64C").unwrap(); + let cred = eth_addr.as_credential_id(); + let back: MultiAddressEvm = cred.into(); + assert_eq!(back, MultiAddressEvm::Vm(eth_addr)); + } + + #[test] + fn credential_from_native_hash_stays_standard() { + let cred = CredentialId::from_bytes([0x42; 32]); + let back: MultiAddressEvm = cred.into(); + match back { + MultiAddressEvm::Standard(_) => {} + MultiAddressEvm::Vm(_) => panic!("non-zero-prefix credential must not decode to Vm"), + } + } + + use sov_modules_api::Spec; + use sov_test_utils::{MockDaSpec, MockZkvm}; type S = ConfigurableSpec; #[test] diff --git a/crates/module-system/sov-address/src/lib.rs b/crates/module-system/sov-address/src/lib.rs index 0dfc813124..5f57b60853 100644 --- a/crates/module-system/sov-address/src/lib.rs +++ b/crates/module-system/sov-address/src/lib.rs @@ -46,9 +46,12 @@ impl From for MultiAddress } } -impl From for MultiAddress { +impl From for MultiAddress { fn from(value: CredentialId) -> Self { - Self::Standard(Address::from(value)) + match VmAddress::try_decode_credential_id(value) { + Some(vm) => Self::Vm(vm), + None => Self::Standard(Address::from(value)), + } } } @@ -176,3 +179,14 @@ pub trait Not28Bytes {} pub trait FromVmAddress { fn from_vm_address(value: VmAddress) -> Self; } + +/// Attempts to reconstruct a VM-specific address from a [`CredentialId`]. +/// Credentials that originate from a VM address carry the address bytes in a +/// recoverable encoding (for example EVM credentials pack the 20-byte address +/// into the low 20 bytes of the 32-byte credential); implementors check for +/// that shape and decode back. Returning `None` means this credential does +/// not encode an address in this VM's format and falls back to the standard +/// hash-derived [`Address`]. +pub trait TryDecodeCredentialId: Sized { + fn try_decode_credential_id(credential_id: CredentialId) -> Option; +} diff --git a/crates/module-system/sov-capabilities/src/lib.rs b/crates/module-system/sov-capabilities/src/lib.rs index 93d950fbb6..2151eb92bd 100644 --- a/crates/module-system/sov-capabilities/src/lib.rs +++ b/crates/module-system/sov-capabilities/src/lib.rs @@ -80,11 +80,24 @@ impl<'a, S: Spec, T> StandardProvenRollupCapabilities<'a, S, T> { } Ok(requested) } - None => Ok(self.accounts.resolve_sender_address( - &auth_data.default_address, - &auth_data.credential_id, - state, - )?), + None => { + let resolved = self.accounts.resolve_sender_address( + &auth_data.default_address, + &auth_data.credential_id, + state, + )?; + if !self + .accounts + .is_authorized_for(&resolved, &auth_data.credential_id, state)? + { + anyhow::bail!( + "credential {} not authorized for resolved address {}", + auth_data.credential_id, + resolved, + ); + } + Ok(resolved) + } } } } diff --git a/crates/module-system/sov-modules-api/src/runtime/capabilities/authorization.rs b/crates/module-system/sov-modules-api/src/runtime/capabilities/authorization.rs index 61bf0eef48..fce2e7e364 100644 --- a/crates/module-system/sov-modules-api/src/runtime/capabilities/authorization.rs +++ b/crates/module-system/sov-modules-api/src/runtime/capabilities/authorization.rs @@ -103,10 +103,12 @@ pub struct AuthorizationData { /// The default address. pub default_address: S::Address, - /// Signer-declared target address for execution. `None` routes the transaction - /// through the default resolver (default address + legacy fallback). `Some(X)` - /// requires `(X, credential_id) ∈ account_owners`; the transaction is skipped - /// otherwise. Populated from V1 transactions' signed `target_address` field; + /// Signer-declared target address for execution. + /// `None` routes the transaction through the default resolver + /// (default address + legacy fallback). + /// `Some(X)` requires `(X, credential_id) ∈ account_owners`; + /// the transaction is skipped otherwise. + /// Populated from V1 transactions' signed `target_address` field; /// always `None` for V0 and non-sov-tx authenticators. pub address: Option, } diff --git a/examples/demo-rollup/README.md b/examples/demo-rollup/README.md index 0919259c92..e9265777dc 100644 --- a/examples/demo-rollup/README.md +++ b/examples/demo-rollup/README.md @@ -120,7 +120,7 @@ this case have the TokenCreated Event ```sh,test-ci,bashtestmd:compare-output $ sleep 5 -$ curl -sS http://127.0.0.1:12346/ledger/txs/0xbe16e6f31255f2f5f0a1e39530f91fd7f6480d73a3fbd3d3dcf7265962417db7/events | jq +$ curl -sS http://127.0.0.1:12346/ledger/txs/0x043686ec1013e8eacc80351d7ff84592382c70461832d218c2e3e6e33bb7bd6b/events | jq [ { "type": "event", @@ -154,7 +154,7 @@ $ curl -sS http://127.0.0.1:12346/ledger/txs/0xbe16e6f31255f2f5f0a1e39530f91fd7f "type": "moduleRef", "name": "Bank" }, - "tx_hash": "0xbe16e6f31255f2f5f0a1e39530f91fd7f6480d73a3fbd3d3dcf7265962417db7" + "tx_hash": "0x043686ec1013e8eacc80351d7ff84592382c70461832d218c2e3e6e33bb7bd6b" } ] ``` @@ -333,7 +333,7 @@ Adding the following transaction to batch: } } }, - "chain_hash": "0x65746dac667c302c76553208e916ba9a2f5738780f789014f8a900d6c2aeb8e5", + "chain_hash": "0x0747c78c9a62a856f5208d9a980136996209d96bfacc6aa9db8c5da2b8322792", "details": { "max_priority_fee_bips": 0, "max_fee": "100000000", diff --git a/examples/demo-rollup/README_CELESTIA.md b/examples/demo-rollup/README_CELESTIA.md index ca83aaca54..d335181418 100644 --- a/examples/demo-rollup/README_CELESTIA.md +++ b/examples/demo-rollup/README_CELESTIA.md @@ -290,7 +290,7 @@ Adding the following transaction to batch: } } }, - "chain_hash": "0x65746dac667c302c76553208e916ba9a2f5738780f789014f8a900d6c2aeb8e5", + "chain_hash": "0x0747c78c9a62a856f5208d9a980136996209d96bfacc6aa9db8c5da2b8322792", "details": { "max_priority_fee_bips": 0, "max_fee": "100000000", diff --git a/examples/demo-rollup/demo-rollup-schema.bin b/examples/demo-rollup/demo-rollup-schema.bin index 2598a10509..98401ebd39 100644 Binary files a/examples/demo-rollup/demo-rollup-schema.bin and b/examples/demo-rollup/demo-rollup-schema.bin differ diff --git a/examples/demo-rollup/demo-rollup-schema.json b/examples/demo-rollup/demo-rollup-schema.json index 8956cc756a..69600db297 100644 --- a/examples/demo-rollup/demo-rollup-schema.json +++ b/examples/demo-rollup/demo-rollup-schema.json @@ -1,32 +1,23 @@ { "types": [ - { - "Struct": { - "type_name": "Transaction", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "versioned_tx", - "silent": false, - "value": { - "ByIndex": 1 - }, - "doc": "" - } - ] - } - }, { "Enum": { - "type_name": "VersionedTx", + "type_name": "Transaction", "variants": [ { "name": "V0", "discriminant": 0, "template": null, "value": { - "ByIndex": 2 + "ByIndex": 1 + } + }, + { + "name": "V1", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 172 } } ], @@ -40,7 +31,7 @@ "fields": [ { "value": { - "ByIndex": 3 + "ByIndex": 2 }, "silent": false, "doc": "" @@ -58,7 +49,12 @@ "display_name": "signature", "silent": false, "value": { - "ByIndex": 4 + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } }, "doc": "" }, @@ -66,7 +62,12 @@ "display_name": "pub_key", "silent": false, "value": { - "ByIndex": 5 + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } }, "doc": "" }, @@ -74,20 +75,15 @@ "display_name": "runtime_call", "silent": false, "value": { - "ByIndex": 6 + "ByIndex": 3 }, "doc": "" }, { - "display_name": "generation", + "display_name": "uniqueness", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 167 }, "doc": "" }, @@ -95,51 +91,7 @@ "display_name": "details", "silent": false, "value": { - "ByIndex": 113 - }, - "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "Ed25519Signature", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "msg_sig", - "silent": false, - "value": { - "Immediate": { - "ByteArray": { - "len": 64, - "display": "Hex" - } - } - }, - "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "Ed25519PublicKey", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "pub_key", - "silent": false, - "value": { - "Immediate": { - "ByteArray": { - "len": 32, - "display": "Hex" - } - } + "ByIndex": 170 }, "doc": "" } @@ -155,7 +107,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 7 + "ByIndex": 4 } }, { @@ -203,7 +155,7 @@ "discriminant": 6, "template": null, "value": { - "ByIndex": 51 + "ByIndex": 54 } }, { @@ -211,7 +163,7 @@ "discriminant": 7, "template": null, "value": { - "ByIndex": 53 + "ByIndex": 56 } }, { @@ -219,7 +171,7 @@ "discriminant": 8, "template": null, "value": { - "ByIndex": 54 + "ByIndex": 59 } }, { @@ -227,31 +179,71 @@ "discriminant": 9, "template": null, "value": { - "ByIndex": 55 + "ByIndex": 60 } }, { - "name": "Evm", + "name": "RevenueShare", "discriminant": 10, "template": null, "value": { - "ByIndex": 84 + "ByIndex": 89 } }, { - "name": "AccessPattern", + "name": "Mailbox", "discriminant": 11, "template": null, "value": { - "ByIndex": 87 + "ByIndex": 94 } }, { - "name": "SyntheticLoad", + "name": "InterchainGasPaymaster", "discriminant": 12, "template": null, "value": { - "ByIndex": 108 + "ByIndex": 103 + } + }, + { + "name": "MerkleTreeHook", + "discriminant": 13, + "template": null, + "value": { + "ByIndex": 113 + } + }, + { + "name": "Warp", + "discriminant": 14, + "template": null, + "value": { + "ByIndex": 114 + } + }, + { + "name": "Evm", + "discriminant": 15, + "template": null, + "value": { + "ByIndex": 134 + } + }, + { + "name": "AccessPattern", + "discriminant": 16, + "template": null, + "value": { + "ByIndex": 148 + } + }, + { + "name": "SyntheticLoad", + "discriminant": 17, + "template": null, + "value": { + "ByIndex": 162 } } ], @@ -265,7 +257,7 @@ "fields": [ { "value": { - "ByIndex": 8 + "ByIndex": 5 }, "silent": false, "doc": "" @@ -282,7 +274,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 9 + "ByIndex": 6 } }, { @@ -290,7 +282,7 @@ "discriminant": 1, "template": "Transfer to address {} {}.", "value": { - "ByIndex": 19 + "ByIndex": 18 } }, { @@ -298,7 +290,7 @@ "discriminant": 2, "template": null, "value": { - "ByIndex": 22 + "ByIndex": 21 } }, { @@ -306,7 +298,7 @@ "discriminant": 3, "template": null, "value": { - "ByIndex": 23 + "ByIndex": 22 } }, { @@ -314,7 +306,7 @@ "discriminant": 4, "template": null, "value": { - "ByIndex": 24 + "ByIndex": 23 } }, { @@ -322,7 +314,15 @@ "discriminant": 5, "template": null, "value": { - "ByIndex": 25 + "ByIndex": 24 + } + }, + { + "name": "TransferWithMemo", + "discriminant": 6, + "template": "Transfer to address {} {} with memo `{}`.", + "value": { + "ByIndex": 26 } } ], @@ -347,7 +347,7 @@ "display_name": "token_decimals", "silent": false, "value": { - "ByIndex": 10 + "ByIndex": 7 }, "doc": "" }, @@ -355,7 +355,7 @@ "display_name": "initial_balance", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" }, @@ -363,7 +363,7 @@ "display_name": "mint_to_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -371,7 +371,7 @@ "display_name": "admins", "silent": false, "value": { - "ByIndex": 17 + "ByIndex": 16 }, "doc": "" }, @@ -379,7 +379,7 @@ "display_name": "supply_cap", "silent": false, "value": { - "ByIndex": 18 + "ByIndex": 17 }, "doc": "" } @@ -420,22 +420,30 @@ }, { "Enum": { - "type_name": "MultiAddress", + "type_name": "MultiAddressEvmSolana", "variants": [ { "name": "Standard", "discriminant": 0, "template": null, "value": { - "ByIndex": 13 + "ByIndex": 10 } }, { - "name": "Vm", + "name": "Evm", "discriminant": 1, "template": null, "value": { - "ByIndex": 15 + "ByIndex": 12 + } + }, + { + "name": "Solana", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 14 } } ], @@ -449,7 +457,7 @@ "fields": [ { "value": { - "ByIndex": 14 + "ByIndex": 11 }, "silent": false, "doc": "" @@ -488,7 +496,7 @@ "fields": [ { "value": { - "ByIndex": 16 + "ByIndex": 13 }, "silent": false, "doc": "" @@ -516,17 +524,52 @@ ] } }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 15 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Base58" + } + } + }, + "silent": false, + "doc": "" + } + ] + } + }, { "Vec": { "value": { - "ByIndex": 12 + "ByIndex": 9 } } }, { "Option": { "value": { - "ByIndex": 11 + "ByIndex": 8 } } }, @@ -540,7 +583,7 @@ "display_name": "to", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -548,7 +591,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" } @@ -585,7 +628,7 @@ "display_name": "token_id", "silent": false, "value": { - "ByIndex": 21 + "ByIndex": 20 }, "doc": "" } @@ -626,7 +669,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" } @@ -643,7 +686,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" }, @@ -651,7 +694,7 @@ "display_name": "mint_to_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -668,7 +711,7 @@ "display_name": "token_id", "silent": false, "value": { - "ByIndex": 21 + "ByIndex": 20 }, "doc": "" } @@ -685,7 +728,7 @@ "display_name": "new_admin", "silent": false, "value": { - "ByIndex": 26 + "ByIndex": 25 }, "doc": "" }, @@ -693,7 +736,7 @@ "display_name": "token_id", "silent": false, "value": { - "ByIndex": 21 + "ByIndex": 20 }, "doc": "" } @@ -703,31 +746,64 @@ { "Option": { "value": { - "ByIndex": 12 + "ByIndex": 9 } } }, { - "Tuple": { - "template": null, + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_TransferWithMemo", + "template": "Transfer to address {} {} with memo `{}`.", "peekable": false, "fields": [ { + "display_name": "to", + "silent": false, "value": { - "ByIndex": 28 + "ByIndex": 9 }, - "silent": false, "doc": "" - } - ] - } - }, - { - "Enum": { - "type_name": "CallMessage", - "variants": [ + }, { - "name": "Register", + "display_name": "coins", + "silent": false, + "value": { + "ByIndex": 19 + }, + "doc": "" + }, + { + "display_name": "memo", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 28 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "Register", "discriminant": 0, "template": null, "value": { @@ -780,7 +856,7 @@ "display_name": "amount", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" } @@ -825,7 +901,7 @@ "display_name": "amount", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" } @@ -907,7 +983,7 @@ "display_name": "new_reward_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -986,7 +1062,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1001,7 +1077,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1016,7 +1092,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1076,7 +1152,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1091,7 +1167,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1125,6 +1201,30 @@ "value": { "ByIndex": 48 } + }, + { + "name": "AddCredentialToAddress", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 51 + } + }, + { + "name": "RemoveCredentialFromAddress", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 52 + } + }, + { + "name": "RotateCredentialOnAddress", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 53 + } } ], "hide_tag": false @@ -1180,6 +1280,89 @@ ] } }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_AddCredentialToAddress", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "credential", + "silent": false, + "value": { + "ByIndex": 49 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RemoveCredentialFromAddress", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "credential", + "silent": false, + "value": { + "ByIndex": 49 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RotateCredentialOnAddress", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "old_credential", + "silent": false, + "value": { + "ByIndex": 49 + }, + "doc": "" + }, + { + "display_name": "new_credential", + "silent": false, + "value": { + "ByIndex": 49 + }, + "doc": "" + } + ] + } + }, { "Tuple": { "template": null, @@ -1187,7 +1370,7 @@ "fields": [ { "value": { - "ByIndex": 52 + "ByIndex": 55 }, "silent": false, "doc": "" @@ -1209,7 +1392,7 @@ "fields": [ { "value": { - "ByIndex": 52 + "ByIndex": 57 }, "silent": false, "doc": "" @@ -1217,6 +1400,50 @@ ] } }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "TerminateSetupMode", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "SetOracleTime", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 58 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_SetOracleTime", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "milliseconds_since_epoch", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "i64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, { "Tuple": { "template": null, @@ -1224,7 +1451,7 @@ "fields": [ { "value": { - "ByIndex": 52 + "ByIndex": 55 }, "silent": false, "doc": "" @@ -1239,7 +1466,7 @@ "fields": [ { "value": { - "ByIndex": 56 + "ByIndex": 61 }, "silent": false, "doc": "" @@ -1256,7 +1483,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 57 + "ByIndex": 62 } }, { @@ -1264,7 +1491,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 73 + "ByIndex": 78 } }, { @@ -1272,7 +1499,7 @@ "discriminant": 2, "template": null, "value": { - "ByIndex": 74 + "ByIndex": 79 } } ], @@ -1289,7 +1516,7 @@ "display_name": "policy", "silent": false, "value": { - "ByIndex": 58 + "ByIndex": 63 }, "doc": "" } @@ -1306,7 +1533,7 @@ "display_name": "default_payee_policy", "silent": false, "value": { - "ByIndex": 59 + "ByIndex": 64 }, "doc": "" }, @@ -1314,7 +1541,7 @@ "display_name": "payees", "silent": false, "value": { - "ByIndex": 68 + "ByIndex": 73 }, "doc": "" }, @@ -1322,7 +1549,7 @@ "display_name": "authorized_updaters", "silent": false, "value": { - "ByIndex": 17 + "ByIndex": 16 }, "doc": "" }, @@ -1330,7 +1557,7 @@ "display_name": "authorized_sequencers", "silent": false, "value": { - "ByIndex": 70 + "ByIndex": 75 }, "doc": "" } @@ -1346,7 +1573,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 60 + "ByIndex": 65 } }, { @@ -1369,7 +1596,7 @@ "display_name": "max_fee", "silent": false, "value": { - "ByIndex": 18 + "ByIndex": 17 }, "doc": "" }, @@ -1377,7 +1604,7 @@ "display_name": "gas_limit", "silent": false, "value": { - "ByIndex": 61 + "ByIndex": 66 }, "doc": "" }, @@ -1385,7 +1612,7 @@ "display_name": "max_gas_price", "silent": false, "value": { - "ByIndex": 64 + "ByIndex": 69 }, "doc": "" }, @@ -1393,7 +1620,7 @@ "display_name": "transaction_limit", "silent": false, "value": { - "ByIndex": 67 + "ByIndex": 72 }, "doc": "" } @@ -1403,7 +1630,7 @@ { "Option": { "value": { - "ByIndex": 62 + "ByIndex": 67 } } }, @@ -1414,7 +1641,7 @@ "fields": [ { "value": { - "ByIndex": 63 + "ByIndex": 68 }, "silent": false, "doc": "" @@ -1438,7 +1665,7 @@ { "Option": { "value": { - "ByIndex": 65 + "ByIndex": 70 } } }, @@ -1452,7 +1679,7 @@ "display_name": "value", "silent": false, "value": { - "ByIndex": 66 + "ByIndex": 71 }, "doc": "" } @@ -1463,7 +1690,7 @@ "Array": { "len": 2, "value": { - "ByIndex": 11 + "ByIndex": 8 } } }, @@ -1482,7 +1709,7 @@ { "Vec": { "value": { - "ByIndex": 69 + "ByIndex": 74 } } }, @@ -1493,14 +1720,14 @@ "fields": [ { "value": { - "ByIndex": 12 + "ByIndex": 9 }, "silent": false, "doc": "" }, { "value": { - "ByIndex": 59 + "ByIndex": 64 }, "silent": false, "doc": "" @@ -1523,7 +1750,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 71 + "ByIndex": 76 } } ], @@ -1537,7 +1764,7 @@ "fields": [ { "value": { - "ByIndex": 72 + "ByIndex": 77 }, "silent": false, "doc": "" @@ -1562,7 +1789,7 @@ "display_name": "payer", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -1579,7 +1806,7 @@ "display_name": "payer", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -1587,7 +1814,7 @@ "display_name": "update", "silent": false, "value": { - "ByIndex": 75 + "ByIndex": 80 }, "doc": "" } @@ -1604,7 +1831,7 @@ "display_name": "sequencer_update", "silent": false, "value": { - "ByIndex": 76 + "ByIndex": 81 }, "doc": "" }, @@ -1612,7 +1839,7 @@ "display_name": "updaters_to_add", "silent": false, "value": { - "ByIndex": 81 + "ByIndex": 86 }, "doc": "" }, @@ -1620,7 +1847,7 @@ "display_name": "updaters_to_remove", "silent": false, "value": { - "ByIndex": 81 + "ByIndex": 86 }, "doc": "" }, @@ -1628,7 +1855,7 @@ "display_name": "payee_policies_to_set", "silent": false, "value": { - "ByIndex": 82 + "ByIndex": 87 }, "doc": "" }, @@ -1636,7 +1863,7 @@ "display_name": "payee_policies_to_delete", "silent": false, "value": { - "ByIndex": 81 + "ByIndex": 86 }, "doc": "" }, @@ -1644,7 +1871,7 @@ "display_name": "default_policy", "silent": false, "value": { - "ByIndex": 83 + "ByIndex": 88 }, "doc": "" } @@ -1654,7 +1881,7 @@ { "Option": { "value": { - "ByIndex": 77 + "ByIndex": 82 } } }, @@ -1673,7 +1900,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 78 + "ByIndex": 83 } } ], @@ -1687,7 +1914,7 @@ "fields": [ { "value": { - "ByIndex": 79 + "ByIndex": 84 }, "silent": false, "doc": "" @@ -1705,7 +1932,7 @@ "display_name": "to_add", "silent": false, "value": { - "ByIndex": 80 + "ByIndex": 85 }, "doc": "" }, @@ -1713,7 +1940,7 @@ "display_name": "to_remove", "silent": false, "value": { - "ByIndex": 80 + "ByIndex": 85 }, "doc": "" } @@ -1723,28 +1950,28 @@ { "Option": { "value": { - "ByIndex": 72 + "ByIndex": 77 } } }, { "Option": { "value": { - "ByIndex": 17 + "ByIndex": 16 } } }, { "Option": { "value": { - "ByIndex": 68 + "ByIndex": 73 } } }, { "Option": { "value": { - "ByIndex": 59 + "ByIndex": 64 } } }, @@ -1755,7 +1982,7 @@ "fields": [ { "value": { - "ByIndex": 85 + "ByIndex": 90 }, "silent": false, "doc": "" @@ -1764,16 +1991,65 @@ } }, { - "Struct": { + "Enum": { "type_name": "CallMessage", + "variants": [ + { + "name": "ActivateRevenueShare", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "DeactivateRevenueShare", + "discriminant": 1, + "template": null, + "value": null + }, + { + "name": "LowerRevenuePercentage", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 91 + } + }, + { + "name": "UpdateSovereignAdmin", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 92 + } + }, + { + "name": "WithdrawRewards", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 93 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_LowerRevenuePercentage", "template": null, "peekable": false, "fields": [ { - "display_name": "rlp", + "display_name": "percentage_in_basis_points", "silent": false, "value": { - "ByIndex": 86 + "Immediate": { + "Integer": [ + "u16", + "Decimal" + ] + } }, "doc": "" } @@ -1782,19 +2058,32 @@ }, { "Struct": { - "type_name": "RlpEvmTransaction", + "type_name": "__SovVirtualWallet_CallMessage_UpdateSovereignAdmin", "template": null, "peekable": false, "fields": [ { - "display_name": "rlp", + "display_name": "new_admin", "silent": false, "value": { - "Immediate": { - "ByteVec": { - "display": "Hex" - } - } + "ByIndex": 9 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_WithdrawRewards", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "token_id", + "silent": false, + "value": { + "ByIndex": 20 }, "doc": "" } @@ -1808,7 +2097,7 @@ "fields": [ { "value": { - "ByIndex": 88 + "ByIndex": 95 }, "silent": false, "doc": "" @@ -1818,115 +2107,31 @@ }, { "Enum": { - "type_name": "AccessPatternMessages", + "type_name": "CallMessage", "variants": [ { - "name": "WriteCells", + "name": "Dispatch", "discriminant": 0, "template": null, - "value": { - "ByIndex": 89 - } - }, - { - "name": "WriteCustom", - "discriminant": 1, - "template": null, - "value": { - "ByIndex": 90 - } - }, - { - "name": "ReadCells", - "discriminant": 2, - "template": null, - "value": { - "ByIndex": 92 - } - }, - { - "name": "HashBytes", - "discriminant": 3, - "template": null, - "value": { - "ByIndex": 93 - } - }, - { - "name": "HashCustom", - "discriminant": 4, - "template": null, - "value": { - "ByIndex": 94 - } - }, - { - "name": "StoreSignature", - "discriminant": 5, - "template": null, - "value": { - "ByIndex": 95 - } - }, - { - "name": "VerifySignature", - "discriminant": 6, - "template": null, - "value": null - }, - { - "name": "VerifyCustomSignature", - "discriminant": 7, - "template": null, "value": { "ByIndex": 96 } }, { - "name": "StoreSerializedString", - "discriminant": 8, - "template": null, - "value": { - "ByIndex": 97 - } - }, - { - "name": "DeserializeBytesAsString", - "discriminant": 9, - "template": null, - "value": null - }, - { - "name": "DeserializeCustomString", - "discriminant": 10, - "template": null, - "value": { - "ByIndex": 98 - } - }, - { - "name": "DeleteCells", - "discriminant": 11, + "name": "Process", + "discriminant": 1, "template": null, "value": { "ByIndex": 99 } }, { - "name": "SetHook", - "discriminant": 12, + "name": "Announce", + "discriminant": 2, "template": null, "value": { "ByIndex": 100 } - }, - { - "name": "UpdateAdmin", - "discriminant": 13, - "template": null, - "value": { - "ByIndex": 107 - } } ], "hide_tag": false @@ -1934,17 +2139,17 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCells", + "type_name": "__SovVirtualWallet_CallMessage_Dispatch", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -1952,28 +2157,42 @@ "doc": "" }, { - "display_name": "num_cells", + "display_name": "recipient", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 50 }, "doc": "" }, { - "display_name": "data_size", + "display_name": "body", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] - } + "ByIndex": 97 + }, + "doc": "" + }, + { + "display_name": "metadata", + "silent": false, + "value": { + "ByIndex": 98 + }, + "doc": "" + }, + { + "display_name": "relayer", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + }, + { + "display_name": "gas_payment_limit", + "silent": false, + "value": { + "ByIndex": 8 }, "doc": "" } @@ -1981,71 +2200,50 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCustom", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "begin", - "silent": false, "value": { "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] + "ByteVec": { + "display": "Hex" + } } }, - "doc": "" - }, - { - "display_name": "content", "silent": false, - "value": { - "ByIndex": 91 - }, "doc": "" } ] } }, { - "Vec": { + "Option": { "value": { - "Immediate": "String" + "ByIndex": 97 } } }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_ReadCells", + "type_name": "__SovVirtualWallet_CallMessage_Process", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "metadata", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 97 }, "doc": "" }, { - "display_name": "num_cells", + "display_name": "message", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 97 }, "doc": "" } @@ -2054,33 +2252,31 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_HashBytes", + "type_name": "__SovVirtualWallet_CallMessage_Announce", "template": null, "peekable": false, "fields": [ { - "display_name": "filler", + "display_name": "validator_address", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u8", - "Decimal" - ] - } + "ByIndex": 101 }, "doc": "" }, { - "display_name": "size", + "display_name": "storage_location", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] - } + "Immediate": "String" + }, + "doc": "" + }, + { + "display_name": "signature", + "silent": false, + "value": { + "ByIndex": 102 }, "doc": "" } @@ -2088,107 +2284,127 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_HashCustom", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "input", - "silent": false, "value": { "Immediate": { - "ByteVec": { + "ByteArray": { + "len": 20, "display": "Hex" } } }, + "silent": false, "doc": "" } ] } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSignature", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "sign", - "silent": false, "value": { - "ByIndex": 4 + "Immediate": { + "ByteArray": { + "len": 65, + "display": "Hex" + } + } }, + "silent": false, "doc": "" - }, + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ { - "display_name": "pub_key", - "silent": false, "value": { - "ByIndex": 5 + "ByIndex": 104 }, + "silent": false, "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "SetRelayerConfig", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 105 + } }, { - "display_name": "message", - "silent": false, + "name": "UpdateOracleData", + "discriminant": 1, + "template": null, "value": { - "Immediate": "String" - }, - "doc": "" + "ByIndex": 111 + } + }, + { + "name": "ClaimRewards", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 112 + } } - ] + ], + "hide_tag": false } }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_VerifyCustomSignature", + "type_name": "__SovVirtualWallet_CallMessage_SetRelayerConfig", "template": null, "peekable": false, "fields": [ { - "display_name": "sign", + "display_name": "domain_oracle_data", "silent": false, "value": { - "ByIndex": 4 + "ByIndex": 106 }, "doc": "" }, { - "display_name": "pub_key", + "display_name": "domain_default_gas", "silent": false, "value": { - "ByIndex": 5 + "ByIndex": 109 }, "doc": "" }, { - "display_name": "message", + "display_name": "default_gas", "silent": false, "value": { - "Immediate": "String" + "ByIndex": 8 }, "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSerializedString", - "template": null, - "peekable": false, - "fields": [ + }, { - "display_name": "input", + "display_name": "beneficiary", "silent": false, "value": { - "Immediate": { - "ByteVec": { - "display": "Hex" - } - } + "ByIndex": 25 }, "doc": "" } @@ -2196,39 +2412,25 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_DeserializeCustomString", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "input", - "silent": false, - "value": { - "Immediate": { - "ByteVec": { - "display": "Hex" - } - } - }, - "doc": "" - } - ] + "Vec": { + "value": { + "ByIndex": 107 + } } }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_DeleteCells", + "type_name": "DomainOracleData", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2236,15 +2438,10 @@ "doc": "" }, { - "display_name": "num_cells", + "display_name": "data_value", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 108 }, "doc": "" } @@ -2253,88 +2450,54 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_SetHook", + "type_name": "ExchangeRateAndGasPrice", "template": null, "peekable": false, "fields": [ { - "display_name": "pre", + "display_name": "gas_price", "silent": false, "value": { - "ByIndex": 101 + "ByIndex": 8 }, "doc": "" }, { - "display_name": "post", + "display_name": "token_exchange_rate", "silent": false, "value": { - "ByIndex": 101 + "Immediate": { + "Integer": [ + "u128", + "Decimal" + ] + } }, "doc": "" } ] } }, - { - "Option": { - "value": { - "ByIndex": 102 - } - } - }, { "Vec": { "value": { - "ByIndex": 103 + "ByIndex": 110 } } }, - { - "Enum": { - "type_name": "HooksConfig", - "variants": [ - { - "name": "Read", - "discriminant": 0, - "template": null, - "value": { - "ByIndex": 104 - } - }, - { - "name": "Write", - "discriminant": 1, - "template": null, - "value": { - "ByIndex": 105 - } - }, - { - "name": "Delete", - "discriminant": 2, - "template": null, - "value": { - "ByIndex": 106 - } - } - ], - "hide_tag": false - } - }, { "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Read", + "type_name": "DomainDefaultGas", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2342,15 +2505,10 @@ "doc": "" }, { - "display_name": "size", + "display_name": "default_gas", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 8 }, "doc": "" } @@ -2359,30 +2517,17 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Write", + "type_name": "__SovVirtualWallet_CallMessage_UpdateOracleData", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", - "silent": false, - "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } - }, - "doc": "" - }, - { - "display_name": "size", + "display_name": "domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2390,15 +2535,10 @@ "doc": "" }, { - "display_name": "data_size", + "display_name": "oracle_data", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] - } + "ByIndex": 108 }, "doc": "" } @@ -2407,33 +2547,15 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Delete", + "type_name": "__SovVirtualWallet_CallMessage_ClaimRewards", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", - "silent": false, - "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } - }, - "doc": "" - }, - { - "display_name": "size", + "display_name": "relayer_address", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 9 }, "doc": "" } @@ -2441,17 +2563,19 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "new_admin", - "silent": false, "value": { - "ByIndex": 12 + "Immediate": { + "Skip": { + "len": 0 + } + } }, + "silent": false, "doc": "" } ] @@ -2464,7 +2588,7 @@ "fields": [ { "value": { - "ByIndex": 109 + "ByIndex": 115 }, "silent": false, "doc": "" @@ -2477,27 +2601,43 @@ "type_name": "CallMessage", "variants": [ { - "name": "ReadAndSetManyIndividualValues", + "name": "Register", "discriminant": 0, "template": null, "value": { - "ByIndex": 110 + "ByIndex": 116 } }, { - "name": "ReadAndSetHeavyState", + "name": "Update", "discriminant": 1, "template": null, "value": { - "ByIndex": 111 + "ByIndex": 128 } }, { - "name": "RunCPUHeavyOperation", + "name": "EnrollRemoteRouter", "discriminant": 2, "template": null, "value": { - "ByIndex": 112 + "ByIndex": 131 + } + }, + { + "name": "UnEnrollRemoteRouter", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 132 + } + }, + { + "name": "TransferRemote", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 133 } } ], @@ -2506,65 +2646,165 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "type_name": "__SovVirtualWallet_CallMessage_Register", "template": null, "peekable": false, "fields": [ { - "display_name": "number_of_operations", + "display_name": "admin", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 117 }, "doc": "" }, { - "display_name": "salt", + "display_name": "token_source", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 119 + }, + "doc": "" + }, + { + "display_name": "ism", + "silent": false, + "value": { + "ByIndex": 122 + }, + "doc": "" + }, + { + "display_name": "remote_routers", + "silent": false, + "value": { + "ByIndex": 126 + }, + "doc": "" + }, + { + "display_name": "inbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "inbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "outbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "outbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "Admin", + "variants": [ + { + "name": "None", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "InsecureOwner", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 118 + } + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 9 }, + "silent": false, "doc": "" } ] } }, + { + "Enum": { + "type_name": "TokenKind", + "variants": [ + { + "name": "Synthetic", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 120 + } + }, + { + "name": "Collateral", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 121 + } + }, + { + "name": "Native", + "discriminant": 2, + "template": null, + "value": null + } + ], + "hide_tag": false + } + }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "type_name": "__SovVirtualWallet_TokenKind_Synthetic", "template": null, "peekable": false, "fields": [ { - "display_name": "number_of_new_values", + "display_name": "remote_token_id", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 50 }, "doc": "" }, { - "display_name": "max_heavy_state_size", + "display_name": "remote_decimals", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u8", "Decimal" ] } @@ -2572,15 +2812,10 @@ "doc": "" }, { - "display_name": "salt", + "display_name": "local_decimals", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 7 }, "doc": "" } @@ -2589,63 +2824,89 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "type_name": "__SovVirtualWallet_TokenKind_Collateral", "template": null, "peekable": false, "fields": [ { - "display_name": "iterations", + "display_name": "token", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 20 }, "doc": "" } ] } }, + { + "Enum": { + "type_name": "Ism", + "variants": [ + { + "name": "AlwaysTrust", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "TrustedRelayer", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 123 + } + }, + { + "name": "MessageIdMultisig", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 124 + } + } + ], + "hide_tag": false + } + }, { "Struct": { - "type_name": "TxDetails", + "type_name": "__SovVirtualWallet_Ism_TrustedRelayer", "template": null, "peekable": false, "fields": [ { - "display_name": "max_priority_fee_bips", - "silent": false, - "value": { - "ByIndex": 114 - }, - "doc": "" - }, - { - "display_name": "max_fee", + "display_name": "relayer", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 50 }, "doc": "" - }, + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_Ism_MessageIdMultisig", + "template": null, + "peekable": false, + "fields": [ { - "display_name": "gas_limit", + "display_name": "validators", "silent": false, "value": { - "ByIndex": 61 + "ByIndex": 125 }, "doc": "" }, { - "display_name": "chain_id", + "display_name": "threshold", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2655,6 +2916,20 @@ ] } }, + { + "Vec": { + "value": { + "ByIndex": 101 + } + } + }, + { + "Vec": { + "value": { + "ByIndex": 127 + } + } + }, { "Tuple": { "template": null, @@ -2664,134 +2939,1974 @@ "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } }, "silent": false, "doc": "" + }, + { + "value": { + "ByIndex": 50 + }, + "silent": false, + "doc": "" } ] } }, { "Struct": { - "type_name": "UnsignedTransaction", + "type_name": "__SovVirtualWallet_CallMessage_Update", "template": null, "peekable": false, "fields": [ { - "display_name": "runtime_call", + "display_name": "warp_route", "silent": false, "value": { - "ByIndex": 6 + "ByIndex": 50 }, "doc": "" }, { - "display_name": "generation", + "display_name": "admin", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 129 }, "doc": "" }, { - "display_name": "details", + "display_name": "ism", "silent": false, "value": { - "ByIndex": 113 + "ByIndex": 130 }, "doc": "" - } - ] - } - } - ], - "root_type_indices": [ - 0, - 115, - 6, - 12 - ], - "chain_data": { - "chain_id": 4321, - "chain_name": "TestChain" - }, - "templates": [ - {}, - {}, + }, + { + "display_name": "inbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "inbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "outbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "outbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + } + ] + } + }, { - "transfer": { - "preencoded_bytes": [ - 0, - 1 - ], - "inputs": [ - [ - "to", - { - "type_link": { - "ByIndex": 12 - }, - "offset": 2 - } - ], - [ - "amount", - { - "type_link": { - "Immediate": { - "Integer": [ - "u128", - { - "FixedPoint": { - "FromSiblingField": { - "field_index": 1, - "byte_offset": 31 - } - } - } - ] - } - }, - "offset": 2 + "Option": { + "value": { + "ByIndex": 117 + } + } + }, + { + "Option": { + "value": { + "ByIndex": 122 + } + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_EnrollRemoteRouter", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "warp_route", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "remote_domain", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "remote_router_address", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_UnEnrollRemoteRouter", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "warp_route", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "remote_domain", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_TransferRemote", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "warp_route", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "destination_domain", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "recipient", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "amount", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "relayer", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + }, + { + "display_name": "gas_payment_limit", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 135 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "Call", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 136 } - ], - [ - "token_id", - { - "type_link": { - "ByIndex": 21 - }, - "offset": 2 + }, + { + "name": "UpdateRuntimeConfig", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 138 } - ] + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 137 + }, + "silent": false, + "doc": "" + } ] } }, - {} - ], - "serde_metadata": [ { - "name": "Transaction", + "Struct": { + "type_name": "RlpEvmTransaction", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "rlp", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 139 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "EvmRuntimeConfigUpdate", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_hardfork", + "silent": false, + "value": { + "ByIndex": 140 + }, + "doc": "" + }, + { + "display_name": "new_contract_creation_policy", + "silent": false, + "value": { + "ByIndex": 142 + }, + "doc": "" + }, + { + "display_name": "chain_spec_update", + "silent": false, + "value": { + "ByIndex": 145 + }, + "doc": "" + }, + { + "display_name": "new_admin", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 141 + } + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + }, + { + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 143 + } + } + }, + { + "Enum": { + "type_name": "ContractCreationPolicyUpdate", + "variants": [ + { + "name": "Everyone", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "Allowlist", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 144 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_ContractCreationPolicyUpdate_Allowlist", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "add", + "silent": false, + "value": { + "ByIndex": 125 + }, + "doc": "" + }, + { + "display_name": "remove", + "silent": false, + "value": { + "ByIndex": 125 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 146 + } + } + }, + { + "Struct": { + "type_name": "ChainSpecUpdate", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_limit_contract_code_size", + "silent": false, + "value": { + "ByIndex": 147 + }, + "doc": "" + }, + { + "display_name": "new_block_gas_limit", + "silent": false, + "value": { + "ByIndex": 72 + }, + "doc": "" + }, + { + "display_name": "new_tx_gas_limit", + "silent": false, + "value": { + "ByIndex": 72 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + } + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 149 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "AccessPatternMessages", + "variants": [ + { + "name": "WriteCells", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 150 + } + }, + { + "name": "WriteCustom", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 151 + } + }, + { + "name": "ReadCells", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 153 + } + }, + { + "name": "HashBytes", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 154 + } + }, + { + "name": "HashCustom", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 155 + } + }, + { + "name": "StoreSignature", + "discriminant": 5, + "template": null, + "value": { + "ByIndex": 156 + } + }, + { + "name": "VerifySignature", + "discriminant": 6, + "template": null, + "value": null + }, + { + "name": "VerifyCustomSignature", + "discriminant": 7, + "template": null, + "value": { + "ByIndex": 157 + } + }, + { + "name": "StoreSerializedString", + "discriminant": 8, + "template": null, + "value": { + "ByIndex": 158 + } + }, + { + "name": "DeserializeBytesAsString", + "discriminant": 9, + "template": null, + "value": null + }, + { + "name": "DeserializeCustomString", + "discriminant": 10, + "template": null, + "value": { + "ByIndex": 159 + } + }, + { + "name": "DeleteCells", + "discriminant": 11, + "template": null, + "value": { + "ByIndex": 160 + } + }, + { + "name": "UpdateAdmin", + "discriminant": 12, + "template": null, + "value": { + "ByIndex": 161 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "data_size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCustom", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "content", + "silent": false, + "value": { + "ByIndex": 152 + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "Immediate": "String" + } + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_ReadCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_HashBytes", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "filler", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_HashCustom", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "sign", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "message", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_VerifyCustomSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "sign", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "message", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSerializedString", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_DeserializeCustomString", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_DeleteCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_admin", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 163 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "ReadAndSetManyIndividualValues", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 164 + } + }, + { + "name": "ReadAndSetHeavyState", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 165 + } + }, + { + "name": "RunCPUHeavyOperation", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 166 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "number_of_operations", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "salt", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "number_of_new_values", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "max_heavy_state_size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "salt", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "iterations", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "UniquenessData", + "variants": [ + { + "name": "Nonce", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 168 + } + }, + { + "name": "Generation", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 169 + } + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "TxDetails", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "max_priority_fee_bips", + "silent": false, + "value": { + "ByIndex": 171 + }, + "doc": "" + }, + { + "display_name": "max_fee", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "gas_limit", + "silent": false, + "value": { + "ByIndex": 66 + }, + "doc": "" + }, + { + "display_name": "chain_id", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 173 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "Version1", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "signatures", + "silent": false, + "value": { + "ByIndex": 174 + }, + "doc": "" + }, + { + "display_name": "unused_pub_keys", + "silent": false, + "value": { + "ByIndex": 176 + }, + "doc": "" + }, + { + "display_name": "min_signers", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + }, + { + "display_name": "target_address", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "ByIndex": 175 + } + } + }, + { + "Struct": { + "type_name": "PubKeyAndSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "signature", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + } + } + }, + { + "Enum": { + "type_name": "UnsignedTransaction", + "variants": [ + { + "name": "V0", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 178 + } + }, + { + "name": "V1", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 180 + } + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 179 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "UnsignedTransactionV0", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 181 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "UnsignedTransactionV1", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + }, + { + "display_name": "credential_address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "target_address", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + } + ], + "root_type_indices": [ + 0, + 177, + 3, + 9 + ], + "chain_data": { + "chain_id": 4321, + "chain_name": "TestChain" + }, + "templates": [ + {}, + {}, + { + "transfer": { + "preencoded_bytes": [ + 0, + 1 + ], + "inputs": [ + [ + "to", + { + "type_link": { + "ByIndex": 9 + }, + "offset": 2 + } + ], + [ + "amount", + { + "type_link": { + "Immediate": { + "Integer": [ + "u128", + { + "FixedPoint": { + "FromSiblingField": { + "field_index": 1, + "byte_offset": 31 + } + } + } + ] + } + }, + "offset": 2 + } + ], + [ + "token_id", + { + "type_link": { + "ByIndex": 20 + }, + "offset": 2 + } + ] + ] + } + }, + {} + ], + "serde_metadata": [ + { + "name": "Transaction", + "fields_or_variants": [ + { + "name": "V0" + }, + { + "name": "V1" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "Version0", + "fields_or_variants": [ + { + "name": "signature" + }, + { + "name": "pub_key" + }, + { + "name": "runtime_call" + }, + { + "name": "uniqueness" + }, + { + "name": "details" + } + ] + }, + { + "name": "RuntimeCall", + "fields_or_variants": [ + { + "name": "bank" + }, + { + "name": "sequencer_registry" + }, + { + "name": "operator_incentives" + }, + { + "name": "attester_incentives" + }, + { + "name": "prover_incentives" + }, + { + "name": "accounts" + }, + { + "name": "uniqueness" + }, + { + "name": "chain_state" + }, + { + "name": "blob_storage" + }, + { + "name": "paymaster" + }, + { + "name": "revenue_share" + }, + { + "name": "mailbox" + }, + { + "name": "interchain_gas_paymaster" + }, + { + "name": "merkle_tree_hook" + }, + { + "name": "warp" + }, + { + "name": "evm" + }, + { + "name": "access_pattern" + }, + { + "name": "synthetic_load" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "create_token" + }, + { + "name": "transfer" + }, + { + "name": "burn" + }, + { + "name": "mint" + }, + { + "name": "freeze" + }, + { + "name": "update_admin" + }, + { + "name": "transfer_with_memo" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_CreateToken", + "fields_or_variants": [ + { + "name": "token_name" + }, + { + "name": "token_decimals" + }, + { + "name": "initial_balance" + }, + { + "name": "mint_to_address" + }, + { + "name": "admins" + }, + { + "name": "supply_cap" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "MultiAddressEvmSolana", + "fields_or_variants": [ + { + "name": "Standard" + }, + { + "name": "Evm" + }, + { + "name": "Solana" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Transfer", + "fields_or_variants": [ + { + "name": "to" + }, + { + "name": "coins" + } + ] + }, + { + "name": "Coins", + "fields_or_variants": [ + { + "name": "amount" + }, + { + "name": "token_id" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Burn", + "fields_or_variants": [ + { + "name": "coins" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Mint", + "fields_or_variants": [ + { + "name": "coins" + }, + { + "name": "mint_to_address" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Freeze", + "fields_or_variants": [ + { + "name": "token_id" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateAdmin", + "fields_or_variants": [ + { + "name": "new_admin" + }, + { + "name": "token_id" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_TransferWithMemo", + "fields_or_variants": [ + { + "name": "to" + }, + { + "name": "coins" + }, + { + "name": "memo" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "register" + }, + { + "name": "deposit" + }, + { + "name": "initiate_withdrawal" + }, + { + "name": "withdraw" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Register", + "fields_or_variants": [ + { + "name": "da_address" + }, + { + "name": "amount" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Deposit", + "fields_or_variants": [ + { + "name": "da_address" + }, + { + "name": "amount" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_InitiateWithdrawal", + "fields_or_variants": [ + { + "name": "da_address" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Withdraw", "fields_or_variants": [ { - "name": "versioned_tx" + "name": "da_address" } ] }, { - "name": "VersionedTx", + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", "fields_or_variants": [ { - "name": "V0" + "name": "update_reward_address" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateRewardAddress", + "fields_or_variants": [ + { + "name": "new_reward_address" } ] }, @@ -2800,82 +4915,289 @@ "fields_or_variants": [] }, { - "name": "Version0", + "name": "CallMessage", "fields_or_variants": [ { - "name": "signature" + "name": "register_attester" }, { - "name": "pub_key" + "name": "begin_exit_attester" }, { - "name": "runtime_call" + "name": "exit_attester" }, { - "name": "generation" + "name": "register_challenger" }, { - "name": "details" + "name": "exit_challenger" + }, + { + "name": "deposit_attester" } ] }, { - "name": "Ed25519Signature", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", "fields_or_variants": [ { - "name": "msg_sig" + "name": "register" + }, + { + "name": "deposit" + }, + { + "name": "exit" } ] }, { - "name": "Ed25519PublicKey", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", "fields_or_variants": [ { - "name": "pub_key" + "name": "insert_credential_id" + }, + { + "name": "add_credential_to_address" + }, + { + "name": "remove_credential_from_address" + }, + { + "name": "rotate_credential_on_address" } ] }, { - "name": "RuntimeCall", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_AddCredentialToAddress", "fields_or_variants": [ { - "name": "bank" + "name": "address" }, { - "name": "sequencer_registry" + "name": "credential" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RemoveCredentialFromAddress", + "fields_or_variants": [ + { + "name": "address" }, { - "name": "operator_incentives" + "name": "credential" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RotateCredentialOnAddress", + "fields_or_variants": [ + { + "name": "address" }, { - "name": "attester_incentives" + "name": "old_credential" }, { - "name": "prover_incentives" + "name": "new_credential" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "NotInstantiable", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "TerminateSetupMode" }, { - "name": "accounts" + "name": "SetOracleTime" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_SetOracleTime", + "fields_or_variants": [ + { + "name": "milliseconds_since_epoch" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "register_paymaster" }, { - "name": "uniqueness" + "name": "set_payer_for_sequencer" }, { - "name": "chain_state" + "name": "update_policy" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", + "fields_or_variants": [ + { + "name": "policy" + } + ] + }, + { + "name": "PaymasterPolicyInitializer", + "fields_or_variants": [ + { + "name": "default_payee_policy" }, { - "name": "blob_storage" + "name": "payees" }, { - "name": "paymaster" + "name": "authorized_updaters" }, { - "name": "evm" + "name": "authorized_sequencers" + } + ] + }, + { + "name": "PayeePolicy", + "fields_or_variants": [ + { + "name": "allow" }, { - "name": "access_pattern" + "name": "deny" + } + ] + }, + { + "name": "__SovVirtualWallet_PayeePolicy_Allow", + "fields_or_variants": [ + { + "name": "max_fee" + }, + { + "name": "gas_limit" + }, + { + "name": "max_gas_price" + }, + { + "name": "transaction_limit" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "GasPrice", + "fields_or_variants": [ + { + "name": "value" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "AuthorizedSequencers", + "fields_or_variants": [ + { + "name": "all" }, { - "name": "synthetic_load" + "name": "some" } ] }, @@ -2884,48 +5206,48 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_SetPayerForSequencer", "fields_or_variants": [ { - "name": "create_token" - }, - { - "name": "transfer" - }, - { - "name": "burn" - }, - { - "name": "mint" - }, + "name": "payer" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdatePolicy", + "fields_or_variants": [ { - "name": "freeze" + "name": "payer" }, { - "name": "update_admin" + "name": "update" } ] }, { - "name": "__SovVirtualWallet_CallMessage_CreateToken", + "name": "PolicyUpdate", "fields_or_variants": [ { - "name": "token_name" + "name": "sequencer_update" }, { - "name": "token_decimals" + "name": "updaters_to_add" }, { - "name": "initial_balance" + "name": "updaters_to_remove" }, { - "name": "mint_to_address" + "name": "payee_policies_to_set" }, { - "name": "admins" + "name": "payee_policies_to_delete" }, { - "name": "supply_cap" + "name": "default_policy" } ] }, @@ -2934,17 +5256,13 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "MultiAddress", + "name": "SequencerSetUpdate", "fields_or_variants": [ { - "name": "Standard" + "name": "allow_all" }, { - "name": "Vm" + "name": "update" } ] }, @@ -2952,6 +5270,17 @@ "name": "", "fields_or_variants": [] }, + { + "name": "AllowedSequencerUpdate", + "fields_or_variants": [ + { + "name": "to_add" + }, + { + "name": "to_remove" + } + ] + }, { "name": "", "fields_or_variants": [] @@ -2973,22 +5302,44 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_Transfer", + "name": "CallMessage", "fields_or_variants": [ { - "name": "to" + "name": "activate_revenue_share" }, { - "name": "coins" + "name": "deactivate_revenue_share" + }, + { + "name": "lower_revenue_percentage" + }, + { + "name": "update_sovereign_admin" + }, + { + "name": "withdraw_rewards" } ] }, { - "name": "Coins", + "name": "__SovVirtualWallet_CallMessage_LowerRevenuePercentage", "fields_or_variants": [ { - "name": "amount" - }, + "name": "percentage_in_basis_points" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateSovereignAdmin", + "fields_or_variants": [ + { + "name": "new_admin" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_WithdrawRewards", + "fields_or_variants": [ { "name": "token_id" } @@ -2999,40 +5350,72 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_Burn", + "name": "CallMessage", "fields_or_variants": [ { - "name": "coins" + "name": "dispatch" + }, + { + "name": "process" + }, + { + "name": "announce" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Mint", + "name": "__SovVirtualWallet_CallMessage_Dispatch", "fields_or_variants": [ { - "name": "coins" + "name": "domain" }, { - "name": "mint_to_address" + "name": "recipient" + }, + { + "name": "body" + }, + { + "name": "metadata" + }, + { + "name": "relayer" + }, + { + "name": "gas_payment_limit" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Freeze", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Process", "fields_or_variants": [ { - "name": "token_id" + "name": "metadata" + }, + { + "name": "message" } ] }, { - "name": "__SovVirtualWallet_CallMessage_UpdateAdmin", + "name": "__SovVirtualWallet_CallMessage_Announce", "fields_or_variants": [ { - "name": "new_admin" + "name": "validator_address" }, { - "name": "token_id" + "name": "storage_location" + }, + { + "name": "signature" } ] }, @@ -3044,31 +5427,38 @@ "name": "", "fields_or_variants": [] }, + { + "name": "", + "fields_or_variants": [] + }, { "name": "CallMessage", "fields_or_variants": [ { - "name": "register" - }, - { - "name": "deposit" + "name": "set_relayer_config" }, { - "name": "initiate_withdrawal" + "name": "update_oracle_data" }, { - "name": "withdraw" + "name": "claim_rewards" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Register", + "name": "__SovVirtualWallet_CallMessage_SetRelayerConfig", "fields_or_variants": [ { - "name": "da_address" + "name": "domain_oracle_data" }, { - "name": "amount" + "name": "domain_default_gas" + }, + { + "name": "default_gas" + }, + { + "name": "beneficiary" } ] }, @@ -3077,49 +5467,58 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_Deposit", + "name": "DomainOracleData", "fields_or_variants": [ { - "name": "da_address" + "name": "domain" }, { - "name": "amount" + "name": "data_value" } ] }, { - "name": "__SovVirtualWallet_CallMessage_InitiateWithdrawal", + "name": "ExchangeRateAndGasPrice", "fields_or_variants": [ { - "name": "da_address" + "name": "gas_price" + }, + { + "name": "token_exchange_rate" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Withdraw", + "name": "", + "fields_or_variants": [] + }, + { + "name": "DomainDefaultGas", "fields_or_variants": [ { - "name": "da_address" + "name": "domain" + }, + { + "name": "default_gas" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "CallMessage", + "name": "__SovVirtualWallet_CallMessage_UpdateOracleData", "fields_or_variants": [ { - "name": "update_reward_address" + "name": "domain" + }, + { + "name": "oracle_data" } ] }, { - "name": "__SovVirtualWallet_CallMessage_UpdateRewardAddress", + "name": "__SovVirtualWallet_CallMessage_ClaimRewards", "fields_or_variants": [ { - "name": "new_reward_address" + "name": "relayer_address" } ] }, @@ -3127,76 +5526,67 @@ "name": "", "fields_or_variants": [] }, + { + "name": "", + "fields_or_variants": [] + }, { "name": "CallMessage", "fields_or_variants": [ { - "name": "register_attester" - }, - { - "name": "begin_exit_attester" + "name": "register" }, { - "name": "exit_attester" + "name": "update" }, { - "name": "register_challenger" + "name": "enroll_remote_router" }, { - "name": "exit_challenger" + "name": "un_enroll_remote_router" }, { - "name": "deposit_attester" + "name": "transfer_remote" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "CallMessage", + "name": "__SovVirtualWallet_CallMessage_Register", "fields_or_variants": [ { - "name": "register" + "name": "admin" }, { - "name": "deposit" + "name": "token_source" }, { - "name": "exit" + "name": "ism" + }, + { + "name": "remote_routers" + }, + { + "name": "inbound_transferrable_tokens_limit" + }, + { + "name": "inbound_limit_replenishment_per_slot" + }, + { + "name": "outbound_transferrable_tokens_limit" + }, + { + "name": "outbound_limit_replenishment_per_slot" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "CallMessage", + "name": "Admin", "fields_or_variants": [ { - "name": "insert_credential_id" + "name": "None" + }, + { + "name": "InsecureOwner" } ] }, @@ -3205,127 +5595,73 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "NotInstantiable", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "CallMessage", + "name": "TokenKind", "fields_or_variants": [ { - "name": "register_paymaster" + "name": "Synthetic" }, { - "name": "set_payer_for_sequencer" + "name": "Collateral" }, { - "name": "update_policy" - } - ] - }, - { - "name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", - "fields_or_variants": [ - { - "name": "policy" + "name": "Native" } ] }, { - "name": "PaymasterPolicyInitializer", + "name": "__SovVirtualWallet_TokenKind_Synthetic", "fields_or_variants": [ { - "name": "default_payee_policy" - }, - { - "name": "payees" + "name": "remote_token_id" }, { - "name": "authorized_updaters" + "name": "remote_decimals" }, { - "name": "authorized_sequencers" + "name": "local_decimals" } ] }, { - "name": "PayeePolicy", + "name": "__SovVirtualWallet_TokenKind_Collateral", "fields_or_variants": [ { - "name": "allow" - }, - { - "name": "deny" + "name": "token" } ] }, { - "name": "__SovVirtualWallet_PayeePolicy_Allow", + "name": "Ism", "fields_or_variants": [ { - "name": "max_fee" - }, - { - "name": "gas_limit" + "name": "AlwaysTrust" }, { - "name": "max_gas_price" + "name": "TrustedRelayer" }, { - "name": "transaction_limit" + "name": "MessageIdMultisig" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "GasPrice", + "name": "__SovVirtualWallet_Ism_TrustedRelayer", "fields_or_variants": [ { - "name": "value" + "name": "relayer" } ] }, { - "name": "", - "fields_or_variants": [] + "name": "__SovVirtualWallet_Ism_MessageIdMultisig", + "fields_or_variants": [ + { + "name": "validators" + }, + { + "name": "threshold" + } + ] }, { "name": "", @@ -3340,13 +5676,28 @@ "fields_or_variants": [] }, { - "name": "AuthorizedSequencers", + "name": "__SovVirtualWallet_CallMessage_Update", "fields_or_variants": [ { - "name": "all" + "name": "warp_route" }, { - "name": "some" + "name": "admin" + }, + { + "name": "ism" + }, + { + "name": "inbound_transferrable_tokens_limit" + }, + { + "name": "inbound_limit_replenishment_per_slot" + }, + { + "name": "outbound_transferrable_tokens_limit" + }, + { + "name": "outbound_limit_replenishment_per_slot" } ] }, @@ -3359,44 +5710,50 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_SetPayerForSequencer", + "name": "__SovVirtualWallet_CallMessage_EnrollRemoteRouter", "fields_or_variants": [ { - "name": "payer" + "name": "warp_route" + }, + { + "name": "remote_domain" + }, + { + "name": "remote_router_address" } ] }, { - "name": "__SovVirtualWallet_CallMessage_UpdatePolicy", + "name": "__SovVirtualWallet_CallMessage_UnEnrollRemoteRouter", "fields_or_variants": [ { - "name": "payer" + "name": "warp_route" }, { - "name": "update" + "name": "remote_domain" } ] }, { - "name": "PolicyUpdate", + "name": "__SovVirtualWallet_CallMessage_TransferRemote", "fields_or_variants": [ { - "name": "sequencer_update" + "name": "warp_route" }, { - "name": "updaters_to_add" + "name": "destination_domain" }, { - "name": "updaters_to_remove" + "name": "recipient" }, { - "name": "payee_policies_to_set" + "name": "amount" }, { - "name": "payee_policies_to_delete" + "name": "relayer" }, { - "name": "default_policy" + "name": "gas_payment_limit" } ] }, @@ -3405,13 +5762,13 @@ "fields_or_variants": [] }, { - "name": "SequencerSetUpdate", + "name": "CallMessage", "fields_or_variants": [ { - "name": "allow_all" + "name": "Call" }, { - "name": "update" + "name": "UpdateRuntimeConfig" } ] }, @@ -3420,13 +5777,10 @@ "fields_or_variants": [] }, { - "name": "AllowedSequencerUpdate", + "name": "RlpEvmTransaction", "fields_or_variants": [ { - "name": "to_add" - }, - { - "name": "to_remove" + "name": "rlp" } ] }, @@ -3435,8 +5789,21 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] + "name": "EvmRuntimeConfigUpdate", + "fields_or_variants": [ + { + "name": "new_hardfork" + }, + { + "name": "new_contract_creation_policy" + }, + { + "name": "chain_spec_update" + }, + { + "name": "new_admin" + } + ] }, { "name": "", @@ -3451,18 +5818,42 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "ContractCreationPolicyUpdate", "fields_or_variants": [ { - "name": "rlp" + "name": "Everyone" + }, + { + "name": "Allowlist" } ] }, { - "name": "RlpEvmTransaction", + "name": "__SovVirtualWallet_ContractCreationPolicyUpdate_Allowlist", "fields_or_variants": [ { - "name": "rlp" + "name": "add" + }, + { + "name": "remove" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "ChainSpecUpdate", + "fields_or_variants": [ + { + "name": "new_limit_contract_code_size" + }, + { + "name": "new_block_gas_limit" + }, + { + "name": "new_tx_gas_limit" } ] }, @@ -3470,6 +5861,10 @@ "name": "", "fields_or_variants": [] }, + { + "name": "", + "fields_or_variants": [] + }, { "name": "AccessPatternMessages", "fields_or_variants": [ @@ -3509,9 +5904,6 @@ { "name": "delete_cells" }, - { - "name": "set_hook" - }, { "name": "update_admin" } @@ -3632,13 +6024,10 @@ ] }, { - "name": "__SovVirtualWallet_AccessPatternMessages_SetHook", + "name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", "fields_or_variants": [ { - "name": "pre" - }, - { - "name": "post" + "name": "new_admin" } ] }, @@ -3647,64 +6036,60 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "HooksConfig", + "name": "CallMessage", "fields_or_variants": [ { - "name": "Read" + "name": "read_and_set_many_individual_values" }, { - "name": "Write" + "name": "read_and_set_heavy_state" }, { - "name": "Delete" + "name": "run_cpu_heavy_operation" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Read", + "name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", "fields_or_variants": [ { - "name": "begin" + "name": "number_of_operations" }, { - "name": "size" + "name": "salt" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Write", + "name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", "fields_or_variants": [ { - "name": "begin" + "name": "number_of_new_values" }, { - "name": "size" + "name": "max_heavy_state_size" }, { - "name": "data_size" + "name": "salt" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Delete", + "name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", "fields_or_variants": [ { - "name": "begin" - }, - { - "name": "size" + "name": "iterations" } ] }, { - "name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", + "name": "UniquenessData", "fields_or_variants": [ { - "name": "new_admin" + "name": "nonce" + }, + { + "name": "generation" } ] }, @@ -3713,66 +6098,105 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "", + "fields_or_variants": [] + }, + { + "name": "TxDetails", "fields_or_variants": [ { - "name": "read_and_set_many_individual_values" + "name": "max_priority_fee_bips" }, { - "name": "read_and_set_heavy_state" + "name": "max_fee" }, { - "name": "run_cpu_heavy_operation" + "name": "gas_limit" + }, + { + "name": "chain_id" } ] }, { - "name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "Version1", "fields_or_variants": [ { - "name": "number_of_operations" + "name": "signatures" }, { - "name": "salt" + "name": "unused_pub_keys" + }, + { + "name": "min_signers" + }, + { + "name": "runtime_call" + }, + { + "name": "uniqueness" + }, + { + "name": "details" + }, + { + "name": "target_address" } ] }, { - "name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "name": "", + "fields_or_variants": [] + }, + { + "name": "PubKeyAndSignature", "fields_or_variants": [ { - "name": "number_of_new_values" - }, - { - "name": "max_heavy_state_size" + "name": "signature" }, { - "name": "salt" + "name": "pub_key" } ] }, { - "name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "name": "", + "fields_or_variants": [] + }, + { + "name": "UnsignedTransaction", "fields_or_variants": [ { - "name": "iterations" + "name": "V0" + }, + { + "name": "V1" } ] }, { - "name": "TxDetails", + "name": "", + "fields_or_variants": [] + }, + { + "name": "UnsignedTransactionV0", "fields_or_variants": [ { - "name": "max_priority_fee_bips" - }, - { - "name": "max_fee" + "name": "runtime_call" }, { - "name": "gas_limit" + "name": "uniqueness" }, { - "name": "chain_id" + "name": "details" } ] }, @@ -3781,16 +6205,22 @@ "fields_or_variants": [] }, { - "name": "UnsignedTransaction", + "name": "UnsignedTransactionV1", "fields_or_variants": [ { "name": "runtime_call" }, { - "name": "generation" + "name": "uniqueness" }, { "name": "details" + }, + { + "name": "credential_address" + }, + { + "name": "target_address" } ] } diff --git a/examples/demo-rollup/stf/stf-declaration/src/address.rs b/examples/demo-rollup/stf/stf-declaration/src/address.rs index 3b73b03474..28116de86c 100644 --- a/examples/demo-rollup/stf/stf-declaration/src/address.rs +++ b/examples/demo-rollup/stf/stf-declaration/src/address.rs @@ -10,7 +10,7 @@ use std::str::FromStr; use borsh::{BorshDeserialize, BorshSerialize}; use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use sov_address::{EthereumAddress, FromVmAddress}; +use sov_address::{EthereumAddress, FromVmAddress, TryDecodeCredentialId}; use sov_hyperlane_integration::HyperlaneAddress; use sov_modules_api::macros::UniversalWallet; use sov_modules_api::{ @@ -54,6 +54,14 @@ impl From for MultiAddressEvmSolana { impl From for MultiAddressEvmSolana { fn from(value: CredentialId) -> Self { + // EVM credentials pack the 20-byte address into the low 20 bytes of + // the 32-byte credential (12 zero bytes of padding); recover the + // `Evm` variant so the canonical-address relationship round-trips + // for EVM signers. Native and Solana credentials are hashes with + // no such structural marker, so they fall back to `Standard`. + if let Some(eth_addr) = EthereumAddress::try_decode_credential_id(value) { + return Self::Evm(eth_addr); + } Self::Standard(Address::from(value)) } } diff --git a/examples/demo-rollup/tests/resync/data/mock_da.sqlite b/examples/demo-rollup/tests/resync/data/mock_da.sqlite index ab0373e365..5a97b0e80f 100644 Binary files a/examples/demo-rollup/tests/resync/data/mock_da.sqlite and b/examples/demo-rollup/tests/resync/data/mock_da.sqlite differ diff --git a/typescript/packages/__fixtures__/demo-rollup-schema.json b/typescript/packages/__fixtures__/demo-rollup-schema.json index 81efd8936e..69600db297 100644 --- a/typescript/packages/__fixtures__/demo-rollup-schema.json +++ b/typescript/packages/__fixtures__/demo-rollup-schema.json @@ -1,32 +1,23 @@ { "types": [ - { - "Struct": { - "type_name": "Transaction", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "versioned_tx", - "silent": false, - "value": { - "ByIndex": 1 - }, - "doc": "" - } - ] - } - }, { "Enum": { - "type_name": "VersionedTx", + "type_name": "Transaction", "variants": [ { "name": "V0", "discriminant": 0, "template": null, "value": { - "ByIndex": 2 + "ByIndex": 1 + } + }, + { + "name": "V1", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 172 } } ], @@ -40,7 +31,7 @@ "fields": [ { "value": { - "ByIndex": 3 + "ByIndex": 2 }, "silent": false, "doc": "" @@ -58,7 +49,12 @@ "display_name": "signature", "silent": false, "value": { - "ByIndex": 4 + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } }, "doc": "" }, @@ -66,7 +62,12 @@ "display_name": "pub_key", "silent": false, "value": { - "ByIndex": 5 + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } }, "doc": "" }, @@ -74,20 +75,15 @@ "display_name": "runtime_call", "silent": false, "value": { - "ByIndex": 6 + "ByIndex": 3 }, "doc": "" }, { - "display_name": "generation", + "display_name": "uniqueness", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 167 }, "doc": "" }, @@ -95,51 +91,7 @@ "display_name": "details", "silent": false, "value": { - "ByIndex": 111 - }, - "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "Ed25519Signature", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "msg_sig", - "silent": false, - "value": { - "Immediate": { - "ByteArray": { - "len": 64, - "display": "Hex" - } - } - }, - "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "Ed25519PublicKey", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "pub_key", - "silent": false, - "value": { - "Immediate": { - "ByteArray": { - "len": 32, - "display": "Hex" - } - } + "ByIndex": 170 }, "doc": "" } @@ -155,7 +107,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 7 + "ByIndex": 4 } }, { @@ -163,7 +115,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 25 + "ByIndex": 27 } }, { @@ -171,7 +123,7 @@ "discriminant": 2, "template": null, "value": { - "ByIndex": 32 + "ByIndex": 34 } }, { @@ -179,7 +131,7 @@ "discriminant": 3, "template": null, "value": { - "ByIndex": 35 + "ByIndex": 37 } }, { @@ -187,7 +139,7 @@ "discriminant": 4, "template": null, "value": { - "ByIndex": 40 + "ByIndex": 42 } }, { @@ -195,7 +147,7 @@ "discriminant": 5, "template": null, "value": { - "ByIndex": 44 + "ByIndex": 46 } }, { @@ -203,7 +155,7 @@ "discriminant": 6, "template": null, "value": { - "ByIndex": 49 + "ByIndex": 54 } }, { @@ -211,7 +163,7 @@ "discriminant": 7, "template": null, "value": { - "ByIndex": 51 + "ByIndex": 56 } }, { @@ -219,7 +171,7 @@ "discriminant": 8, "template": null, "value": { - "ByIndex": 52 + "ByIndex": 59 } }, { @@ -227,31 +179,71 @@ "discriminant": 9, "template": null, "value": { - "ByIndex": 53 + "ByIndex": 60 } }, { - "name": "Evm", + "name": "RevenueShare", "discriminant": 10, "template": null, "value": { - "ByIndex": 82 + "ByIndex": 89 } }, { - "name": "AccessPattern", + "name": "Mailbox", "discriminant": 11, "template": null, "value": { - "ByIndex": 85 + "ByIndex": 94 } }, { - "name": "SyntheticLoad", + "name": "InterchainGasPaymaster", "discriminant": 12, "template": null, "value": { - "ByIndex": 106 + "ByIndex": 103 + } + }, + { + "name": "MerkleTreeHook", + "discriminant": 13, + "template": null, + "value": { + "ByIndex": 113 + } + }, + { + "name": "Warp", + "discriminant": 14, + "template": null, + "value": { + "ByIndex": 114 + } + }, + { + "name": "Evm", + "discriminant": 15, + "template": null, + "value": { + "ByIndex": 134 + } + }, + { + "name": "AccessPattern", + "discriminant": 16, + "template": null, + "value": { + "ByIndex": 148 + } + }, + { + "name": "SyntheticLoad", + "discriminant": 17, + "template": null, + "value": { + "ByIndex": 162 } } ], @@ -265,7 +257,7 @@ "fields": [ { "value": { - "ByIndex": 8 + "ByIndex": 5 }, "silent": false, "doc": "" @@ -282,7 +274,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 9 + "ByIndex": 6 } }, { @@ -290,7 +282,7 @@ "discriminant": 1, "template": "Transfer to address {} {}.", "value": { - "ByIndex": 19 + "ByIndex": 18 } }, { @@ -298,7 +290,7 @@ "discriminant": 2, "template": null, "value": { - "ByIndex": 22 + "ByIndex": 21 } }, { @@ -306,16 +298,32 @@ "discriminant": 3, "template": null, "value": { - "ByIndex": 23 + "ByIndex": 22 } }, { "name": "Freeze", "discriminant": 4, "template": null, + "value": { + "ByIndex": 23 + } + }, + { + "name": "UpdateAdmin", + "discriminant": 5, + "template": null, "value": { "ByIndex": 24 } + }, + { + "name": "TransferWithMemo", + "discriminant": 6, + "template": "Transfer to address {} {} with memo `{}`.", + "value": { + "ByIndex": 26 + } } ], "hide_tag": false @@ -339,7 +347,7 @@ "display_name": "token_decimals", "silent": false, "value": { - "ByIndex": 10 + "ByIndex": 7 }, "doc": "" }, @@ -347,7 +355,7 @@ "display_name": "initial_balance", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" }, @@ -355,7 +363,7 @@ "display_name": "mint_to_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -363,7 +371,7 @@ "display_name": "admins", "silent": false, "value": { - "ByIndex": 17 + "ByIndex": 16 }, "doc": "" }, @@ -371,7 +379,7 @@ "display_name": "supply_cap", "silent": false, "value": { - "ByIndex": 18 + "ByIndex": 17 }, "doc": "" } @@ -412,22 +420,30 @@ }, { "Enum": { - "type_name": "MultiAddress", + "type_name": "MultiAddressEvmSolana", "variants": [ { "name": "Standard", "discriminant": 0, "template": null, "value": { - "ByIndex": 13 + "ByIndex": 10 } }, { - "name": "Vm", + "name": "Evm", "discriminant": 1, "template": null, "value": { - "ByIndex": 15 + "ByIndex": 12 + } + }, + { + "name": "Solana", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 14 } } ], @@ -441,7 +457,7 @@ "fields": [ { "value": { - "ByIndex": 14 + "ByIndex": 11 }, "silent": false, "doc": "" @@ -480,7 +496,7 @@ "fields": [ { "value": { - "ByIndex": 16 + "ByIndex": 13 }, "silent": false, "doc": "" @@ -508,17 +524,52 @@ ] } }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 15 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Base58" + } + } + }, + "silent": false, + "doc": "" + } + ] + } + }, { "Vec": { "value": { - "ByIndex": 12 + "ByIndex": 9 } } }, { "Option": { "value": { - "ByIndex": 11 + "ByIndex": 8 } } }, @@ -532,7 +583,7 @@ "display_name": "to", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -540,7 +591,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" } @@ -577,7 +628,7 @@ "display_name": "token_id", "silent": false, "value": { - "ByIndex": 21 + "ByIndex": 20 }, "doc": "" } @@ -618,7 +669,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" } @@ -635,7 +686,7 @@ "display_name": "coins", "silent": false, "value": { - "ByIndex": 20 + "ByIndex": 19 }, "doc": "" }, @@ -643,7 +694,7 @@ "display_name": "mint_to_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -660,7 +711,7 @@ "display_name": "token_id", "silent": false, "value": { - "ByIndex": 21 + "ByIndex": 20 }, "doc": "" } @@ -668,20 +719,85 @@ } }, { - "Tuple": { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_UpdateAdmin", "template": null, "peekable": false, "fields": [ { + "display_name": "new_admin", + "silent": false, "value": { - "ByIndex": 26 + "ByIndex": 25 }, - "silent": false, "doc": "" - } - ] - } - }, + }, + { + "display_name": "token_id", + "silent": false, + "value": { + "ByIndex": 20 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 9 + } + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_TransferWithMemo", + "template": "Transfer to address {} {} with memo `{}`.", + "peekable": false, + "fields": [ + { + "display_name": "to", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "coins", + "silent": false, + "value": { + "ByIndex": 19 + }, + "doc": "" + }, + { + "display_name": "memo", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 28 + }, + "silent": false, + "doc": "" + } + ] + } + }, { "Enum": { "type_name": "CallMessage", @@ -691,7 +807,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 27 + "ByIndex": 29 } }, { @@ -699,7 +815,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 29 + "ByIndex": 31 } }, { @@ -707,7 +823,7 @@ "discriminant": 2, "template": null, "value": { - "ByIndex": 30 + "ByIndex": 32 } }, { @@ -715,7 +831,7 @@ "discriminant": 3, "template": null, "value": { - "ByIndex": 31 + "ByIndex": 33 } } ], @@ -732,7 +848,7 @@ "display_name": "da_address", "silent": false, "value": { - "ByIndex": 28 + "ByIndex": 30 }, "doc": "" }, @@ -740,7 +856,7 @@ "display_name": "amount", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" } @@ -777,7 +893,7 @@ "display_name": "da_address", "silent": false, "value": { - "ByIndex": 28 + "ByIndex": 30 }, "doc": "" }, @@ -785,7 +901,7 @@ "display_name": "amount", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 8 }, "doc": "" } @@ -802,7 +918,7 @@ "display_name": "da_address", "silent": false, "value": { - "ByIndex": 28 + "ByIndex": 30 }, "doc": "" } @@ -819,7 +935,7 @@ "display_name": "da_address", "silent": false, "value": { - "ByIndex": 28 + "ByIndex": 30 }, "doc": "" } @@ -833,7 +949,7 @@ "fields": [ { "value": { - "ByIndex": 33 + "ByIndex": 35 }, "silent": false, "doc": "" @@ -850,7 +966,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 34 + "ByIndex": 36 } } ], @@ -867,7 +983,7 @@ "display_name": "new_reward_address", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -881,7 +997,7 @@ "fields": [ { "value": { - "ByIndex": 36 + "ByIndex": 38 }, "silent": false, "doc": "" @@ -898,7 +1014,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 37 + "ByIndex": 39 } }, { @@ -918,7 +1034,7 @@ "discriminant": 3, "template": null, "value": { - "ByIndex": 38 + "ByIndex": 40 } }, { @@ -932,7 +1048,7 @@ "discriminant": 5, "template": null, "value": { - "ByIndex": 39 + "ByIndex": 41 } } ], @@ -946,7 +1062,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -961,7 +1077,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -976,7 +1092,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -991,7 +1107,7 @@ "fields": [ { "value": { - "ByIndex": 41 + "ByIndex": 43 }, "silent": false, "doc": "" @@ -1008,7 +1124,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 42 + "ByIndex": 44 } }, { @@ -1016,7 +1132,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 43 + "ByIndex": 45 } }, { @@ -1036,7 +1152,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1051,7 +1167,7 @@ "fields": [ { "value": { - "ByIndex": 11 + "ByIndex": 8 }, "silent": false, "doc": "" @@ -1066,7 +1182,7 @@ "fields": [ { "value": { - "ByIndex": 45 + "ByIndex": 47 }, "silent": false, "doc": "" @@ -1083,7 +1199,31 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 46 + "ByIndex": 48 + } + }, + { + "name": "AddCredentialToAddress", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 51 + } + }, + { + "name": "RemoveCredentialFromAddress", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 52 + } + }, + { + "name": "RotateCredentialOnAddress", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 53 } } ], @@ -1097,7 +1237,7 @@ "fields": [ { "value": { - "ByIndex": 47 + "ByIndex": 49 }, "silent": false, "doc": "" @@ -1112,7 +1252,7 @@ "fields": [ { "value": { - "ByIndex": 48 + "ByIndex": 50 }, "silent": false, "doc": "" @@ -1141,37 +1281,83 @@ } }, { - "Tuple": { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_AddCredentialToAddress", "template": null, "peekable": false, "fields": [ { + "display_name": "address", + "silent": false, "value": { - "ByIndex": 50 + "ByIndex": 9 }, + "doc": "" + }, + { + "display_name": "credential", "silent": false, + "value": { + "ByIndex": 49 + }, "doc": "" } ] } }, { - "Enum": { - "type_name": "NotInstantiable", - "variants": [], - "hide_tag": false + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RemoveCredentialFromAddress", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "credential", + "silent": false, + "value": { + "ByIndex": 49 + }, + "doc": "" + } + ] } }, { - "Tuple": { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RotateCredentialOnAddress", "template": null, "peekable": false, "fields": [ { + "display_name": "address", + "silent": false, "value": { - "ByIndex": 50 + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "old_credential", + "silent": false, + "value": { + "ByIndex": 49 }, + "doc": "" + }, + { + "display_name": "new_credential", "silent": false, + "value": { + "ByIndex": 49 + }, "doc": "" } ] @@ -1184,7 +1370,7 @@ "fields": [ { "value": { - "ByIndex": 50 + "ByIndex": 55 }, "silent": false, "doc": "" @@ -1192,6 +1378,13 @@ ] } }, + { + "Enum": { + "type_name": "NotInstantiable", + "variants": [], + "hide_tag": false + } + }, { "Tuple": { "template": null, @@ -1199,7 +1392,7 @@ "fields": [ { "value": { - "ByIndex": 54 + "ByIndex": 57 }, "silent": false, "doc": "" @@ -1212,27 +1405,17 @@ "type_name": "CallMessage", "variants": [ { - "name": "RegisterPaymaster", + "name": "TerminateSetupMode", "discriminant": 0, "template": null, - "value": { - "ByIndex": 55 - } + "value": null }, { - "name": "SetPayerForSequencer", + "name": "SetOracleTime", "discriminant": 1, "template": null, "value": { - "ByIndex": 71 - } - }, - { - "name": "UpdatePolicy", - "discriminant": 2, - "template": null, - "value": { - "ByIndex": 72 + "ByIndex": 58 } } ], @@ -1241,15 +1424,20 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", + "type_name": "__SovVirtualWallet_CallMessage_SetOracleTime", "template": null, "peekable": false, "fields": [ { - "display_name": "policy", + "display_name": "milliseconds_since_epoch", "silent": false, "value": { - "ByIndex": 56 + "Immediate": { + "Integer": [ + "i64", + "Decimal" + ] + } }, "doc": "" } @@ -1257,32 +1445,111 @@ } }, { - "Struct": { - "type_name": "PaymasterPolicyInitializer", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "default_payee_policy", - "silent": false, "value": { - "ByIndex": 57 + "ByIndex": 55 }, + "silent": false, "doc": "" - }, + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ { - "display_name": "payees", - "silent": false, "value": { - "ByIndex": 66 + "ByIndex": 61 }, - "doc": "" - }, - { - "display_name": "authorized_updaters", "silent": false, - "value": { - "ByIndex": 17 + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "RegisterPaymaster", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 62 + } + }, + { + "name": "SetPayerForSequencer", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 78 + } + }, + { + "name": "UpdatePolicy", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 79 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "policy", + "silent": false, + "value": { + "ByIndex": 63 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "PaymasterPolicyInitializer", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "default_payee_policy", + "silent": false, + "value": { + "ByIndex": 64 + }, + "doc": "" + }, + { + "display_name": "payees", + "silent": false, + "value": { + "ByIndex": 73 + }, + "doc": "" + }, + { + "display_name": "authorized_updaters", + "silent": false, + "value": { + "ByIndex": 16 }, "doc": "" }, @@ -1290,7 +1557,7 @@ "display_name": "authorized_sequencers", "silent": false, "value": { - "ByIndex": 68 + "ByIndex": 75 }, "doc": "" } @@ -1306,7 +1573,7 @@ "discriminant": 0, "template": null, "value": { - "ByIndex": 58 + "ByIndex": 65 } }, { @@ -1329,7 +1596,7 @@ "display_name": "max_fee", "silent": false, "value": { - "ByIndex": 18 + "ByIndex": 17 }, "doc": "" }, @@ -1337,7 +1604,7 @@ "display_name": "gas_limit", "silent": false, "value": { - "ByIndex": 59 + "ByIndex": 66 }, "doc": "" }, @@ -1345,7 +1612,7 @@ "display_name": "max_gas_price", "silent": false, "value": { - "ByIndex": 62 + "ByIndex": 69 }, "doc": "" }, @@ -1353,7 +1620,7 @@ "display_name": "transaction_limit", "silent": false, "value": { - "ByIndex": 65 + "ByIndex": 72 }, "doc": "" } @@ -1363,7 +1630,7 @@ { "Option": { "value": { - "ByIndex": 60 + "ByIndex": 67 } } }, @@ -1374,7 +1641,7 @@ "fields": [ { "value": { - "ByIndex": 61 + "ByIndex": 68 }, "silent": false, "doc": "" @@ -1398,7 +1665,7 @@ { "Option": { "value": { - "ByIndex": 63 + "ByIndex": 70 } } }, @@ -1412,7 +1679,7 @@ "display_name": "value", "silent": false, "value": { - "ByIndex": 64 + "ByIndex": 71 }, "doc": "" } @@ -1423,7 +1690,7 @@ "Array": { "len": 2, "value": { - "ByIndex": 11 + "ByIndex": 8 } } }, @@ -1442,7 +1709,7 @@ { "Vec": { "value": { - "ByIndex": 67 + "ByIndex": 74 } } }, @@ -1453,14 +1720,14 @@ "fields": [ { "value": { - "ByIndex": 12 + "ByIndex": 9 }, "silent": false, "doc": "" }, { "value": { - "ByIndex": 57 + "ByIndex": 64 }, "silent": false, "doc": "" @@ -1483,7 +1750,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 69 + "ByIndex": 76 } } ], @@ -1497,7 +1764,7 @@ "fields": [ { "value": { - "ByIndex": 70 + "ByIndex": 77 }, "silent": false, "doc": "" @@ -1508,7 +1775,7 @@ { "Vec": { "value": { - "ByIndex": 28 + "ByIndex": 30 } } }, @@ -1522,7 +1789,7 @@ "display_name": "payer", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" } @@ -1539,7 +1806,7 @@ "display_name": "payer", "silent": false, "value": { - "ByIndex": 12 + "ByIndex": 9 }, "doc": "" }, @@ -1547,7 +1814,7 @@ "display_name": "update", "silent": false, "value": { - "ByIndex": 73 + "ByIndex": 80 }, "doc": "" } @@ -1564,7 +1831,7 @@ "display_name": "sequencer_update", "silent": false, "value": { - "ByIndex": 74 + "ByIndex": 81 }, "doc": "" }, @@ -1572,7 +1839,7 @@ "display_name": "updaters_to_add", "silent": false, "value": { - "ByIndex": 79 + "ByIndex": 86 }, "doc": "" }, @@ -1580,7 +1847,7 @@ "display_name": "updaters_to_remove", "silent": false, "value": { - "ByIndex": 79 + "ByIndex": 86 }, "doc": "" }, @@ -1588,7 +1855,7 @@ "display_name": "payee_policies_to_set", "silent": false, "value": { - "ByIndex": 80 + "ByIndex": 87 }, "doc": "" }, @@ -1596,7 +1863,7 @@ "display_name": "payee_policies_to_delete", "silent": false, "value": { - "ByIndex": 79 + "ByIndex": 86 }, "doc": "" }, @@ -1604,7 +1871,7 @@ "display_name": "default_policy", "silent": false, "value": { - "ByIndex": 81 + "ByIndex": 88 }, "doc": "" } @@ -1614,7 +1881,7 @@ { "Option": { "value": { - "ByIndex": 75 + "ByIndex": 82 } } }, @@ -1633,7 +1900,7 @@ "discriminant": 1, "template": null, "value": { - "ByIndex": 76 + "ByIndex": 83 } } ], @@ -1647,7 +1914,7 @@ "fields": [ { "value": { - "ByIndex": 77 + "ByIndex": 84 }, "silent": false, "doc": "" @@ -1665,7 +1932,7 @@ "display_name": "to_add", "silent": false, "value": { - "ByIndex": 78 + "ByIndex": 85 }, "doc": "" }, @@ -1673,7 +1940,7 @@ "display_name": "to_remove", "silent": false, "value": { - "ByIndex": 78 + "ByIndex": 85 }, "doc": "" } @@ -1683,28 +1950,28 @@ { "Option": { "value": { - "ByIndex": 70 + "ByIndex": 77 } } }, { "Option": { "value": { - "ByIndex": 17 + "ByIndex": 16 } } }, { "Option": { "value": { - "ByIndex": 66 + "ByIndex": 73 } } }, { "Option": { "value": { - "ByIndex": 57 + "ByIndex": 64 } } }, @@ -1715,7 +1982,7 @@ "fields": [ { "value": { - "ByIndex": 83 + "ByIndex": 90 }, "silent": false, "doc": "" @@ -1724,16 +1991,65 @@ } }, { - "Struct": { + "Enum": { "type_name": "CallMessage", + "variants": [ + { + "name": "ActivateRevenueShare", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "DeactivateRevenueShare", + "discriminant": 1, + "template": null, + "value": null + }, + { + "name": "LowerRevenuePercentage", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 91 + } + }, + { + "name": "UpdateSovereignAdmin", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 92 + } + }, + { + "name": "WithdrawRewards", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 93 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_LowerRevenuePercentage", "template": null, "peekable": false, "fields": [ { - "display_name": "rlp", + "display_name": "percentage_in_basis_points", "silent": false, "value": { - "ByIndex": 84 + "Immediate": { + "Integer": [ + "u16", + "Decimal" + ] + } }, "doc": "" } @@ -1742,19 +2058,32 @@ }, { "Struct": { - "type_name": "RlpEvmTransaction", + "type_name": "__SovVirtualWallet_CallMessage_UpdateSovereignAdmin", "template": null, "peekable": false, "fields": [ { - "display_name": "rlp", + "display_name": "new_admin", "silent": false, "value": { - "Immediate": { - "ByteVec": { - "display": "Hex" - } - } + "ByIndex": 9 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_WithdrawRewards", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "token_id", + "silent": false, + "value": { + "ByIndex": 20 }, "doc": "" } @@ -1768,7 +2097,7 @@ "fields": [ { "value": { - "ByIndex": 86 + "ByIndex": 95 }, "silent": false, "doc": "" @@ -1778,162 +2107,92 @@ }, { "Enum": { - "type_name": "AccessPatternMessages", + "type_name": "CallMessage", "variants": [ { - "name": "WriteCells", + "name": "Dispatch", "discriminant": 0, "template": null, "value": { - "ByIndex": 87 + "ByIndex": 96 } }, { - "name": "WriteCustom", + "name": "Process", "discriminant": 1, "template": null, "value": { - "ByIndex": 88 + "ByIndex": 99 } }, { - "name": "ReadCells", + "name": "Announce", "discriminant": 2, "template": null, "value": { - "ByIndex": 90 + "ByIndex": 100 } - }, + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_Dispatch", + "template": null, + "peekable": false, + "fields": [ { - "name": "HashBytes", - "discriminant": 3, - "template": null, + "display_name": "domain", + "silent": false, "value": { - "ByIndex": 91 - } + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" }, { - "name": "HashCustom", - "discriminant": 4, - "template": null, + "display_name": "recipient", + "silent": false, "value": { - "ByIndex": 92 - } + "ByIndex": 50 + }, + "doc": "" }, { - "name": "StoreSignature", - "discriminant": 5, - "template": null, - "value": { - "ByIndex": 93 - } - }, - { - "name": "VerifySignature", - "discriminant": 6, - "template": null, - "value": null - }, - { - "name": "VerifyCustomSignature", - "discriminant": 7, - "template": null, - "value": { - "ByIndex": 94 - } - }, - { - "name": "StoreSerializedString", - "discriminant": 8, - "template": null, - "value": { - "ByIndex": 95 - } - }, - { - "name": "DeserializeBytesAsString", - "discriminant": 9, - "template": null, - "value": null - }, - { - "name": "DeserializeCustomString", - "discriminant": 10, - "template": null, - "value": { - "ByIndex": 96 - } - }, - { - "name": "DeleteCells", - "discriminant": 11, - "template": null, + "display_name": "body", + "silent": false, "value": { "ByIndex": 97 - } - }, - { - "name": "SetHook", - "discriminant": 12, - "template": null, - "value": { - "ByIndex": 98 - } + }, + "doc": "" }, { - "name": "UpdateAdmin", - "discriminant": 13, - "template": null, - "value": { - "ByIndex": 105 - } - } - ], - "hide_tag": false - } - }, - { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCells", - "template": null, - "peekable": false, - "fields": [ - { - "display_name": "begin", + "display_name": "metadata", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 98 }, "doc": "" }, { - "display_name": "num_cells", + "display_name": "relayer", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 25 }, "doc": "" }, { - "display_name": "data_size", + "display_name": "gas_payment_limit", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] - } + "ByIndex": 8 }, "doc": "" } @@ -1941,71 +2200,50 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCustom", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "begin", - "silent": false, "value": { "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] + "ByteVec": { + "display": "Hex" + } } }, - "doc": "" - }, - { - "display_name": "content", "silent": false, - "value": { - "ByIndex": 89 - }, "doc": "" } ] } }, { - "Vec": { + "Option": { "value": { - "Immediate": "String" + "ByIndex": 97 } } }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_ReadCells", + "type_name": "__SovVirtualWallet_CallMessage_Process", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "metadata", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 97 }, "doc": "" }, { - "display_name": "num_cells", + "display_name": "message", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 97 }, "doc": "" } @@ -2014,141 +2252,196 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_HashBytes", + "type_name": "__SovVirtualWallet_CallMessage_Announce", "template": null, "peekable": false, "fields": [ { - "display_name": "filler", + "display_name": "validator_address", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u8", - "Decimal" - ] - } + "ByIndex": 101 }, "doc": "" }, { - "display_name": "size", + "display_name": "storage_location", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + }, + { + "display_name": "signature", "silent": false, + "value": { + "ByIndex": 102 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { "value": { "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] + "ByteArray": { + "len": 20, + "display": "Hex" + } } }, + "silent": false, "doc": "" } ] } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_HashCustom", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "input", - "silent": false, "value": { "Immediate": { - "ByteVec": { + "ByteArray": { + "len": 65, "display": "Hex" } } }, + "silent": false, "doc": "" } ] } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSignature", + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "sign", - "silent": false, "value": { - "ByIndex": 4 + "ByIndex": 104 }, + "silent": false, "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "SetRelayerConfig", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 105 + } }, { - "display_name": "pub_key", - "silent": false, + "name": "UpdateOracleData", + "discriminant": 1, + "template": null, "value": { - "ByIndex": 5 - }, - "doc": "" + "ByIndex": 111 + } }, { - "display_name": "message", - "silent": false, + "name": "ClaimRewards", + "discriminant": 2, + "template": null, "value": { - "Immediate": "String" - }, - "doc": "" + "ByIndex": 112 + } } - ] + ], + "hide_tag": false } }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_VerifyCustomSignature", + "type_name": "__SovVirtualWallet_CallMessage_SetRelayerConfig", "template": null, "peekable": false, "fields": [ { - "display_name": "sign", + "display_name": "domain_oracle_data", "silent": false, "value": { - "ByIndex": 4 + "ByIndex": 106 }, "doc": "" }, { - "display_name": "pub_key", + "display_name": "domain_default_gas", "silent": false, "value": { - "ByIndex": 5 + "ByIndex": 109 }, "doc": "" }, { - "display_name": "message", + "display_name": "default_gas", "silent": false, "value": { - "Immediate": "String" + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "beneficiary", + "silent": false, + "value": { + "ByIndex": 25 }, "doc": "" } ] } }, + { + "Vec": { + "value": { + "ByIndex": 107 + } + } + }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSerializedString", + "type_name": "DomainOracleData", "template": null, "peekable": false, "fields": [ { - "display_name": "input", + "display_name": "domain", "silent": false, "value": { "Immediate": { - "ByteVec": { - "display": "Hex" - } - } + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "data_value", + "silent": false, + "value": { + "ByIndex": 108 }, "doc": "" } @@ -2157,18 +2450,27 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_DeserializeCustomString", + "type_name": "ExchangeRateAndGasPrice", "template": null, "peekable": false, "fields": [ { - "display_name": "input", + "display_name": "gas_price", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "token_exchange_rate", "silent": false, "value": { "Immediate": { - "ByteVec": { - "display": "Hex" - } + "Integer": [ + "u128", + "Decimal" + ] } }, "doc": "" @@ -2176,19 +2478,26 @@ ] } }, + { + "Vec": { + "value": { + "ByIndex": 110 + } + } + }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_DeleteCells", + "type_name": "DomainDefaultGas", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2196,15 +2505,10 @@ "doc": "" }, { - "display_name": "num_cells", + "display_name": "default_gas", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 8 }, "doc": "" } @@ -2213,23 +2517,28 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_SetHook", + "type_name": "__SovVirtualWallet_CallMessage_UpdateOracleData", "template": null, "peekable": false, "fields": [ { - "display_name": "pre", + "display_name": "domain", "silent": false, "value": { - "ByIndex": 99 + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } }, "doc": "" }, { - "display_name": "post", + "display_name": "oracle_data", "silent": false, "value": { - "ByIndex": 99 + "ByIndex": 108 }, "doc": "" } @@ -2237,45 +2546,98 @@ } }, { - "Option": { - "value": { - "ByIndex": 100 - } + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_ClaimRewards", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "relayer_address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + } + ] } }, { - "Vec": { - "value": { - "ByIndex": 101 - } + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Skip": { + "len": 0 + } + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 115 + }, + "silent": false, + "doc": "" + } + ] } }, { "Enum": { - "type_name": "HooksConfig", + "type_name": "CallMessage", "variants": [ { - "name": "Read", + "name": "Register", "discriminant": 0, "template": null, "value": { - "ByIndex": 102 + "ByIndex": 116 } }, { - "name": "Write", + "name": "Update", "discriminant": 1, "template": null, "value": { - "ByIndex": 103 + "ByIndex": 128 } }, { - "name": "Delete", + "name": "EnrollRemoteRouter", "discriminant": 2, "template": null, "value": { - "ByIndex": 104 + "ByIndex": 131 + } + }, + { + "name": "UnEnrollRemoteRouter", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 132 + } + }, + { + "name": "TransferRemote", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 133 } } ], @@ -2284,116 +2646,71 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Read", + "type_name": "__SovVirtualWallet_CallMessage_Register", "template": null, "peekable": false, "fields": [ { - "display_name": "begin", + "display_name": "admin", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 117 }, "doc": "" }, { - "display_name": "size", + "display_name": "token_source", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 119 }, "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Write", - "template": null, - "peekable": false, - "fields": [ + }, { - "display_name": "begin", + "display_name": "ism", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 122 }, "doc": "" }, { - "display_name": "size", + "display_name": "remote_routers", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 126 }, "doc": "" }, { - "display_name": "data_size", + "display_name": "inbound_transferrable_tokens_limit", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u32", - "Decimal" - ] - } + "ByIndex": 8 }, "doc": "" - } - ] - } - }, - { - "Struct": { - "type_name": "__SovVirtualWallet_HooksConfig_Delete", - "template": null, - "peekable": false, - "fields": [ + }, { - "display_name": "begin", + "display_name": "inbound_limit_replenishment_per_slot", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 8 }, "doc": "" }, { - "display_name": "size", + "display_name": "outbound_transferrable_tokens_limit", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "outbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 8 }, "doc": "" } @@ -2401,20 +2718,25 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", - "template": null, - "peekable": false, - "fields": [ + "Enum": { + "type_name": "Admin", + "variants": [ { - "display_name": "new_admin", - "silent": false, + "name": "None", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "InsecureOwner", + "discriminant": 1, + "template": null, "value": { - "ByIndex": 12 - }, - "doc": "" + "ByIndex": 118 + } } - ] + ], + "hide_tag": false } }, { @@ -2424,7 +2746,7 @@ "fields": [ { "value": { - "ByIndex": 107 + "ByIndex": 9 }, "silent": false, "doc": "" @@ -2434,31 +2756,29 @@ }, { "Enum": { - "type_name": "CallMessage", + "type_name": "TokenKind", "variants": [ { - "name": "ReadAndSetManyIndividualValues", + "name": "Synthetic", "discriminant": 0, "template": null, "value": { - "ByIndex": 108 + "ByIndex": 120 } }, { - "name": "ReadAndSetHeavyState", + "name": "Collateral", "discriminant": 1, "template": null, "value": { - "ByIndex": 109 + "ByIndex": 121 } }, { - "name": "RunCPUHeavyOperation", + "name": "Native", "discriminant": 2, "template": null, - "value": { - "ByIndex": 110 - } + "value": null } ], "hide_tag": false @@ -2466,78 +2786,127 @@ }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "type_name": "__SovVirtualWallet_TokenKind_Synthetic", "template": null, "peekable": false, "fields": [ { - "display_name": "number_of_operations", + "display_name": "remote_token_id", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 50 }, "doc": "" }, { - "display_name": "salt", + "display_name": "remote_decimals", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u8", "Decimal" ] } }, "doc": "" + }, + { + "display_name": "local_decimals", + "silent": false, + "value": { + "ByIndex": 7 + }, + "doc": "" } ] } }, { "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "type_name": "__SovVirtualWallet_TokenKind_Collateral", "template": null, "peekable": false, "fields": [ { - "display_name": "number_of_new_values", + "display_name": "token", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 20 }, "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "Ism", + "variants": [ + { + "name": "AlwaysTrust", + "discriminant": 0, + "template": null, + "value": null }, { - "display_name": "max_heavy_state_size", + "name": "TrustedRelayer", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 123 + } + }, + { + "name": "MessageIdMultisig", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 124 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_Ism_TrustedRelayer", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "relayer", "silent": false, "value": { - "Immediate": { - "Integer": [ - "u64", - "Decimal" - ] - } + "ByIndex": 50 + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_Ism_MessageIdMultisig", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "validators", + "silent": false, + "value": { + "ByIndex": 125 }, "doc": "" }, { - "display_name": "salt", + "display_name": "threshold", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2548,22 +2917,41 @@ } }, { - "Struct": { - "type_name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "Vec": { + "value": { + "ByIndex": 101 + } + } + }, + { + "Vec": { + "value": { + "ByIndex": 127 + } + } + }, + { + "Tuple": { "template": null, "peekable": false, "fields": [ { - "display_name": "iterations", - "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } }, + "silent": false, + "doc": "" + }, + { + "value": { + "ByIndex": 50 + }, + "silent": false, "doc": "" } ] @@ -2571,65 +2959,146 @@ }, { "Struct": { - "type_name": "TxDetails", + "type_name": "__SovVirtualWallet_CallMessage_Update", "template": null, "peekable": false, "fields": [ { - "display_name": "max_priority_fee_bips", + "display_name": "warp_route", "silent": false, "value": { - "ByIndex": 112 + "ByIndex": 50 }, "doc": "" }, { - "display_name": "max_fee", + "display_name": "admin", "silent": false, "value": { - "ByIndex": 11 + "ByIndex": 129 }, "doc": "" }, { - "display_name": "gas_limit", + "display_name": "ism", "silent": false, "value": { - "ByIndex": 59 + "ByIndex": 130 }, "doc": "" }, { - "display_name": "chain_id", + "display_name": "inbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "inbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "outbound_transferrable_tokens_limit", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + }, + { + "display_name": "outbound_limit_replenishment_per_slot", + "silent": false, + "value": { + "ByIndex": 17 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 117 + } + } + }, + { + "Option": { + "value": { + "ByIndex": 122 + } + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_EnrollRemoteRouter", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "warp_route", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "remote_domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } }, "doc": "" + }, + { + "display_name": "remote_router_address", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" } ] } }, { - "Tuple": { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_UnEnrollRemoteRouter", "template": null, "peekable": false, "fields": [ { + "display_name": "warp_route", + "silent": false, + "value": { + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "remote_domain", + "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } }, - "silent": false, "doc": "" } ] @@ -2637,25 +3106,25 @@ }, { "Struct": { - "type_name": "UnsignedTransaction", + "type_name": "__SovVirtualWallet_CallMessage_TransferRemote", "template": null, "peekable": false, "fields": [ { - "display_name": "runtime_call", + "display_name": "warp_route", "silent": false, "value": { - "ByIndex": 6 + "ByIndex": 50 }, "doc": "" }, { - "display_name": "generation", + "display_name": "destination_domain", "silent": false, "value": { "Immediate": { "Integer": [ - "u64", + "u32", "Decimal" ] } @@ -2663,95 +3132,1761 @@ "doc": "" }, { - "display_name": "details", + "display_name": "recipient", "silent": false, "value": { - "ByIndex": 111 + "ByIndex": 50 + }, + "doc": "" + }, + { + "display_name": "amount", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "relayer", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + }, + { + "display_name": "gas_payment_limit", + "silent": false, + "value": { + "ByIndex": 8 }, "doc": "" } ] } - } - ], - "root_type_indices": [ - 0, - 113, - 6, - 14 - ], - "chain_data": { - "chain_id": 4321, - "chain_name": "TestChain" - }, - "templates": [ - {}, - {}, + }, { - "transfer": { - "preencoded_bytes": [ - 0, - 1 - ], - "inputs": [ - [ - "to", - { - "type_link": { - "ByIndex": 12 - }, - "offset": 2 + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 135 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "Call", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 136 } - ], - [ - "amount", - { - "type_link": { - "Immediate": { - "Integer": [ - "u128", - { - "FixedPoint": { - "FromSiblingField": { - "field_index": 1, - "byte_offset": 31 - } - } - } - ] - } - }, - "offset": 2 + }, + { + "name": "UpdateRuntimeConfig", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 138 } - ], - [ - "token_id", - { - "type_link": { - "ByIndex": 21 - }, - "offset": 2 + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 137 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "RlpEvmTransaction", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "rlp", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 139 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "EvmRuntimeConfigUpdate", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_hardfork", + "silent": false, + "value": { + "ByIndex": 140 + }, + "doc": "" + }, + { + "display_name": "new_contract_creation_policy", + "silent": false, + "value": { + "ByIndex": 142 + }, + "doc": "" + }, + { + "display_name": "chain_spec_update", + "silent": false, + "value": { + "ByIndex": 145 + }, + "doc": "" + }, + { + "display_name": "new_admin", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 141 + } + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + }, + { + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 143 + } + } + }, + { + "Enum": { + "type_name": "ContractCreationPolicyUpdate", + "variants": [ + { + "name": "Everyone", + "discriminant": 0, + "template": null, + "value": null + }, + { + "name": "Allowlist", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 144 } - ] + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_ContractCreationPolicyUpdate_Allowlist", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "add", + "silent": false, + "value": { + "ByIndex": 125 + }, + "doc": "" + }, + { + "display_name": "remove", + "silent": false, + "value": { + "ByIndex": 125 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "ByIndex": 146 + } + } + }, + { + "Struct": { + "type_name": "ChainSpecUpdate", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_limit_contract_code_size", + "silent": false, + "value": { + "ByIndex": 147 + }, + "doc": "" + }, + { + "display_name": "new_block_gas_limit", + "silent": false, + "value": { + "ByIndex": 72 + }, + "doc": "" + }, + { + "display_name": "new_tx_gas_limit", + "silent": false, + "value": { + "ByIndex": 72 + }, + "doc": "" + } + ] + } + }, + { + "Option": { + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + } + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 149 + }, + "silent": false, + "doc": "" + } ] } }, - {} - ], - "serde_metadata": [ { - "name": "Transaction", + "Enum": { + "type_name": "AccessPatternMessages", + "variants": [ + { + "name": "WriteCells", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 150 + } + }, + { + "name": "WriteCustom", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 151 + } + }, + { + "name": "ReadCells", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 153 + } + }, + { + "name": "HashBytes", + "discriminant": 3, + "template": null, + "value": { + "ByIndex": 154 + } + }, + { + "name": "HashCustom", + "discriminant": 4, + "template": null, + "value": { + "ByIndex": 155 + } + }, + { + "name": "StoreSignature", + "discriminant": 5, + "template": null, + "value": { + "ByIndex": 156 + } + }, + { + "name": "VerifySignature", + "discriminant": 6, + "template": null, + "value": null + }, + { + "name": "VerifyCustomSignature", + "discriminant": 7, + "template": null, + "value": { + "ByIndex": 157 + } + }, + { + "name": "StoreSerializedString", + "discriminant": 8, + "template": null, + "value": { + "ByIndex": 158 + } + }, + { + "name": "DeserializeBytesAsString", + "discriminant": 9, + "template": null, + "value": null + }, + { + "name": "DeserializeCustomString", + "discriminant": 10, + "template": null, + "value": { + "ByIndex": 159 + } + }, + { + "name": "DeleteCells", + "discriminant": 11, + "template": null, + "value": { + "ByIndex": 160 + } + }, + { + "name": "UpdateAdmin", + "discriminant": 12, + "template": null, + "value": { + "ByIndex": 161 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "data_size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_WriteCustom", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "content", + "silent": false, + "value": { + "ByIndex": 152 + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "Immediate": "String" + } + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_ReadCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_HashBytes", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "filler", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u32", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_HashCustom", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "sign", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "message", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_VerifyCustomSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "sign", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "message", + "silent": false, + "value": { + "Immediate": "String" + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_StoreSerializedString", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_DeserializeCustomString", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "input", + "silent": false, + "value": { + "Immediate": { + "ByteVec": { + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_DeleteCells", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "begin", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "num_cells", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "new_admin", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 163 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "CallMessage", + "variants": [ + { + "name": "ReadAndSetManyIndividualValues", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 164 + } + }, + { + "name": "ReadAndSetHeavyState", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 165 + } + }, + { + "name": "RunCPUHeavyOperation", + "discriminant": 2, + "template": null, + "value": { + "ByIndex": 166 + } + } + ], + "hide_tag": false + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "number_of_operations", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "salt", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "number_of_new_values", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "max_heavy_state_size", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "salt", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "iterations", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Enum": { + "type_name": "UniquenessData", + "variants": [ + { + "name": "Nonce", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 168 + } + }, + { + "name": "Generation", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 169 + } + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "TxDetails", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "max_priority_fee_bips", + "silent": false, + "value": { + "ByIndex": 171 + }, + "doc": "" + }, + { + "display_name": "max_fee", + "silent": false, + "value": { + "ByIndex": 8 + }, + "doc": "" + }, + { + "display_name": "gas_limit", + "silent": false, + "value": { + "ByIndex": 66 + }, + "doc": "" + }, + { + "display_name": "chain_id", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "Immediate": { + "Integer": [ + "u64", + "Decimal" + ] + } + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 173 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "Version1", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "signatures", + "silent": false, + "value": { + "ByIndex": 174 + }, + "doc": "" + }, + { + "display_name": "unused_pub_keys", + "silent": false, + "value": { + "ByIndex": 176 + }, + "doc": "" + }, + { + "display_name": "min_signers", + "silent": false, + "value": { + "Immediate": { + "Integer": [ + "u8", + "Decimal" + ] + } + }, + "doc": "" + }, + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + }, + { + "display_name": "target_address", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "ByIndex": 175 + } + } + }, + { + "Struct": { + "type_name": "PubKeyAndSignature", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "signature", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 64, + "display": "Hex" + } + } + }, + "doc": "" + }, + { + "display_name": "pub_key", + "silent": false, + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + }, + "doc": "" + } + ] + } + }, + { + "Vec": { + "value": { + "Immediate": { + "ByteArray": { + "len": 32, + "display": "Hex" + } + } + } + } + }, + { + "Enum": { + "type_name": "UnsignedTransaction", + "variants": [ + { + "name": "V0", + "discriminant": 0, + "template": null, + "value": { + "ByIndex": 178 + } + }, + { + "name": "V1", + "discriminant": 1, + "template": null, + "value": { + "ByIndex": 180 + } + } + ], + "hide_tag": false + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 179 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "UnsignedTransactionV0", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + } + ] + } + }, + { + "Tuple": { + "template": null, + "peekable": false, + "fields": [ + { + "value": { + "ByIndex": 181 + }, + "silent": false, + "doc": "" + } + ] + } + }, + { + "Struct": { + "type_name": "UnsignedTransactionV1", + "template": null, + "peekable": false, + "fields": [ + { + "display_name": "runtime_call", + "silent": false, + "value": { + "ByIndex": 3 + }, + "doc": "" + }, + { + "display_name": "uniqueness", + "silent": false, + "value": { + "ByIndex": 167 + }, + "doc": "" + }, + { + "display_name": "details", + "silent": false, + "value": { + "ByIndex": 170 + }, + "doc": "" + }, + { + "display_name": "credential_address", + "silent": false, + "value": { + "ByIndex": 9 + }, + "doc": "" + }, + { + "display_name": "target_address", + "silent": false, + "value": { + "ByIndex": 25 + }, + "doc": "" + } + ] + } + } + ], + "root_type_indices": [ + 0, + 177, + 3, + 9 + ], + "chain_data": { + "chain_id": 4321, + "chain_name": "TestChain" + }, + "templates": [ + {}, + {}, + { + "transfer": { + "preencoded_bytes": [ + 0, + 1 + ], + "inputs": [ + [ + "to", + { + "type_link": { + "ByIndex": 9 + }, + "offset": 2 + } + ], + [ + "amount", + { + "type_link": { + "Immediate": { + "Integer": [ + "u128", + { + "FixedPoint": { + "FromSiblingField": { + "field_index": 1, + "byte_offset": 31 + } + } + } + ] + } + }, + "offset": 2 + } + ], + [ + "token_id", + { + "type_link": { + "ByIndex": 20 + }, + "offset": 2 + } + ] + ] + } + }, + {} + ], + "serde_metadata": [ + { + "name": "Transaction", + "fields_or_variants": [ + { + "name": "V0" + }, + { + "name": "V1" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "Version0", + "fields_or_variants": [ + { + "name": "signature" + }, + { + "name": "pub_key" + }, + { + "name": "runtime_call" + }, + { + "name": "uniqueness" + }, + { + "name": "details" + } + ] + }, + { + "name": "RuntimeCall", + "fields_or_variants": [ + { + "name": "bank" + }, + { + "name": "sequencer_registry" + }, + { + "name": "operator_incentives" + }, + { + "name": "attester_incentives" + }, + { + "name": "prover_incentives" + }, + { + "name": "accounts" + }, + { + "name": "uniqueness" + }, + { + "name": "chain_state" + }, + { + "name": "blob_storage" + }, + { + "name": "paymaster" + }, + { + "name": "revenue_share" + }, + { + "name": "mailbox" + }, + { + "name": "interchain_gas_paymaster" + }, + { + "name": "merkle_tree_hook" + }, + { + "name": "warp" + }, + { + "name": "evm" + }, + { + "name": "access_pattern" + }, + { + "name": "synthetic_load" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "create_token" + }, + { + "name": "transfer" + }, + { + "name": "burn" + }, + { + "name": "mint" + }, + { + "name": "freeze" + }, + { + "name": "update_admin" + }, + { + "name": "transfer_with_memo" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_CreateToken", + "fields_or_variants": [ + { + "name": "token_name" + }, + { + "name": "token_decimals" + }, + { + "name": "initial_balance" + }, + { + "name": "mint_to_address" + }, + { + "name": "admins" + }, + { + "name": "supply_cap" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "MultiAddressEvmSolana", + "fields_or_variants": [ + { + "name": "Standard" + }, + { + "name": "Evm" + }, + { + "name": "Solana" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Transfer", + "fields_or_variants": [ + { + "name": "to" + }, + { + "name": "coins" + } + ] + }, + { + "name": "Coins", + "fields_or_variants": [ + { + "name": "amount" + }, + { + "name": "token_id" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Burn", + "fields_or_variants": [ + { + "name": "coins" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Mint", + "fields_or_variants": [ + { + "name": "coins" + }, + { + "name": "mint_to_address" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Freeze", + "fields_or_variants": [ + { + "name": "token_id" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateAdmin", + "fields_or_variants": [ + { + "name": "new_admin" + }, + { + "name": "token_id" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_TransferWithMemo", + "fields_or_variants": [ + { + "name": "to" + }, + { + "name": "coins" + }, + { + "name": "memo" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "register" + }, + { + "name": "deposit" + }, + { + "name": "initiate_withdrawal" + }, + { + "name": "withdraw" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_Register", + "fields_or_variants": [ + { + "name": "da_address" + }, + { + "name": "amount" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Deposit", + "fields_or_variants": [ + { + "name": "da_address" + }, + { + "name": "amount" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_InitiateWithdrawal", "fields_or_variants": [ { - "name": "versioned_tx" + "name": "da_address" } ] }, { - "name": "VersionedTx", + "name": "__SovVirtualWallet_CallMessage_Withdraw", "fields_or_variants": [ { - "name": "V0" + "name": "da_address" } ] }, @@ -2760,82 +4895,309 @@ "fields_or_variants": [] }, { - "name": "Version0", + "name": "CallMessage", "fields_or_variants": [ { - "name": "signature" + "name": "update_reward_address" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateRewardAddress", + "fields_or_variants": [ + { + "name": "new_reward_address" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "register_attester" }, { - "name": "pub_key" + "name": "begin_exit_attester" }, { - "name": "runtime_call" + "name": "exit_attester" }, { - "name": "generation" + "name": "register_challenger" }, { - "name": "details" + "name": "exit_challenger" + }, + { + "name": "deposit_attester" } ] }, { - "name": "Ed25519Signature", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", "fields_or_variants": [ { - "name": "msg_sig" + "name": "register" + }, + { + "name": "deposit" + }, + { + "name": "exit" } ] }, { - "name": "Ed25519PublicKey", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", "fields_or_variants": [ { - "name": "pub_key" + "name": "insert_credential_id" + }, + { + "name": "add_credential_to_address" + }, + { + "name": "remove_credential_from_address" + }, + { + "name": "rotate_credential_on_address" } ] }, { - "name": "RuntimeCall", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_AddCredentialToAddress", "fields_or_variants": [ { - "name": "bank" + "name": "address" }, { - "name": "sequencer_registry" + "name": "credential" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RemoveCredentialFromAddress", + "fields_or_variants": [ + { + "name": "address" }, { - "name": "operator_incentives" + "name": "credential" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RotateCredentialOnAddress", + "fields_or_variants": [ + { + "name": "address" }, { - "name": "attester_incentives" + "name": "old_credential" }, { - "name": "prover_incentives" + "name": "new_credential" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "NotInstantiable", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "TerminateSetupMode" }, { - "name": "accounts" + "name": "SetOracleTime" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_SetOracleTime", + "fields_or_variants": [ + { + "name": "milliseconds_since_epoch" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "CallMessage", + "fields_or_variants": [ + { + "name": "register_paymaster" }, { - "name": "uniqueness" + "name": "set_payer_for_sequencer" }, { - "name": "chain_state" + "name": "update_policy" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", + "fields_or_variants": [ + { + "name": "policy" + } + ] + }, + { + "name": "PaymasterPolicyInitializer", + "fields_or_variants": [ + { + "name": "default_payee_policy" }, { - "name": "blob_storage" + "name": "payees" }, { - "name": "paymaster" + "name": "authorized_updaters" }, { - "name": "evm" + "name": "authorized_sequencers" + } + ] + }, + { + "name": "PayeePolicy", + "fields_or_variants": [ + { + "name": "allow" + }, + { + "name": "deny" + } + ] + }, + { + "name": "__SovVirtualWallet_PayeePolicy_Allow", + "fields_or_variants": [ + { + "name": "max_fee" + }, + { + "name": "gas_limit" + }, + { + "name": "max_gas_price" }, { - "name": "access_pattern" + "name": "transaction_limit" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "GasPrice", + "fields_or_variants": [ + { + "name": "value" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "AuthorizedSequencers", + "fields_or_variants": [ + { + "name": "all" }, { - "name": "synthetic_load" + "name": "some" } ] }, @@ -2844,45 +5206,48 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_SetPayerForSequencer", "fields_or_variants": [ { - "name": "create_token" - }, - { - "name": "transfer" - }, - { - "name": "burn" - }, + "name": "payer" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdatePolicy", + "fields_or_variants": [ { - "name": "mint" + "name": "payer" }, { - "name": "freeze" + "name": "update" } ] }, { - "name": "__SovVirtualWallet_CallMessage_CreateToken", + "name": "PolicyUpdate", "fields_or_variants": [ { - "name": "token_name" + "name": "sequencer_update" }, { - "name": "token_decimals" + "name": "updaters_to_add" }, { - "name": "initial_balance" + "name": "updaters_to_remove" }, { - "name": "mint_to_address" + "name": "payee_policies_to_set" }, { - "name": "admins" + "name": "payee_policies_to_delete" }, { - "name": "supply_cap" + "name": "default_policy" } ] }, @@ -2891,17 +5256,13 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "MultiAddress", + "name": "SequencerSetUpdate", "fields_or_variants": [ { - "name": "Standard" + "name": "allow_all" }, { - "name": "Vm" + "name": "update" } ] }, @@ -2909,6 +5270,17 @@ "name": "", "fields_or_variants": [] }, + { + "name": "AllowedSequencerUpdate", + "fields_or_variants": [ + { + "name": "to_add" + }, + { + "name": "to_remove" + } + ] + }, { "name": "", "fields_or_variants": [] @@ -2930,52 +5302,43 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_Transfer", + "name": "CallMessage", "fields_or_variants": [ { - "name": "to" + "name": "activate_revenue_share" }, { - "name": "coins" - } - ] - }, - { - "name": "Coins", - "fields_or_variants": [ + "name": "deactivate_revenue_share" + }, { - "name": "amount" + "name": "lower_revenue_percentage" }, { - "name": "token_id" + "name": "update_sovereign_admin" + }, + { + "name": "withdraw_rewards" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "__SovVirtualWallet_CallMessage_Burn", + "name": "__SovVirtualWallet_CallMessage_LowerRevenuePercentage", "fields_or_variants": [ { - "name": "coins" + "name": "percentage_in_basis_points" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Mint", + "name": "__SovVirtualWallet_CallMessage_UpdateSovereignAdmin", "fields_or_variants": [ { - "name": "coins" - }, - { - "name": "mint_to_address" + "name": "new_admin" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Freeze", + "name": "__SovVirtualWallet_CallMessage_WithdrawRewards", "fields_or_variants": [ { "name": "token_id" @@ -2990,27 +5353,36 @@ "name": "CallMessage", "fields_or_variants": [ { - "name": "register" - }, - { - "name": "deposit" + "name": "dispatch" }, { - "name": "initiate_withdrawal" + "name": "process" }, { - "name": "withdraw" + "name": "announce" } ] }, { - "name": "__SovVirtualWallet_CallMessage_Register", + "name": "__SovVirtualWallet_CallMessage_Dispatch", "fields_or_variants": [ { - "name": "da_address" + "name": "domain" }, { - "name": "amount" + "name": "recipient" + }, + { + "name": "body" + }, + { + "name": "metadata" + }, + { + "name": "relayer" + }, + { + "name": "gas_payment_limit" } ] }, @@ -3019,29 +5391,31 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_Deposit", + "name": "", + "fields_or_variants": [] + }, + { + "name": "__SovVirtualWallet_CallMessage_Process", "fields_or_variants": [ { - "name": "da_address" + "name": "metadata" }, { - "name": "amount" + "name": "message" } ] }, { - "name": "__SovVirtualWallet_CallMessage_InitiateWithdrawal", + "name": "__SovVirtualWallet_CallMessage_Announce", "fields_or_variants": [ { - "name": "da_address" - } - ] - }, - { - "name": "__SovVirtualWallet_CallMessage_Withdraw", - "fields_or_variants": [ + "name": "validator_address" + }, { - "name": "da_address" + "name": "storage_location" + }, + { + "name": "signature" } ] }, @@ -3050,20 +5424,8 @@ "fields_or_variants": [] }, { - "name": "CallMessage", - "fields_or_variants": [ - { - "name": "update_reward_address" - } - ] - }, - { - "name": "__SovVirtualWallet_CallMessage_UpdateRewardAddress", - "fields_or_variants": [ - { - "name": "new_reward_address" - } - ] + "name": "", + "fields_or_variants": [] }, { "name": "", @@ -3073,22 +5435,30 @@ "name": "CallMessage", "fields_or_variants": [ { - "name": "register_attester" + "name": "set_relayer_config" }, { - "name": "begin_exit_attester" + "name": "update_oracle_data" }, { - "name": "exit_attester" + "name": "claim_rewards" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_SetRelayerConfig", + "fields_or_variants": [ + { + "name": "domain_oracle_data" }, { - "name": "register_challenger" + "name": "domain_default_gas" }, { - "name": "exit_challenger" + "name": "default_gas" }, { - "name": "deposit_attester" + "name": "beneficiary" } ] }, @@ -3097,34 +5467,60 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] + "name": "DomainOracleData", + "fields_or_variants": [ + { + "name": "domain" + }, + { + "name": "data_value" + } + ] }, { - "name": "", - "fields_or_variants": [] + "name": "ExchangeRateAndGasPrice", + "fields_or_variants": [ + { + "name": "gas_price" + }, + { + "name": "token_exchange_rate" + } + ] }, { "name": "", "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "DomainDefaultGas", "fields_or_variants": [ { - "name": "register" + "name": "domain" }, { - "name": "deposit" + "name": "default_gas" + } + ] + }, + { + "name": "__SovVirtualWallet_CallMessage_UpdateOracleData", + "fields_or_variants": [ + { + "name": "domain" }, { - "name": "exit" + "name": "oracle_data" } ] }, { - "name": "", - "fields_or_variants": [] + "name": "__SovVirtualWallet_CallMessage_ClaimRewards", + "fields_or_variants": [ + { + "name": "relayer_address" + } + ] }, { "name": "", @@ -3138,136 +5534,134 @@ "name": "CallMessage", "fields_or_variants": [ { - "name": "insert_credential_id" + "name": "register" + }, + { + "name": "update" + }, + { + "name": "enroll_remote_router" + }, + { + "name": "un_enroll_remote_router" + }, + { + "name": "transfer_remote" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "NotInstantiable", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] + "name": "__SovVirtualWallet_CallMessage_Register", + "fields_or_variants": [ + { + "name": "admin" + }, + { + "name": "token_source" + }, + { + "name": "ism" + }, + { + "name": "remote_routers" + }, + { + "name": "inbound_transferrable_tokens_limit" + }, + { + "name": "inbound_limit_replenishment_per_slot" + }, + { + "name": "outbound_transferrable_tokens_limit" + }, + { + "name": "outbound_limit_replenishment_per_slot" + } + ] }, { - "name": "", - "fields_or_variants": [] + "name": "Admin", + "fields_or_variants": [ + { + "name": "None" + }, + { + "name": "InsecureOwner" + } + ] }, { "name": "", "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "TokenKind", "fields_or_variants": [ { - "name": "register_paymaster" + "name": "Synthetic" }, { - "name": "set_payer_for_sequencer" + "name": "Collateral" }, { - "name": "update_policy" - } - ] - }, - { - "name": "__SovVirtualWallet_CallMessage_RegisterPaymaster", - "fields_or_variants": [ - { - "name": "policy" + "name": "Native" } ] }, { - "name": "PaymasterPolicyInitializer", + "name": "__SovVirtualWallet_TokenKind_Synthetic", "fields_or_variants": [ { - "name": "default_payee_policy" - }, - { - "name": "payees" + "name": "remote_token_id" }, { - "name": "authorized_updaters" + "name": "remote_decimals" }, { - "name": "authorized_sequencers" + "name": "local_decimals" } ] }, { - "name": "PayeePolicy", + "name": "__SovVirtualWallet_TokenKind_Collateral", "fields_or_variants": [ { - "name": "allow" - }, - { - "name": "deny" + "name": "token" } ] }, { - "name": "__SovVirtualWallet_PayeePolicy_Allow", + "name": "Ism", "fields_or_variants": [ { - "name": "max_fee" - }, - { - "name": "gas_limit" + "name": "AlwaysTrust" }, { - "name": "max_gas_price" + "name": "TrustedRelayer" }, { - "name": "transaction_limit" + "name": "MessageIdMultisig" } ] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "", - "fields_or_variants": [] - }, - { - "name": "GasPrice", + "name": "__SovVirtualWallet_Ism_TrustedRelayer", "fields_or_variants": [ { - "name": "value" + "name": "relayer" } ] }, { - "name": "", - "fields_or_variants": [] + "name": "__SovVirtualWallet_Ism_MessageIdMultisig", + "fields_or_variants": [ + { + "name": "validators" + }, + { + "name": "threshold" + } + ] }, { "name": "", @@ -3282,13 +5676,28 @@ "fields_or_variants": [] }, { - "name": "AuthorizedSequencers", + "name": "__SovVirtualWallet_CallMessage_Update", "fields_or_variants": [ { - "name": "all" + "name": "warp_route" }, { - "name": "some" + "name": "admin" + }, + { + "name": "ism" + }, + { + "name": "inbound_transferrable_tokens_limit" + }, + { + "name": "inbound_limit_replenishment_per_slot" + }, + { + "name": "outbound_transferrable_tokens_limit" + }, + { + "name": "outbound_limit_replenishment_per_slot" } ] }, @@ -3301,44 +5710,50 @@ "fields_or_variants": [] }, { - "name": "__SovVirtualWallet_CallMessage_SetPayerForSequencer", + "name": "__SovVirtualWallet_CallMessage_EnrollRemoteRouter", "fields_or_variants": [ { - "name": "payer" + "name": "warp_route" + }, + { + "name": "remote_domain" + }, + { + "name": "remote_router_address" } ] }, { - "name": "__SovVirtualWallet_CallMessage_UpdatePolicy", + "name": "__SovVirtualWallet_CallMessage_UnEnrollRemoteRouter", "fields_or_variants": [ { - "name": "payer" + "name": "warp_route" }, { - "name": "update" + "name": "remote_domain" } ] }, { - "name": "PolicyUpdate", + "name": "__SovVirtualWallet_CallMessage_TransferRemote", "fields_or_variants": [ { - "name": "sequencer_update" + "name": "warp_route" }, { - "name": "updaters_to_add" + "name": "destination_domain" }, { - "name": "updaters_to_remove" + "name": "recipient" }, { - "name": "payee_policies_to_set" + "name": "amount" }, { - "name": "payee_policies_to_delete" + "name": "relayer" }, { - "name": "default_policy" + "name": "gas_payment_limit" } ] }, @@ -3347,13 +5762,13 @@ "fields_or_variants": [] }, { - "name": "SequencerSetUpdate", + "name": "CallMessage", "fields_or_variants": [ { - "name": "allow_all" + "name": "Call" }, { - "name": "update" + "name": "UpdateRuntimeConfig" } ] }, @@ -3362,13 +5777,10 @@ "fields_or_variants": [] }, { - "name": "AllowedSequencerUpdate", + "name": "RlpEvmTransaction", "fields_or_variants": [ { - "name": "to_add" - }, - { - "name": "to_remove" + "name": "rlp" } ] }, @@ -3377,8 +5789,21 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] + "name": "EvmRuntimeConfigUpdate", + "fields_or_variants": [ + { + "name": "new_hardfork" + }, + { + "name": "new_contract_creation_policy" + }, + { + "name": "chain_spec_update" + }, + { + "name": "new_admin" + } + ] }, { "name": "", @@ -3393,18 +5818,42 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "ContractCreationPolicyUpdate", "fields_or_variants": [ { - "name": "rlp" + "name": "Everyone" + }, + { + "name": "Allowlist" } ] }, { - "name": "RlpEvmTransaction", + "name": "__SovVirtualWallet_ContractCreationPolicyUpdate_Allowlist", "fields_or_variants": [ { - "name": "rlp" + "name": "add" + }, + { + "name": "remove" + } + ] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "ChainSpecUpdate", + "fields_or_variants": [ + { + "name": "new_limit_contract_code_size" + }, + { + "name": "new_block_gas_limit" + }, + { + "name": "new_tx_gas_limit" } ] }, @@ -3412,6 +5861,10 @@ "name": "", "fields_or_variants": [] }, + { + "name": "", + "fields_or_variants": [] + }, { "name": "AccessPatternMessages", "fields_or_variants": [ @@ -3451,9 +5904,6 @@ { "name": "delete_cells" }, - { - "name": "set_hook" - }, { "name": "update_admin" } @@ -3574,13 +6024,10 @@ ] }, { - "name": "__SovVirtualWallet_AccessPatternMessages_SetHook", + "name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", "fields_or_variants": [ { - "name": "pre" - }, - { - "name": "post" + "name": "new_admin" } ] }, @@ -3589,64 +6036,60 @@ "fields_or_variants": [] }, { - "name": "", - "fields_or_variants": [] - }, - { - "name": "HooksConfig", + "name": "CallMessage", "fields_or_variants": [ { - "name": "Read" + "name": "read_and_set_many_individual_values" }, { - "name": "Write" + "name": "read_and_set_heavy_state" }, { - "name": "Delete" + "name": "run_cpu_heavy_operation" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Read", + "name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", "fields_or_variants": [ { - "name": "begin" + "name": "number_of_operations" }, { - "name": "size" + "name": "salt" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Write", + "name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", "fields_or_variants": [ { - "name": "begin" + "name": "number_of_new_values" }, { - "name": "size" + "name": "max_heavy_state_size" }, { - "name": "data_size" + "name": "salt" } ] }, { - "name": "__SovVirtualWallet_HooksConfig_Delete", + "name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", "fields_or_variants": [ { - "name": "begin" - }, - { - "name": "size" + "name": "iterations" } ] }, { - "name": "__SovVirtualWallet_AccessPatternMessages_UpdateAdmin", + "name": "UniquenessData", "fields_or_variants": [ { - "name": "new_admin" + "name": "nonce" + }, + { + "name": "generation" } ] }, @@ -3655,66 +6098,105 @@ "fields_or_variants": [] }, { - "name": "CallMessage", + "name": "", + "fields_or_variants": [] + }, + { + "name": "TxDetails", "fields_or_variants": [ { - "name": "read_and_set_many_individual_values" + "name": "max_priority_fee_bips" }, { - "name": "read_and_set_heavy_state" + "name": "max_fee" }, { - "name": "run_cpu_heavy_operation" + "name": "gas_limit" + }, + { + "name": "chain_id" } ] }, { - "name": "__SovVirtualWallet_CallMessage_ReadAndSetManyIndividualValues", + "name": "", + "fields_or_variants": [] + }, + { + "name": "", + "fields_or_variants": [] + }, + { + "name": "Version1", "fields_or_variants": [ { - "name": "number_of_operations" + "name": "signatures" }, { - "name": "salt" + "name": "unused_pub_keys" + }, + { + "name": "min_signers" + }, + { + "name": "runtime_call" + }, + { + "name": "uniqueness" + }, + { + "name": "details" + }, + { + "name": "target_address" } ] }, { - "name": "__SovVirtualWallet_CallMessage_ReadAndSetHeavyState", + "name": "", + "fields_or_variants": [] + }, + { + "name": "PubKeyAndSignature", "fields_or_variants": [ { - "name": "number_of_new_values" - }, - { - "name": "max_heavy_state_size" + "name": "signature" }, { - "name": "salt" + "name": "pub_key" } ] }, { - "name": "__SovVirtualWallet_CallMessage_RunCPUHeavyOperation", + "name": "", + "fields_or_variants": [] + }, + { + "name": "UnsignedTransaction", "fields_or_variants": [ { - "name": "iterations" + "name": "V0" + }, + { + "name": "V1" } ] }, { - "name": "TxDetails", + "name": "", + "fields_or_variants": [] + }, + { + "name": "UnsignedTransactionV0", "fields_or_variants": [ { - "name": "max_priority_fee_bips" - }, - { - "name": "max_fee" + "name": "runtime_call" }, { - "name": "gas_limit" + "name": "uniqueness" }, { - "name": "chain_id" + "name": "details" } ] }, @@ -3723,18 +6205,24 @@ "fields_or_variants": [] }, { - "name": "UnsignedTransaction", + "name": "UnsignedTransactionV1", "fields_or_variants": [ { "name": "runtime_call" }, { - "name": "generation" + "name": "uniqueness" }, { "name": "details" + }, + { + "name": "credential_address" + }, + { + "name": "target_address" } ] } ] -} \ No newline at end of file +} diff --git a/typescript/packages/serializers/src/serializer.test.ts b/typescript/packages/serializers/src/serializer.test.ts index 11cfcecbdf..6752bff6aa 100644 --- a/typescript/packages/serializers/src/serializer.test.ts +++ b/typescript/packages/serializers/src/serializer.test.ts @@ -1,5 +1,88 @@ import { describe, expect, it } from "vitest"; -import { convertUint8ArraysToArrays } from "./serializer"; +import { Serializer, convertUint8ArraysToArrays } from "./serializer"; + +class TestSerializer extends Serializer { + public lastInput: unknown; + public lastIndex?: number; + + protected jsonToBorsh(input: unknown, index: number): Uint8Array { + this.lastInput = input; + this.lastIndex = index; + return new Uint8Array([1, 2, 3]); + } +} + +describe("Serializer", () => { + it("should wrap plain unsigned transactions as V0", () => { + const serializer = new TestSerializer({ root_type_indices: [0, 177, 3] }); + const unsignedTx = { + runtime_call: { bank: "transfer" }, + uniqueness: { generation: 1 }, + details: { max_fee: "1000" }, + }; + + const result = serializer.serializeUnsignedTx(unsignedTx); + + expect(result).toEqual(new Uint8Array([1, 2, 3])); + expect(serializer.lastIndex).toBe(177); + expect(serializer.lastInput).toEqual({ V0: unsignedTx }); + }); + + it("should not double-wrap versioned unsigned transactions", () => { + const serializer = new TestSerializer({ root_type_indices: [0, 177, 3] }); + const v0UnsignedTx = { + V0: { + runtime_call: { bank: "transfer" }, + uniqueness: { generation: 1 }, + details: { max_fee: "1000" }, + }, + }; + const v1UnsignedTx = { + V1: { + runtime_call: { bank: "transfer" }, + uniqueness: { nonce: 1 }, + details: { max_fee: "1000" }, + }, + }; + + serializer.serializeUnsignedTx(v0UnsignedTx); + expect(serializer.lastInput).toEqual(v0UnsignedTx); + + serializer.serializeUnsignedTx(v1UnsignedTx); + expect(serializer.lastInput).toEqual(v1UnsignedTx); + }); + + it("should convert Uint8Arrays when wrapping plain unsigned transactions", () => { + const serializer = new TestSerializer({ root_type_indices: [0, 177, 3] }); + const unsignedTx = { + runtime_call: { + bank: { + transfer: { + to: new Uint8Array([1, 2, 3]), + }, + }, + }, + uniqueness: { generation: 1 }, + details: { max_fee: "1000" }, + }; + + serializer.serializeUnsignedTx(unsignedTx); + + expect(serializer.lastInput).toEqual({ + V0: { + runtime_call: { + bank: { + transfer: { + to: [1, 2, 3], + }, + }, + }, + uniqueness: { generation: 1 }, + details: { max_fee: "1000" }, + }, + }); + }); +}); describe("convertUint8ArraysToArrays", () => { it("should convert a simple Uint8Array to a regular array", () => { diff --git a/typescript/packages/serializers/src/serializer.ts b/typescript/packages/serializers/src/serializer.ts index e77d12bd90..25640fe260 100644 --- a/typescript/packages/serializers/src/serializer.ts +++ b/typescript/packages/serializers/src/serializer.ts @@ -81,8 +81,10 @@ export abstract class Serializer { * @returns The serialized Borsh bytes. */ serializeUnsignedTx(input: unknown): Uint8Array { + const unsignedTx = isVersionedUnsignedTx(input) ? input : { V0: input }; + return this.serialize( - input, + unsignedTx, this.lookupKnownTypeIndex(KnownTypeId.UnsignedTransaction), ); } @@ -139,3 +141,13 @@ export function convertUint8ArraysToArrays(obj: T): T { return obj; } + +function isVersionedUnsignedTx( + input: unknown, +): input is { V0?: unknown; V1?: unknown } { + return ( + typeof input === "object" && + input !== null && + ("V0" in input || "V1" in input) + ); +} diff --git a/typescript/packages/signers/src/wasm/eip712.test.ts b/typescript/packages/signers/src/wasm/eip712.test.ts index b2fce08bc9..61461eaa23 100644 --- a/typescript/packages/signers/src/wasm/eip712.test.ts +++ b/typescript/packages/signers/src/wasm/eip712.test.ts @@ -34,7 +34,7 @@ const sampleUnsignedTx = { }, }, }, - generation: "12345", + uniqueness: { generation: "12345" }, details: { max_priority_fee_bips: "1000", max_fee: "10000", @@ -50,7 +50,7 @@ const sampleUnsignedTx = { function createTestMessage(): Uint8Array { const unsignedTxBorsh = schema.jsonToBorsh( schema.knownTypeIndex(KnownTypeId.UnsignedTransaction), - JSON.stringify(sampleUnsignedTx), + JSON.stringify({ V0: sampleUnsignedTx }), ); return new Uint8Array([...unsignedTxBorsh, ...schema.chainHash]); } diff --git a/typescript/packages/universal-wallet-wasm/tests/schema.test.ts b/typescript/packages/universal-wallet-wasm/tests/schema.test.ts index ffc4f430cf..51368eed90 100644 --- a/typescript/packages/universal-wallet-wasm/tests/schema.test.ts +++ b/typescript/packages/universal-wallet-wasm/tests/schema.test.ts @@ -30,7 +30,7 @@ describe("Schema", () => { describe("chainHash", () => { it("should calculate the chain hash successfully", () => { const expected = - "672f49a623e325540b52fe25a255a584f4cdf8e2b0c5c1fca13eab8a92c610ed"; + "0747c78c9a62a856f5208d9a980136996209d96bfacc6aa9db8c5da2b8322792"; const actual = bytesToHex(schema.chainHash); expect(actual).toEqual(expected); @@ -39,7 +39,7 @@ describe("Schema", () => { describe("metadataHash", () => { it("should restore the metadata hash successfully", () => { const expected = - "57c66aa8f2935ec352980d39e4f48d6aa10faf322d96254c63ec64eed82eb5b3"; + "1b7964c74362ea00edd356995713768b068d69a0d13da3bf143959307a228e06"; const actual = bytesToHex(schema.metadataHash); expect(actual).toEqual(expected); @@ -137,13 +137,15 @@ describe("Schema", () => { }; const unsignedTransaction = { - runtime_call: call, - generation: "0", - details: { - max_priority_fee_bips: "1000", - max_fee: "10000", - gas_limit: null, - chain_id: "1", + V0: { + runtime_call: call, + uniqueness: { generation: "0" }, + details: { + max_priority_fee_bips: "1000", + max_fee: "10000", + gas_limit: null, + chain_id: "1", + }, }, }; @@ -168,7 +170,7 @@ describe("Schema", () => { expect(parsed.primaryType).toBe("UnsignedTransaction"); expect(JSON.stringify(parsed)).toEqual( - `{"domain":{"name":"TestChain","chainId":"0x10e1","salt":"0x672f49a623e325540b52fe25a255a584f4cdf8e2b0c5c1fca13eab8a92c610ed"},"types":{"Bank":[{"type":"Transfer","name":"Transfer"}],"Coins":[{"type":"uint128","name":"amount"},{"type":"string","name":"token_id"}],"EIP712Domain":[{"type":"string","name":"name"},{"type":"uint256","name":"chainId"},{"type":"bytes32","name":"salt"}],"MultiAddress":[{"type":"string","name":"Standard"}],"RuntimeCall":[{"type":"Bank","name":"Bank"}],"Transfer":[{"type":"MultiAddress","name":"to"},{"type":"Coins","name":"coins"}],"TxDetails":[{"type":"uint64","name":"max_priority_fee_bips"},{"type":"uint128","name":"max_fee"},{"type":"uint64","name":"chain_id"}],"UnsignedTransaction":[{"type":"RuntimeCall","name":"runtime_call"},{"type":"uint64","name":"generation"},{"type":"TxDetails","name":"details"}]},"primaryType":"UnsignedTransaction","message":{"details":{"chain_id":"1","max_fee":"10000","max_priority_fee_bips":"1000"},"generation":"0","runtime_call":{"Bank":{"Transfer":{"coins":{"amount":"1000","token_id":"token_1rwrh8gn2py0dl4vv65twgctmlwck6esm2as9dftumcw89kqqn3nqrduss6"},"to":{"Standard":"sov1lzkjgdaz08su3yevqu6ceywufl35se9f33kztu5cu2spja5hyyf"}}}}}}` + `{"domain":{"name":"TestChain","chainId":"0x10e1","salt":"0x0747c78c9a62a856f5208d9a980136996209d96bfacc6aa9db8c5da2b8322792"},"types":{"Bank":[{"type":"Transfer","name":"Transfer"}],"Coins":[{"type":"uint128","name":"amount"},{"type":"string","name":"token_id"}],"EIP712Domain":[{"type":"string","name":"name"},{"type":"uint256","name":"chainId"},{"type":"bytes32","name":"salt"}],"MultiAddressEvmSolana":[{"type":"string","name":"Standard"}],"RuntimeCall":[{"type":"Bank","name":"Bank"}],"Transfer":[{"type":"MultiAddressEvmSolana","name":"to"},{"type":"Coins","name":"coins"}],"TxDetails":[{"type":"uint64","name":"max_priority_fee_bips"},{"type":"uint128","name":"max_fee"},{"type":"uint64","name":"chain_id"}],"UniquenessData":[{"type":"uint64","name":"Generation"}],"UnsignedTransaction":[{"type":"V0","name":"V0"}],"V0":[{"type":"RuntimeCall","name":"runtime_call"},{"type":"UniquenessData","name":"uniqueness"},{"type":"TxDetails","name":"details"}]},"primaryType":"UnsignedTransaction","message":{"V0":{"details":{"chain_id":"1","max_fee":"10000","max_priority_fee_bips":"1000"},"runtime_call":{"Bank":{"Transfer":{"coins":{"amount":"1000","token_id":"token_1rwrh8gn2py0dl4vv65twgctmlwck6esm2as9dftumcw89kqqn3nqrduss6"},"to":{"Standard":"sov1lzkjgdaz08su3yevqu6ceywufl35se9f33kztu5cu2spja5hyyf"}}}},"uniqueness":{"Generation":"0"}}}}` ); }); }); @@ -192,13 +194,15 @@ describe("Schema", () => { }; const unsignedTransaction = { - runtime_call: call, - generation: "0", - details: { - max_priority_fee_bips: "1000", - max_fee: "10000", - gas_limit: null, - chain_id: "1", + V0: { + runtime_call: call, + uniqueness: { generation: "0" }, + details: { + max_priority_fee_bips: "1000", + max_fee: "10000", + gas_limit: null, + chain_id: "1", + }, }, }; @@ -215,7 +219,7 @@ describe("Schema", () => { // Should return a 32-byte hash expect(signingHash).toHaveLength(32); expect(bytesToHex(signingHash)).toEqual( - "4afeb093d3faef4587d0074eac770e5cbde89c2392b3d5b1ae3f3674d53a8cc4" + "e21ca89ff493401ac0371c8bc7dc5782c585c0c9de8a3583a4753cb203f85999" ); }); });