diff --git a/api/libcompiler.aarch64.so b/api/libcompiler.aarch64.so index 1d728645..ba2cb9e5 100644 Binary files a/api/libcompiler.aarch64.so and b/api/libcompiler.aarch64.so differ diff --git a/api/libcompiler.dylib b/api/libcompiler.dylib index b0d3a25b..65beb0f7 100644 Binary files a/api/libcompiler.dylib and b/api/libcompiler.dylib differ diff --git a/api/libcompiler.x86_64.so b/api/libcompiler.x86_64.so index d736a0c1..2d39a301 100644 Binary files a/api/libcompiler.x86_64.so and b/api/libcompiler.x86_64.so differ diff --git a/api/libmovevm.aarch64.so b/api/libmovevm.aarch64.so index 8abbefab..fa912b81 100644 Binary files a/api/libmovevm.aarch64.so and b/api/libmovevm.aarch64.so differ diff --git a/api/libmovevm.dylib b/api/libmovevm.dylib index 74b6ef2d..2a56e7fa 100644 Binary files a/api/libmovevm.dylib and b/api/libmovevm.dylib differ diff --git a/api/libmovevm.x86_64.so b/api/libmovevm.x86_64.so index fcbea20f..8a1333fc 100644 Binary files a/api/libmovevm.x86_64.so and b/api/libmovevm.x86_64.so differ diff --git a/crates/e2e-move-tests/Cargo.toml b/crates/e2e-move-tests/Cargo.toml index 60c4ff0d..d6b5e665 100644 --- a/crates/e2e-move-tests/Cargo.toml +++ b/crates/e2e-move-tests/Cargo.toml @@ -21,6 +21,7 @@ once_cell = { workspace = true } sha3 = { workspace = true } bytes = { workspace = true } bigdecimal = { workspace = true } +bech32 = { workspace = true } initia-move-types = { workspace = true } initia-move-vm = { workspace = true } diff --git a/crates/e2e-move-tests/src/tests/cosmos.rs b/crates/e2e-move-tests/src/tests/cosmos.rs index 8a482104..9877ddc1 100644 --- a/crates/e2e-move-tests/src/tests/cosmos.rs +++ b/crates/e2e-move-tests/src/tests/cosmos.rs @@ -1,13 +1,14 @@ +use core::str; + use crate::tests::common::ExpectedOutput; use crate::MoveHarness; use initia_move_natives::code::UpgradePolicy; -use initia_move_types::cosmos::{ - CosmosCoin, CosmosMessage, DistributionMessage, IBCFee, IBCHeight, IBCMessage, MoveMessage, - StakingMessage, StargateCallback, StargateMessage, -}; +use initia_move_types::cosmos::{CosmosCallback, CosmosMessage}; use move_core_types::account_address::AccountAddress; use move_core_types::language_storage::TypeTag; use move_core_types::vm_status::VMStatus; + +use bech32::{Bech32, Hrp}; use sha3::{Digest, Sha3_256}; const STAKING_SYMBOL: &[u8] = b"ustake"; @@ -107,6 +108,13 @@ fn test_cosmos_delegate() { ); tests.push(test_initialize_coin); + let staking_denom = str::from_utf8(STAKING_SYMBOL).unwrap(); + let delegator_cosmos_addr = bech32::encode::( + Hrp::parse_unchecked("init"), + &delegator_address.into_bytes(), + ) + .unwrap(); + let expected_data = format!("{{\"@type\":\"/initia.mstaking.v1.MsgDelegate\",\"amount\":[{{\"amount\":\"{amount}\",\"denom\":\"{staking_denom}\"}}],\"delegator_address\":\"{delegator_cosmos_addr}\",\"validator_address\":\"{validator_address}\"}}"); let test_delegate = ( delegator_address, "0x1::cosmos::delegate", @@ -120,11 +128,12 @@ fn test_cosmos_delegate() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Staking(StakingMessage::Delegate { - delegator_address, - validator_address, - amount: CosmosCoin { amount, metadata }, - })]), + Some(vec![CosmosMessage { + sender: delegator_address, + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_delegate); @@ -155,6 +164,12 @@ fn test_cosmos_fund_community_pool() { ); tests.push(test_initialize_coin); + let denom = str::from_utf8(STAKING_SYMBOL).unwrap(); + let depositor_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender_address.into_bytes()) + .unwrap(); + let expected_data = format!("{{\"@type\":\"/cosmos.distribution.v1beta1.MsgFundCommunityPool\",\"amount\":[{{\"amount\":\"{amount}\",\"denom\":\"{denom}\"}}],\"depositor\":\"{depositor_cosmos_addr}\"}}"); + let test_fund_community_pool = ( sender_address, "0x1::cosmos::fund_community_pool", @@ -164,12 +179,12 @@ fn test_cosmos_fund_community_pool() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Distribution( - DistributionMessage::FundCommunityPool { - sender_address, - amount: CosmosCoin { amount, metadata }, - }, - )]), + Some(vec![CosmosMessage { + sender: sender_address, + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_fund_community_pool); @@ -207,6 +222,11 @@ fn test_cosmos_transfer() { ); tests.push(test_initialize_coin); + let denom = str::from_utf8(STAKING_SYMBOL).unwrap(); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/ibc.applications.transfer.v1.MsgTransfer\",\"memo\":\"{memo}\",\"receiver\":\"{receiver}\",\"sender\":\"{sender_cosmos_addr}\",\"source_channel\":\"{source_channel}\",\"source_port\":\"{source_port}\",\"timeout_height\":{{\"revision_height\":\"{revision_height}\",\"revision_number\":\"{revision_number}\"}},\"timeout_timestamp\":\"{timeout_timestamp}\",\"token\":{{\"amount\":\"{amount}\",\"denom\":\"{denom}\"}}}}"); + let test_transfer = ( sender, "0x1::cosmos::transfer", @@ -226,19 +246,12 @@ fn test_cosmos_transfer() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::IBC(IBCMessage::Transfer { - source_port, - source_channel, - token: CosmosCoin { amount, metadata }, + Some(vec![CosmosMessage { sender, - receiver, - timeout_height: IBCHeight { - revision_height, - revision_number, - }, - timeout_timestamp, - memo, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_transfer); @@ -281,6 +294,11 @@ fn test_cosmos_nft_transfer() { ); tests.push(test_create_collection); + let class_id = str::from_utf8(COLLECTION_NAME).unwrap(); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/ibc.applications.nft_transfer.v1.MsgTransfer\",\"class_id\":\"{class_id}\",\"memo\":\"{memo}\",\"receiver\":\"{receiver}\",\"sender\":\"{sender_cosmos_addr}\",\"source_channel\":\"{source_channel}\",\"source_port\":\"{source_port}\",\"timeout_height\":{{\"revision_height\":\"{revision_height}\",\"revision_number\":\"{revision_number}\"}},\"timeout_timestamp\":\"{timeout_timestamp}\",\"token_ids\":[\"id1\",\"id2\"]}}"); + let test_nft_transfer = ( sender, "0x1::cosmos::nft_transfer", @@ -300,20 +318,12 @@ fn test_cosmos_nft_transfer() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::IBC(IBCMessage::NFTTransfer { - source_port, - source_channel, - collection, - token_ids, + Some(vec![CosmosMessage { sender, - receiver, - timeout_height: IBCHeight { - revision_height, - revision_number, - }, - timeout_timestamp, - memo, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_nft_transfer); @@ -382,6 +392,13 @@ fn test_cosmos_pay_fee() { ); tests.push(test_initialize_coin); + let recv_fee_denom = str::from_utf8(STAKING_SYMBOL).unwrap(); + let ack_fee_denom = str::from_utf8(FEE_A_SYMBOL).unwrap(); + let timeout_fee_denom = str::from_utf8(FEE_B_SYMBOL).unwrap(); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/ibc.applications.fee.v1.MsgPayPacketFee\",\"fee\":{{\"ack_fee\":[{{\"amount\":\"{ack_fee_amount}\",\"denom\":\"{ack_fee_denom}\"}}],\"recv_fee\":[{{\"amount\":\"{recv_fee_amount}\",\"denom\":\"{recv_fee_denom}\"}}],\"timeout_fee\":[{{\"amount\":\"{timeout_fee_amount}\",\"denom\":\"{timeout_fee_denom}\"}}]}},\"relayers\":[],\"signer\":\"{sender_cosmos_addr}\",\"source_channel\":\"{source_channel}\",\"source_port\":\"{source_port}\"}}"); + let test_pay_fee = ( sender, "0x1::cosmos::pay_fee", @@ -400,25 +417,12 @@ fn test_cosmos_pay_fee() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::IBC(IBCMessage::PayFee { - signer: sender, - source_port, - source_channel, - fee: IBCFee { - recv_fee: CosmosCoin { - metadata: recv_fee_metadata, - amount: recv_fee_amount, - }, - ack_fee: CosmosCoin { - metadata: ack_fee_metadata, - amount: ack_fee_amount, - }, - timeout_fee: CosmosCoin { - metadata: timeout_fee_metadata, - amount: timeout_fee_amount, - }, - }, - })]), + Some(vec![CosmosMessage { + sender, + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_pay_fee); @@ -438,6 +442,13 @@ fn test_cosmos_move_execute() { let arg1 = vec![1, 2, 3]; let arg2 = vec![4, 5, 6]; + let arg1_hex = hex::encode(arg1.clone()); + let arg2_hex = hex::encode(arg2.clone()); + let module_addr_hex = module_address.to_hex_literal(); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/initia.move.v1.MsgExecute\",\"args\":[\"{arg1_hex}\",\"{arg2_hex}\"],\"function_name\":\"{function_name}\",\"module_address\":\"{module_addr_hex}\",\"module_name\":\"{module_name}\",\"sender\":\"{sender_cosmos_addr}\",\"type_args\":[\"{type_arg1}\",\"{type_arg2}\"]}}"); + let test_move_execute = ( sender, "0x1::cosmos::move_execute", @@ -453,15 +464,12 @@ fn test_cosmos_move_execute() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Move(MoveMessage::Execute { + Some(vec![CosmosMessage { sender, - module_address, - module_name, - function_name, - type_args: vec![type_arg1, type_arg2], - args: vec![arg1, arg2], - is_json: false, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_move_execute); @@ -481,6 +489,11 @@ fn test_cosmos_move_execute_with_json() { let arg1 = b"\"hello\"".to_vec(); let arg2 = b"\"world\"".to_vec(); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let module_addr_hex = module_address.to_hex_literal(); + let expected_data = format!("{{\"@type\":\"/initia.move.v1.MsgExecuteJSON\",\"args\":[\"\\\"hello\\\"\",\"\\\"world\\\"\"],\"function_name\":\"{function_name}\",\"module_address\":\"{module_addr_hex}\",\"module_name\":\"{module_name}\",\"sender\":\"{sender_cosmos_addr}\",\"type_args\":[\"{type_arg1}\",\"{type_arg2}\"]}}"); + let test_move_execute = ( sender, "0x1::cosmos::move_execute_with_json", @@ -496,15 +509,12 @@ fn test_cosmos_move_execute_with_json() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Move(MoveMessage::Execute { + Some(vec![CosmosMessage { sender, - module_address, - module_name, - function_name, - type_args: vec![type_arg1, type_arg2], - args: vec![arg1, arg2], - is_json: true, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_move_execute); @@ -522,6 +532,13 @@ fn test_cosmos_move_script() { let arg1 = vec![1, 2, 3]; let arg2 = vec![4, 5, 6]; + let code_bytes_hex = hex::encode(code_bytes.clone()); + let arg1_hex = hex::encode(arg1.clone()); + let arg2_hex = hex::encode(arg2.clone()); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/initia.move.v1.MsgScript\",\"args\":[\"{arg1_hex}\",\"{arg2_hex}\"],\"code_bytes\":\"{code_bytes_hex}\",\"sender\":\"{sender_cosmos_addr}\",\"type_args\":[\"{type_arg1}\",\"{type_arg2}\"]}}"); + let test_move_script = ( sender, "0x1::cosmos::move_script", @@ -535,13 +552,12 @@ fn test_cosmos_move_script() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Move(MoveMessage::Script { + Some(vec![CosmosMessage { sender, - code_bytes, - type_args: vec![type_arg1, type_arg2], - args: vec![arg1, arg2], - is_json: false, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_move_script); @@ -559,6 +575,11 @@ fn test_cosmos_move_script_with_json() { let arg1 = b"\"hello\"".to_vec(); let arg2 = b"\"world\"".to_vec(); + let code_bytes_hex = hex::encode(code_bytes.clone()); + let sender_cosmos_addr = + bech32::encode::(Hrp::parse_unchecked("init"), &sender.into_bytes()).unwrap(); + let expected_data = format!("{{\"@type\":\"/initia.move.v1.MsgScriptJSON\",\"args\":[\"\\\"hello\\\"\",\"\\\"world\\\"\"],\"code_bytes\":\"{code_bytes_hex}\",\"sender\":\"{sender_cosmos_addr}\",\"type_args\":[\"{type_arg1}\",\"{type_arg2}\"]}}"); + let test_move_script = ( sender, "0x1::cosmos::move_script_with_json", @@ -572,13 +593,12 @@ fn test_cosmos_move_script_with_json() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Move(MoveMessage::Script { + Some(vec![CosmosMessage { sender, - code_bytes, - type_args: vec![type_arg1, type_arg2], - args: vec![arg1, arg2], - is_json: true, - })]), + data: expected_data.into_bytes(), + allow_failure: false, + callback: None, + }]), ), ); tests.push(test_move_script); @@ -601,12 +621,12 @@ fn test_cosmos_stargate() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Stargate(StargateMessage { + Some(vec![CosmosMessage { sender, data: data.as_bytes().to_vec(), allow_failure: false, callback: None, - })]), + }]), ), ); tests.push(test_stargate); @@ -625,17 +645,17 @@ fn test_cosmos_stargate() { VMStatus::Executed, None, None, - Some(vec![CosmosMessage::Stargate(StargateMessage { + Some(vec![CosmosMessage { sender, data: data.as_bytes().to_vec(), allow_failure: false, - callback: Some(StargateCallback { + callback: Some(CosmosCallback { id: 123, module_address: AccountAddress::from_hex_literal("0xcafe").unwrap(), module_name: "test".to_string(), function_name: "callback".to_string(), }), - })]), + }]), ), ); tests.push(test_stargate); diff --git a/crates/gas/src/initia_stdlib.rs b/crates/gas/src/initia_stdlib.rs index 62ffc0b5..679d73d9 100644 --- a/crates/gas/src/initia_stdlib.rs +++ b/crates/gas/src/initia_stdlib.rs @@ -85,22 +85,7 @@ crate::macros::define_gas_parameters!( // These functions will consume gas after move execution finished, // so don't need to charge a lot here. [cosmos_stargate_base: InternalGas, "cosmos.stargate.base", 1000 * SCALING], - [cosmos_stargate_per_byte: InternalGasPerByte, "cosmos.stargate.per_byte", 7], - [cosmos_move_execute_base: InternalGas, "cosmos.move_execute.base", 1000 * SCALING], - [cosmos_move_execute_per_byte: InternalGasPerByte, "cosmos.move_execute.per_byte", 18], - [cosmos_move_script_base: InternalGas, "cosmos.move_script.base", 1000 * SCALING], - [cosmos_move_script_per_byte: InternalGasPerByte, "cosmos.move_script.per_byte", 18], - [cosmos_delegate_base: InternalGas, "cosmos.delegate.base", 1000 * SCALING], - [cosmos_delegate_per_byte: InternalGasPerByte, "cosmos.delegate.per_byte", 18], - [cosmos_fund_community_pool_base: InternalGas, "cosmos.fund_community_pool.base", 1000 * SCALING], - [cosmos_fund_community_pool_per_byte: InternalGasPerByte, "cosmos.fund_community_pool.per_byte", 18], - [cosmos_transfer_base: InternalGas, "cosmos.transfer.base", 1000 * SCALING], - [cosmos_transfer_per_byte: InternalGasPerByte, "cosmos.transfer.per_byte", 18], - [cosmos_nft_transfer_base: InternalGas, "cosmos.nft_transfer.base", 1000 * SCALING], - [cosmos_nft_transfer_per_token: InternalGasPerArg, "cosmos.nft_transfer.per_token", 10 * SCALING], - [cosmos_nft_transfer_per_byte: InternalGasPerByte, "cosmos.nft_transfer.per_byte", 18], - [cosmos_pay_fee_base: InternalGas, "cosmos.pay_fee.base", 1000 * SCALING], - [cosmos_pay_fee_per_byte: InternalGasPerByte, "cosmos.pay_fee.per_byte", 18], + [cosmos_stargate_per_byte: InternalGasPerByte, "cosmos.stargate.per_byte", 18], [query_custom_base: InternalGas, "query.custom.base", 100 * SCALING], [query_custom_per_byte: InternalGasPerByte, "query.custom.per_byte", 18], diff --git a/crates/json/src/json_to_value.rs b/crates/json/src/json_to_value.rs index ded2dc38..e5a0a62b 100644 --- a/crates/json/src/json_to_value.rs +++ b/crates/json/src/json_to_value.rs @@ -252,6 +252,7 @@ pub fn convert_json_value_to_value( let field_name = match f.name.as_str() { "_type_" => "@type", "_move_" => "move", + "_signer_" => "signer", v => v, }; diff --git a/crates/json/src/move_to_json.rs b/crates/json/src/move_to_json.rs index 737b54dc..1403782f 100644 --- a/crates/json/src/move_to_json.rs +++ b/crates/json/src/move_to_json.rs @@ -103,6 +103,7 @@ fn convert_move_value_to_json_value(val: &MoveValue, depth: usize) -> VMResult "@type", "_move_" => "move", + "_signer_" => "signer", v => v, }; diff --git a/crates/natives/src/cosmos.rs b/crates/natives/src/cosmos.rs index ec7fc877..185772a2 100644 --- a/crates/natives/src/cosmos.rs +++ b/crates/natives/src/cosmos.rs @@ -1,24 +1,18 @@ use better_any::{Tid, TidAble}; -use initia_move_gas::NumArgs; -use initia_move_types::cosmos::{ - CosmosCoin, CosmosMessage, CosmosMessages, DistributionMessage, IBCFee, IBCHeight, IBCMessage, - MoveMessage, StakingMessage, StargateMessage, -}; +use initia_move_types::cosmos::{CosmosMessage, CosmosMessages}; use move_core_types::{account_address::AccountAddress, gas_algebra::NumBytes}; use move_vm_runtime::native_functions::NativeFunction; use move_vm_types::{ loaded_data::runtime_types::Type, - values::{Struct, StructRef, Value, Vector}, + values::{Struct, Value, Vector}, }; use smallvec::{smallvec, SmallVec}; use std::{cell::RefCell, collections::VecDeque}; use crate::{ - helpers::{get_metadata_address, get_stargate_options, partial_extension_error}, - interface::{ - RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, SafeNativeResult, - }, - safely_pop_arg, safely_pop_vec_arg, + helpers::get_stargate_options, + interface::{RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult}, + safely_pop_arg, }; /*************************************************************************************************** @@ -72,12 +66,12 @@ fn native_stargate( context.charge(gas_params.cosmos_stargate_per_byte * NumBytes::new(data.len() as u64))?; let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - let message = CosmosMessage::Stargate(StargateMessage { + let message = CosmosMessage { sender, data, callback, allow_failure, - }); + }; // build cosmos message let cosmos_context = context.extensions().get::(); @@ -86,413 +80,27 @@ fn native_stargate( Ok(smallvec![]) } -fn native_move_execute( +#[cfg(feature = "testing")] +fn native_requested_messages( context: &mut SafeNativeContext, ty_args: Vec, - mut arguments: VecDeque, + _arguments: VecDeque, ) -> SafeNativeResult> { let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_move_execute_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 7); - - let is_json = safely_pop_arg!(arguments, bool); - - let mut msg_args: Vec> = vec![]; - for msg_arg in safely_pop_vec_arg!(arguments, Vec) { - context.charge( - gas_params.cosmos_move_execute_per_byte * NumBytes::new(msg_arg.len() as u64), - )?; - - msg_args.push(msg_arg); - } - - let mut msg_type_args: Vec = vec![]; - for msg_type_arg in safely_pop_vec_arg!(arguments, Vec) { - context.charge( - gas_params.cosmos_move_execute_per_byte * NumBytes::new(msg_type_arg.len() as u64), - )?; - - let msg_type_arg = std::str::from_utf8(&msg_type_arg) - .map_err(|_| partial_extension_error("failed to deserialize type args"))? - .to_string(); - msg_type_args.push(msg_type_arg); - } - - let function_name = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge( - gas_params.cosmos_move_execute_per_byte * NumBytes::new(function_name.len() as u64), - )?; - - let module_name = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge( - gas_params.cosmos_move_execute_per_byte * NumBytes::new(module_name.len() as u64), - )?; - - let module_address = safely_pop_arg!(arguments, AccountAddress); - let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - let function_name = std::str::from_utf8(&function_name) - .map_err(|_| partial_extension_error("failed to deserialize function_name"))? - .to_string(); - - let module_name = std::str::from_utf8(&module_name) - .map_err(|_| partial_extension_error("failed to deserialize module_name"))? - .to_string(); - - let message = CosmosMessage::Move(MoveMessage::Execute { - sender, - module_address, - module_name, - function_name, - type_args: msg_type_args, - args: msg_args, - is_json, - }); - - // build cosmos message - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_move_script( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_move_script_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 5); - - let is_json = safely_pop_arg!(arguments, bool); - - let mut msg_args: Vec> = vec![]; - for msg_arg in safely_pop_vec_arg!(arguments, Vec) { - context - .charge(gas_params.cosmos_move_script_per_byte * NumBytes::new(msg_arg.len() as u64))?; - - msg_args.push(msg_arg); - } - - let mut msg_type_args: Vec = vec![]; - for msg_type_arg in safely_pop_vec_arg!(arguments, Vec) { - context.charge( - gas_params.cosmos_move_script_per_byte * NumBytes::new(msg_type_arg.len() as u64), - )?; - - let msg_type_arg = std::str::from_utf8(&msg_type_arg) - .map_err(|_| partial_extension_error("failed to deserialize type args"))? - .to_string(); - msg_type_args.push(msg_type_arg); - } - - let code_bytes = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context - .charge(gas_params.cosmos_move_script_per_byte * NumBytes::new(code_bytes.len() as u64))?; - - let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - let message = CosmosMessage::Move(MoveMessage::Script { - sender, - code_bytes, - type_args: msg_type_args, - args: msg_args, - is_json, - }); - - // build cosmos message - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_delegate( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_delegate_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 4); - - let amount = safely_pop_arg!(arguments, u64); - let metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let validator_address = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge( - gas_params.cosmos_delegate_per_byte * NumBytes::new(validator_address.len() as u64), - )?; - - let delegator_address: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - // convert string - let validator_address = std::str::from_utf8(&validator_address) - .map_err(|_| partial_extension_error("failed to deserialize validator_address"))? - .to_string(); - let message = CosmosMessage::Staking(StakingMessage::Delegate { - delegator_address, - validator_address, - amount: CosmosCoin { amount, metadata }, - }); - - // build cosmos message - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_fund_community_pool( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_fund_community_pool_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 3); - - let amount = safely_pop_arg!(arguments, u64); - let metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let sender_address: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - let message = CosmosMessage::Distribution(DistributionMessage::FundCommunityPool { - sender_address, - amount: CosmosCoin { amount, metadata }, - }); - - // build cosmos message - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_transfer( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_transfer_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 10); - - let memo = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge(gas_params.cosmos_transfer_per_byte * NumBytes::new(memo.len() as u64))?; - - let timeout_timestamp = safely_pop_arg!(arguments, u64); - let revision_height = safely_pop_arg!(arguments, u64); - let revision_number = safely_pop_arg!(arguments, u64); - let source_channel = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context - .charge(gas_params.cosmos_transfer_per_byte * NumBytes::new(source_channel.len() as u64))?; - - let source_port = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context - .charge(gas_params.cosmos_transfer_per_byte * NumBytes::new(source_channel.len() as u64))?; - - let token_amount = safely_pop_arg!(arguments, u64); - let metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let receiver = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge(gas_params.cosmos_transfer_per_byte * NumBytes::new(receiver.len() as u64))?; - - let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - // convert to string - let memo = std::str::from_utf8(&memo) - .map_err(|_| partial_extension_error("failed to deserialize memo"))? - .to_string(); - let source_channel = std::str::from_utf8(&source_channel) - .map_err(|_| partial_extension_error("failed to deserialize source_channel"))? - .to_string(); - let source_port = std::str::from_utf8(&source_port) - .map_err(|_| partial_extension_error("failed to deserialize source_port"))? - .to_string(); - let receiver = std::str::from_utf8(&receiver) - .map_err(|_| partial_extension_error("failed to deserialize receiver"))? - .to_string(); - - // build cosmos message - let message = CosmosMessage::IBC(IBCMessage::Transfer { - source_port, - source_channel, - token: CosmosCoin { - metadata, - amount: token_amount, - }, - sender, - receiver, - timeout_height: IBCHeight { - revision_number, - revision_height, - }, - timeout_timestamp, - memo, - }); - - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_nft_transfer( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_nft_transfer_base)?; - - debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 10); - - let memo = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge(gas_params.cosmos_nft_transfer_per_byte * NumBytes::new(memo.len() as u64))?; - - let timeout_timestamp = safely_pop_arg!(arguments, u64); - let revision_height = safely_pop_arg!(arguments, u64); - let revision_number = safely_pop_arg!(arguments, u64); - let source_channel = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge( - gas_params.cosmos_nft_transfer_per_byte * NumBytes::new(source_channel.len() as u64), - )?; - - let source_port = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge( - gas_params.cosmos_nft_transfer_per_byte * NumBytes::new(source_port.len() as u64), - )?; - - let token_ids = safely_pop_vec_arg!(arguments, Vec); - context.charge( - gas_params.cosmos_nft_transfer_per_byte - * NumBytes::new(token_ids.iter().map(|v| v.len()).sum::() as u64), - )?; - context - .charge(gas_params.cosmos_nft_transfer_per_token * NumArgs::new(token_ids.len() as u64))?; - - let collection = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let receiver = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context - .charge(gas_params.cosmos_nft_transfer_per_byte * NumBytes::new(receiver.len() as u64))?; - - let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - // convert to string - let memo = std::str::from_utf8(&memo) - .map_err(|_| partial_extension_error("failed to deserialize memo"))? - .to_string(); - let source_channel = std::str::from_utf8(&source_channel) - .map_err(|_| partial_extension_error("failed to deserialize source_channel"))? - .to_string(); - let source_port = std::str::from_utf8(&source_port) - .map_err(|_| partial_extension_error("failed to deserialize source_port"))? - .to_string(); - let receiver = std::str::from_utf8(&receiver) - .map_err(|_| partial_extension_error("failed to deserialize receiver"))? - .to_string(); - - let token_ids = token_ids - .iter() - .map(|v| { - std::str::from_utf8(v).map(|v| v.to_string()).map_err(|_| { - SafeNativeError::InvariantViolation(partial_extension_error( - "failed to deserialize receiver", - )) - }) - }) - .collect::>>()?; - - // build cosmos message - let message = CosmosMessage::IBC(IBCMessage::NFTTransfer { - source_port, - source_channel, - collection, - token_ids, - sender, - receiver, - timeout_height: IBCHeight { - revision_number, - revision_height, - }, - timeout_timestamp, - memo, - }); - - let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) -} - -fn native_pay_fee( - context: &mut SafeNativeContext, - ty_args: Vec, - mut arguments: VecDeque, -) -> SafeNativeResult> { - let gas_params = &context.native_gas_params.initia_stdlib; - context.charge(gas_params.cosmos_pay_fee_base)?; + context.charge(gas_params.cosmos_stargate_base)?; debug_assert!(ty_args.is_empty()); - debug_assert!(arguments.len() == 9); - - let timeout_fee_amount = safely_pop_arg!(arguments, u64); - let timeout_fee_metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let ack_fee_amount = safely_pop_arg!(arguments, u64); - let ack_fee_metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let recv_fee_amount = safely_pop_arg!(arguments, u64); - let recv_fee_metadata = get_metadata_address(&safely_pop_arg!(arguments, StructRef))?; - let source_channel = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context - .charge(gas_params.cosmos_pay_fee_per_byte * NumBytes::new(source_channel.len() as u64))?; - - let source_port = safely_pop_arg!(arguments, Vector).to_vec_u8()?; - context.charge(gas_params.cosmos_pay_fee_per_byte * NumBytes::new(source_port.len() as u64))?; - - let sender: AccountAddress = safely_pop_arg!(arguments, AccountAddress); - - // convert to string - let source_channel = std::str::from_utf8(&source_channel) - .map_err(|_| partial_extension_error("failed to deserialize source_channel"))? - .to_string(); - let source_port = std::str::from_utf8(&source_port) - .map_err(|_| partial_extension_error("failed to deserialize source_port"))? - .to_string(); - - // build cosmos message - let message = CosmosMessage::IBC(IBCMessage::PayFee { - signer: sender, - source_channel, - source_port, - fee: IBCFee { - recv_fee: CosmosCoin { - metadata: recv_fee_metadata, - amount: recv_fee_amount, - }, - ack_fee: CosmosCoin { - metadata: ack_fee_metadata, - amount: ack_fee_amount, - }, - timeout_fee: CosmosCoin { - metadata: timeout_fee_metadata, - amount: timeout_fee_amount, - }, - }, - }); + debug_assert!(_arguments.is_empty()); let cosmos_context = context.extensions().get::(); - cosmos_context.messages.borrow_mut().push(message); - - Ok(smallvec![]) + let messages = cosmos_context + .messages + .borrow() + .clone() + .into_iter() + .map(|m| Value::struct_(Struct::pack(vec![Value::vector_u8(m.data)]))); + + Ok(smallvec![Value::vector_for_testing_only(messages)]) } /*************************************************************************************************** @@ -502,16 +110,14 @@ fn native_pay_fee( pub fn make_all( builder: &SafeNativeBuilder, ) -> impl Iterator + '_ { - let natives = vec![ - ("stargate_internal", native_stargate as RawSafeNative), - ("move_execute_internal", native_move_execute), - ("move_script_internal", native_move_script), - ("delegate_internal", native_delegate), - ("fund_community_pool_internal", native_fund_community_pool), - ("transfer_internal", native_transfer), - ("nft_transfer_internal", native_nft_transfer), - ("pay_fee_internal", native_pay_fee), - ]; + let mut natives = vec![]; + natives.extend([("stargate_internal", native_stargate as RawSafeNative)]); + + #[cfg(feature = "testing")] + natives.extend([( + "requested_messages", + native_requested_messages as RawSafeNative, + )]); builder.make_named_natives(natives) } diff --git a/crates/natives/src/helpers.rs b/crates/natives/src/helpers.rs index f0a1b727..d1aa48b9 100644 --- a/crates/natives/src/helpers.rs +++ b/crates/natives/src/helpers.rs @@ -1,6 +1,6 @@ use std::str::from_utf8; -use initia_move_types::cosmos::StargateCallback; +use initia_move_types::cosmos::CosmosCallback; use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{account_address::AccountAddress, vm_status::StatusCode}; use move_vm_types::values::{Reference, Struct, StructRef, Value, Vector}; @@ -30,7 +30,7 @@ pub fn get_string(v: Struct) -> PartialVMResult> { ) } -pub fn get_stargate_options(v: Struct) -> PartialVMResult<(bool, Option)> { +pub fn get_stargate_options(v: Struct) -> PartialVMResult<(bool, Option)> { let mut vals: Vec = v .unpack() .map_err(|_| partial_extension_error("failed to deserialize arg"))? @@ -71,7 +71,7 @@ pub fn get_stargate_options(v: Struct) -> PartialVMResult<(bool, Option, pub allow_failure: bool, - pub callback: Option, + pub callback: Option, +} + +impl Debug for CosmosMessage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CosmosMessage") + .field("sender", &self.sender.to_standard_string()) + .field( + "data", + &str::from_utf8(&self.data).unwrap_or(""), + ) + .field("allow_failure", &self.allow_failure) + .field("callback", &self.callback) + .finish() + } } #[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct StargateCallback { +pub struct CosmosCallback { pub id: u64, pub module_address: AccountAddress, pub module_name: String, pub function_name: String, } - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub enum MoveMessage { - Execute { - sender: AccountAddress, - module_address: AccountAddress, - module_name: String, - function_name: String, - type_args: Vec, - args: Vec>, - is_json: bool, - }, - Script { - sender: AccountAddress, - code_bytes: Vec, - type_args: Vec, - args: Vec>, - is_json: bool, - }, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub enum StakingMessage { - Delegate { - delegator_address: AccountAddress, - validator_address: String, - amount: CosmosCoin, - }, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub enum DistributionMessage { - FundCommunityPool { - sender_address: AccountAddress, - amount: CosmosCoin, - }, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub enum IBCMessage { - Transfer { - source_port: String, - source_channel: String, - token: CosmosCoin, - sender: AccountAddress, - receiver: String, - timeout_height: IBCHeight, - timeout_timestamp: u64, - memo: String, - }, - NFTTransfer { - source_port: String, - source_channel: String, - collection: AccountAddress, - token_ids: Vec, - sender: AccountAddress, - receiver: String, - timeout_height: IBCHeight, - timeout_timestamp: u64, - memo: String, - }, - PayFee { - fee: IBCFee, - source_port: String, - source_channel: String, - signer: AccountAddress, - }, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct CosmosCoin { - pub metadata: AccountAddress, - pub amount: u64, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct IBCHeight { - pub revision_number: u64, - pub revision_height: u64, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] -pub struct IBCFee { - pub recv_fee: CosmosCoin, - pub ack_fee: CosmosCoin, - pub timeout_fee: CosmosCoin, -} diff --git a/precompile/binaries/minlib/collection.mv b/precompile/binaries/minlib/collection.mv index 5ac55b79..07ce7f53 100644 Binary files a/precompile/binaries/minlib/collection.mv and b/precompile/binaries/minlib/collection.mv differ diff --git a/precompile/binaries/minlib/cosmos.mv b/precompile/binaries/minlib/cosmos.mv index 096f706e..cac09be4 100644 Binary files a/precompile/binaries/minlib/cosmos.mv and b/precompile/binaries/minlib/cosmos.mv differ diff --git a/precompile/binaries/stdlib/collection.mv b/precompile/binaries/stdlib/collection.mv index 5ac55b79..07ce7f53 100644 Binary files a/precompile/binaries/stdlib/collection.mv and b/precompile/binaries/stdlib/collection.mv differ diff --git a/precompile/binaries/stdlib/cosmos.mv b/precompile/binaries/stdlib/cosmos.mv index 096f706e..cac09be4 100644 Binary files a/precompile/binaries/stdlib/cosmos.mv and b/precompile/binaries/stdlib/cosmos.mv differ diff --git a/precompile/binaries/stdlib/minitswap.mv b/precompile/binaries/stdlib/minitswap.mv index fe6e3eeb..d39d07c4 100644 Binary files a/precompile/binaries/stdlib/minitswap.mv and b/precompile/binaries/stdlib/minitswap.mv differ diff --git a/precompile/binaries/stdlib/staking.mv b/precompile/binaries/stdlib/staking.mv index 772711d9..bc269458 100644 Binary files a/precompile/binaries/stdlib/staking.mv and b/precompile/binaries/stdlib/staking.mv differ diff --git a/precompile/modules/initia_stdlib/sources/cosmos.move b/precompile/modules/initia_stdlib/sources/cosmos.move index 8490922b..46faa211 100644 --- a/precompile/modules/initia_stdlib/sources/cosmos.move +++ b/precompile/modules/initia_stdlib/sources/cosmos.move @@ -1,6 +1,7 @@ /// This module provides interfaces to allow CosmosMessage /// execution after the move execution finished. module initia_std::cosmos { + use std::address; use std::signer; use std::vector; use std::string::{Self, String}; @@ -8,6 +9,8 @@ module initia_std::cosmos { use std::fungible_asset::Metadata; use std::collection::{Collection}; use std::error; + use std::coin::metadata_to_denom; + use std::collection::collection_to_class_id; use initia_std::json; @@ -68,6 +71,16 @@ module initia_std::cosmos { stargate_internal(signer::address_of(sender), data, options) } + struct ExecuteRequest has copy, drop { + _type_: String, + sender: String, + module_address: address, + module_name: String, + function_name: String, + type_args: vector, + args: vector> + } + public entry fun move_execute( sender: &signer, module_address: address, @@ -76,17 +89,32 @@ module initia_std::cosmos { type_args: vector, args: vector> ) { - move_execute_internal( - signer::address_of(sender), - module_address, - *string::bytes(&module_name), - *string::bytes(&function_name), - vector::map_ref(&type_args, |v| *string::bytes(v)), - args, - false + stargate( + sender, + json::marshal( + &ExecuteRequest { + _type_: string::utf8(b"/initia.move.v1.MsgExecute"), + sender: address::to_sdk(signer::address_of(sender)), + module_address, + module_name, + function_name, + type_args, + args + } + ) ) } + struct ExecuteJSONRequest has copy, drop { + _type_: String, + sender: String, + module_address: address, + module_name: String, + function_name: String, + type_args: vector, + args: vector + } + public entry fun move_execute_with_json( sender: &signer, module_address: address, @@ -95,65 +123,147 @@ module initia_std::cosmos { type_args: vector, args: vector ) { - move_execute_internal( - signer::address_of(sender), - module_address, - *string::bytes(&module_name), - *string::bytes(&function_name), - vector::map_ref(&type_args, |v| *string::bytes(v)), - vector::map_ref(&args, |v| *string::bytes(v)), - true + stargate( + sender, + json::marshal( + &ExecuteJSONRequest { + _type_: string::utf8(b"/initia.move.v1.MsgExecuteJSON"), + sender: address::to_sdk(signer::address_of(sender)), + module_address, + module_name, + function_name, + type_args, + args + } + ) ) } + struct ScriptRequest has copy, drop { + _type_: String, + sender: String, + code_bytes: vector, + type_args: vector, + args: vector> + } + public entry fun move_script( sender: &signer, code_bytes: vector, type_args: vector, args: vector> ) { - move_script_internal( - signer::address_of(sender), - code_bytes, - vector::map_ref(&type_args, |v| *string::bytes(v)), - args, - false + stargate( + sender, + json::marshal( + &ScriptRequest { + _type_: string::utf8(b"/initia.move.v1.MsgScript"), + sender: address::to_sdk(signer::address_of(sender)), + code_bytes, + type_args, + args + } + ) ) } + struct ScriptJSONRequest has copy, drop { + _type_: String, + sender: String, + code_bytes: vector, + type_args: vector, + args: vector + } + public entry fun move_script_with_json( sender: &signer, code_bytes: vector, type_args: vector, args: vector ) { - move_script_internal( - signer::address_of(sender), - code_bytes, - vector::map_ref(&type_args, |v| *string::bytes(v)), - vector::map_ref(&args, |v| *string::bytes(v)), - true + stargate( + sender, + json::marshal( + &ScriptJSONRequest { + _type_: string::utf8(b"/initia.move.v1.MsgScriptJSON"), + sender: address::to_sdk(signer::address_of(sender)), + code_bytes, + type_args, + args + } + ) ) } + struct DelegateRequest has copy, drop { + _type_: String, + delegator_address: String, + validator_address: String, + amount: vector + } + + struct CosmosCoin has copy, drop { + denom: String, + amount: u64 + } + public entry fun delegate( delegator: &signer, validator: String, metadata: Object, amount: u64 ) { - delegate_internal( - signer::address_of(delegator), - *string::bytes(&validator), - &metadata, - amount + stargate( + delegator, + json::marshal( + &DelegateRequest { + _type_: string::utf8(b"/initia.mstaking.v1.MsgDelegate"), + delegator_address: address::to_sdk(signer::address_of(delegator)), + validator_address: validator, + amount: vector[CosmosCoin { denom: metadata_to_denom(metadata), amount }] + } + ) ) } + struct FuncCommunityPoolRequest has copy, drop { + _type_: String, + depositor: String, + amount: vector + } + public entry fun fund_community_pool( sender: &signer, metadata: Object, amount: u64 ) { - fund_community_pool_internal(signer::address_of(sender), &metadata, amount) + stargate( + sender, + json::marshal( + &FuncCommunityPoolRequest { + _type_: string::utf8( + b"/cosmos.distribution.v1beta1.MsgFundCommunityPool" + ), + depositor: address::to_sdk(signer::address_of(sender)), + amount: vector[CosmosCoin { denom: metadata_to_denom(metadata), amount }] + } + ) + ) + } + + struct TransferRequest has copy, drop { + _type_: String, + source_port: String, + source_channel: String, + sender: String, + receiver: String, + token: CosmosCoin, + timeout_height: TimeoutHeight, + timeout_timestamp: u64, + memo: String + } + + struct TimeoutHeight has copy, drop { + revision_number: u64, + revision_height: u64 } /// ICS20 ibc transfer @@ -170,20 +280,40 @@ module initia_std::cosmos { timeout_timestamp: u64, memo: String ) { - transfer_internal( - signer::address_of(sender), - *string::bytes(&receiver), - &metadata, - token_amount, - *string::bytes(&source_port), - *string::bytes(&source_channel), - revision_number, - revision_height, - timeout_timestamp, - *string::bytes(&memo) + stargate( + sender, + json::marshal( + &TransferRequest { + _type_: string::utf8(b"/ibc.applications.transfer.v1.MsgTransfer"), + source_port, + source_channel, + sender: address::to_sdk(signer::address_of(sender)), + receiver, + token: CosmosCoin { + denom: metadata_to_denom(metadata), + amount: token_amount + }, + timeout_height: TimeoutHeight { revision_number, revision_height }, + timeout_timestamp, + memo + } + ) ) } + struct NFTTransferRequest has copy, drop { + _type_: String, + sender: String, + receiver: String, + class_id: String, + token_ids: vector, + source_port: String, + source_channel: String, + timeout_height: TimeoutHeight, + timeout_timestamp: u64, + memo: String + } + /// ICS721 ibc nft_transfer /// https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer public entry fun nft_transfer( @@ -198,20 +328,40 @@ module initia_std::cosmos { timeout_timestamp: u64, memo: String ) { - nft_transfer_internal( - signer::address_of(sender), - *string::bytes(&receiver), - &collection, - vector::map_ref(&token_ids, |v| *string::bytes(v)), - *string::bytes(&source_port), - *string::bytes(&source_channel), - revision_number, - revision_height, - timeout_timestamp, - *string::bytes(&memo) + stargate( + sender, + json::marshal( + &NFTTransferRequest { + _type_: string::utf8(b"/ibc.applications.nft_transfer.v1.MsgTransfer"), + sender: address::to_sdk(signer::address_of(sender)), + receiver, + class_id: collection_to_class_id(collection), + token_ids, + source_port, + source_channel, + timeout_height: TimeoutHeight { revision_number, revision_height }, + timeout_timestamp, + memo + } + ) ) } + struct Fee has copy, drop { + recv_fee: vector, + ack_fee: vector, + timeout_fee: vector + } + + struct PayFeeRequest has copy, drop { + _type_: String, + _signer_: String, + source_port: String, + source_channel: String, + fee: Fee, + relayers: vector + } + /// ICS29 ibc relayer fee /// https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment public entry fun pay_fee( @@ -225,16 +375,37 @@ module initia_std::cosmos { timeout_fee_metadata: Object, timeout_fee_amount: u64 ) { - pay_fee_internal( - signer::address_of(sender), - *string::bytes(&source_port), - *string::bytes(&source_channel), - &recv_fee_metadata, - recv_fee_amount, - &ack_fee_metadata, - ack_fee_amount, - &timeout_fee_metadata, - timeout_fee_amount + stargate( + sender, + json::marshal( + &PayFeeRequest { + _type_: string::utf8(b"/ibc.applications.fee.v1.MsgPayPacketFee"), + _signer_: address::to_sdk(signer::address_of(sender)), + source_port, + source_channel, + fee: Fee { + recv_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(recv_fee_metadata), + amount: recv_fee_amount + } + ], + ack_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(ack_fee_metadata), + amount: ack_fee_amount + } + ], + timeout_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(timeout_fee_metadata), + amount: timeout_fee_amount + } + ] + }, + relayers: vector::empty() + } + ) ) } @@ -242,72 +413,14 @@ module initia_std::cosmos { sender: address, data: vector, option: Options ); - native fun move_execute_internal( - sender: address, - module_address: address, - module_name: vector, - function_name: vector, - type_args: vector>, - args: vector>, - is_json: bool - ); - - native fun move_script_internal( - sender: address, - code_bytes: vector, - type_args: vector>, - args: vector>, - is_json: bool - ); - - native fun delegate_internal( - delegator: address, - validator: vector, - metadata: &Object, - amount: u64 - ); - - native fun fund_community_pool_internal( - sender: address, metadata: &Object, amount: u64 - ); - - native fun transfer_internal( - sender: address, - receiver: vector, - metadata: &Object, - token_amount: u64, - source_port: vector, - source_channel: vector, - revision_number: u64, - revision_height: u64, - timeout_timestamp: u64, - memo: vector - ); - - native fun nft_transfer_internal( - sender: address, - receiver: vector, - collection: &Object, - token_ids: vector>, - source_port: vector, - source_channel: vector, - revision_number: u64, - revision_height: u64, - timeout_timestamp: u64, - memo: vector - ); + #[test_only] + native public fun requested_messages(): vector; - native fun pay_fee_internal( - sender: address, - source_port: vector, - source_channel: vector, - recv_fee_metadata: &Object, - recv_fee_amount: u64, - ack_fee_metadata: &Object, - ack_fee_amount: u64, - timeout_fee_metadata: &Object, - timeout_fee_amount: u64 - ); + #[test_only] + public fun was_message_requested(msg: &String): bool { + use std::vector; + vector::contains(&requested_messages(), msg) + } // ================================================== Options ================================================= @@ -374,4 +487,30 @@ module initia_std::cosmos { callback_fid: *string::bytes(&fid) } } + + //=========================================== Tests =========================================== + + #[test(sender = @0xcafe)] + public fun test_stargate_vote(sender: &signer) { + use std::string::utf8; + + let voter = utf8(b"voter"); + let proposal_id = 1; + let option = 1; + let metadata = utf8(b"metadata"); + stargate_vote(sender, proposal_id, voter, option, metadata); + + let msg = + json::marshal_to_string( + &VoteRequest { + _type_: utf8(b"/cosmos.gov.v1.MsgVote"), + proposal_id, + voter: voter, + option, + metadata: metadata + } + ); + + assert!(was_message_requested(&msg), 1); + } } diff --git a/precompile/modules/initia_stdlib/sources/json.move b/precompile/modules/initia_stdlib/sources/json.move index 0d8618e4..dde31e8c 100644 --- a/precompile/modules/initia_stdlib/sources/json.move +++ b/precompile/modules/initia_stdlib/sources/json.move @@ -87,6 +87,7 @@ module initia_std::json { /// /// NOTE: key `_type_` is converted to `@type` /// NOTE: key `_move_` is converted to `move` + /// NOTE: key `_signer_` is converted to `signer` public fun marshal(value: &T): vector { marshal_internal(value) } @@ -95,6 +96,7 @@ module initia_std::json { /// /// NOTE: key `_type_` is converted to `@type` /// NOTE: key `_move_` is converted to `move` + /// /// NOTE: key `_signer_` is converted to `signer` public fun marshal_to_string(value: &T): String { marshal_to_string_internal(value) } @@ -103,6 +105,7 @@ module initia_std::json { /// /// NOTE: key `@type` is converted to `_type_` /// NOTE: key `move` is converted to `_move_` + /// NOTE: key `signer` is converted to `_signer_` public fun unmarshal(json: vector): T { unmarshal_internal(json) } @@ -127,6 +130,7 @@ module initia_std::json { f: Option, _type_: String, _move_: String, + _signer_: String, biguint: BigUint, bigdecimal: BigDecimal } @@ -179,6 +183,7 @@ module initia_std::json { f: option::none(), _type_: string::utf8(b"/cosmos.gov.v1.MsgVote"), _move_: string::utf8(b"move"), + _signer_: string::utf8(b"signer"), biguint: biguint::from_u64(42), bigdecimal: bigdecimal::from_ratio_u64(123, 10000) }; @@ -186,7 +191,7 @@ module initia_std::json { let json = marshal(&obj); assert!( json - == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"010203\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\"}", + == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"010203\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\",\"signer\":\"signer\"}", 1 ); @@ -242,7 +247,7 @@ module initia_std::json { let json5 = marshal(&json_obj); assert!( json5 - == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"hello\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\"}", + == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"hello\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\",\"signer\":\"signer\"}", 9 ); } diff --git a/precompile/modules/initia_stdlib/sources/token/collection.move b/precompile/modules/initia_stdlib/sources/token/collection.move index 5d2b7144..278da9c8 100644 --- a/precompile/modules/initia_stdlib/sources/token/collection.move +++ b/precompile/modules/initia_stdlib/sources/token/collection.move @@ -22,9 +22,11 @@ module initia_std::collection { use std::signer; use std::string::{Self, String}; use std::vector; + use std::bcs; use initia_std::event; use initia_std::object::{Self, ConstructorRef, Object}; use initia_std::table::{Self, Table}; + use initia_std::hex; use initia_std::royalty::{Self, Royalty}; @@ -387,6 +389,21 @@ module initia_std::collection { borrow(collection).uri } + #[view] + public fun collection_to_class_id(collection: Object): String acquires Collection { + let col = borrow(collection); + if (col.creator == @initia_std) { + return col.name + }; + + let metadata_addr = object::object_address(&collection); + let denom = string::utf8(b"move/"); + let addr_bytes = bcs::to_bytes(&metadata_addr); + let addr_string = hex::encode_to_string(&addr_bytes); + string::append(&mut denom, addr_string); + return denom + } + #[view] /// get nft list from collection /// if `start_after` is not none, seach nfts in range (start_after, ...] diff --git a/precompile/modules/minitia_stdlib/sources/cosmos.move b/precompile/modules/minitia_stdlib/sources/cosmos.move index bc78d77d..045b61ec 100644 --- a/precompile/modules/minitia_stdlib/sources/cosmos.move +++ b/precompile/modules/minitia_stdlib/sources/cosmos.move @@ -1,6 +1,7 @@ /// This module provides interfaces to allow CosmosMessage /// execution after the move execution finished. module minitia_std::cosmos { + use std::address; use std::signer; use std::vector; use std::string::{Self, String}; @@ -8,6 +9,8 @@ module minitia_std::cosmos { use std::fungible_asset::Metadata; use std::collection::{Collection}; use std::error; + use std::coin::metadata_to_denom; + use std::collection::collection_to_class_id; use minitia_std::json; @@ -68,6 +71,16 @@ module minitia_std::cosmos { stargate_internal(signer::address_of(sender), data, options) } + struct ExecuteRequest has copy, drop { + _type_: String, + sender: String, + module_address: address, + module_name: String, + function_name: String, + type_args: vector, + args: vector> + } + public entry fun move_execute( sender: &signer, module_address: address, @@ -76,17 +89,32 @@ module minitia_std::cosmos { type_args: vector, args: vector> ) { - move_execute_internal( - signer::address_of(sender), - module_address, - *string::bytes(&module_name), - *string::bytes(&function_name), - vector::map_ref(&type_args, |v| *string::bytes(v)), - args, - false + stargate( + sender, + json::marshal( + &ExecuteRequest { + _type_: string::utf8(b"/initia.move.v1.MsgExecute"), + sender: address::to_sdk(signer::address_of(sender)), + module_address, + module_name, + function_name, + type_args, + args + } + ) ) } + struct ExecuteJSONRequest has copy, drop { + _type_: String, + sender: String, + module_address: address, + module_name: String, + function_name: String, + type_args: vector, + args: vector + } + public entry fun move_execute_with_json( sender: &signer, module_address: address, @@ -95,65 +123,147 @@ module minitia_std::cosmos { type_args: vector, args: vector ) { - move_execute_internal( - signer::address_of(sender), - module_address, - *string::bytes(&module_name), - *string::bytes(&function_name), - vector::map_ref(&type_args, |v| *string::bytes(v)), - vector::map_ref(&args, |v| *string::bytes(v)), - true + stargate( + sender, + json::marshal( + &ExecuteJSONRequest { + _type_: string::utf8(b"/initia.move.v1.MsgExecuteJSON"), + sender: address::to_sdk(signer::address_of(sender)), + module_address, + module_name, + function_name, + type_args, + args + } + ) ) } + struct ScriptRequest has copy, drop { + _type_: String, + sender: String, + code_bytes: vector, + type_args: vector, + args: vector> + } + public entry fun move_script( sender: &signer, code_bytes: vector, type_args: vector, args: vector> ) { - move_script_internal( - signer::address_of(sender), - code_bytes, - vector::map_ref(&type_args, |v| *string::bytes(v)), - args, - false + stargate( + sender, + json::marshal( + &ScriptRequest { + _type_: string::utf8(b"/initia.move.v1.MsgScript"), + sender: address::to_sdk(signer::address_of(sender)), + code_bytes, + type_args, + args + } + ) ) } + struct ScriptJSONRequest has copy, drop { + _type_: String, + sender: String, + code_bytes: vector, + type_args: vector, + args: vector + } + public entry fun move_script_with_json( sender: &signer, code_bytes: vector, type_args: vector, args: vector ) { - move_script_internal( - signer::address_of(sender), - code_bytes, - vector::map_ref(&type_args, |v| *string::bytes(v)), - vector::map_ref(&args, |v| *string::bytes(v)), - true + stargate( + sender, + json::marshal( + &ScriptJSONRequest { + _type_: string::utf8(b"/initia.move.v1.MsgScriptJSON"), + sender: address::to_sdk(signer::address_of(sender)), + code_bytes, + type_args, + args + } + ) ) } + struct DelegateRequest has copy, drop { + _type_: String, + delegator_address: String, + validator_address: String, + amount: vector + } + + struct CosmosCoin has copy, drop { + denom: String, + amount: u64 + } + public entry fun delegate( delegator: &signer, validator: String, metadata: Object, amount: u64 ) { - delegate_internal( - signer::address_of(delegator), - *string::bytes(&validator), - &metadata, - amount + stargate( + delegator, + json::marshal( + &DelegateRequest { + _type_: string::utf8(b"/initia.mstaking.v1.MsgDelegate"), + delegator_address: address::to_sdk(signer::address_of(delegator)), + validator_address: validator, + amount: vector[CosmosCoin { denom: metadata_to_denom(metadata), amount }] + } + ) ) } + struct FuncCommunityPoolRequest has copy, drop { + _type_: String, + depositor: String, + amount: vector + } + public entry fun fund_community_pool( sender: &signer, metadata: Object, amount: u64 ) { - fund_community_pool_internal(signer::address_of(sender), &metadata, amount) + stargate( + sender, + json::marshal( + &FuncCommunityPoolRequest { + _type_: string::utf8( + b"/cosmos.distribution.v1beta1.MsgFundCommunityPool" + ), + depositor: address::to_sdk(signer::address_of(sender)), + amount: vector[CosmosCoin { denom: metadata_to_denom(metadata), amount }] + } + ) + ) + } + + struct TransferRequest has copy, drop { + _type_: String, + source_port: String, + source_channel: String, + sender: String, + receiver: String, + token: CosmosCoin, + timeout_height: TimeoutHeight, + timeout_timestamp: u64, + memo: String + } + + struct TimeoutHeight has copy, drop { + revision_number: u64, + revision_height: u64 } /// ICS20 ibc transfer @@ -170,20 +280,40 @@ module minitia_std::cosmos { timeout_timestamp: u64, memo: String ) { - transfer_internal( - signer::address_of(sender), - *string::bytes(&receiver), - &metadata, - token_amount, - *string::bytes(&source_port), - *string::bytes(&source_channel), - revision_number, - revision_height, - timeout_timestamp, - *string::bytes(&memo) + stargate( + sender, + json::marshal( + &TransferRequest { + _type_: string::utf8(b"/ibc.applications.transfer.v1.MsgTransfer"), + source_port, + source_channel, + sender: address::to_sdk(signer::address_of(sender)), + receiver, + token: CosmosCoin { + denom: metadata_to_denom(metadata), + amount: token_amount + }, + timeout_height: TimeoutHeight { revision_number, revision_height }, + timeout_timestamp, + memo + } + ) ) } + struct NFTTransferRequest has copy, drop { + _type_: String, + sender: String, + receiver: String, + class_id: String, + token_ids: vector, + source_port: String, + source_channel: String, + timeout_height: TimeoutHeight, + timeout_timestamp: u64, + memo: String + } + /// ICS721 ibc nft_transfer /// https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer public entry fun nft_transfer( @@ -198,20 +328,40 @@ module minitia_std::cosmos { timeout_timestamp: u64, memo: String ) { - nft_transfer_internal( - signer::address_of(sender), - *string::bytes(&receiver), - &collection, - vector::map_ref(&token_ids, |v| *string::bytes(v)), - *string::bytes(&source_port), - *string::bytes(&source_channel), - revision_number, - revision_height, - timeout_timestamp, - *string::bytes(&memo) + stargate( + sender, + json::marshal( + &NFTTransferRequest { + _type_: string::utf8(b"/ibc.applications.nft_transfer.v1.MsgTransfer"), + sender: address::to_sdk(signer::address_of(sender)), + receiver, + class_id: collection_to_class_id(collection), + token_ids, + source_port, + source_channel, + timeout_height: TimeoutHeight { revision_number, revision_height }, + timeout_timestamp, + memo + } + ) ) } + struct Fee has copy, drop { + recv_fee: vector, + ack_fee: vector, + timeout_fee: vector + } + + struct PayFeeRequest has copy, drop { + _type_: String, + _signer_: String, + source_port: String, + source_channel: String, + fee: Fee, + relayers: vector + } + /// ICS29 ibc relayer fee /// https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment public entry fun pay_fee( @@ -225,16 +375,37 @@ module minitia_std::cosmos { timeout_fee_metadata: Object, timeout_fee_amount: u64 ) { - pay_fee_internal( - signer::address_of(sender), - *string::bytes(&source_port), - *string::bytes(&source_channel), - &recv_fee_metadata, - recv_fee_amount, - &ack_fee_metadata, - ack_fee_amount, - &timeout_fee_metadata, - timeout_fee_amount + stargate( + sender, + json::marshal( + &PayFeeRequest { + _type_: string::utf8(b"/ibc.applications.fee.v1.MsgPayPacketFee"), + _signer_: address::to_sdk(signer::address_of(sender)), + source_port, + source_channel, + fee: Fee { + recv_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(recv_fee_metadata), + amount: recv_fee_amount + } + ], + ack_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(ack_fee_metadata), + amount: ack_fee_amount + } + ], + timeout_fee: vector[ + CosmosCoin { + denom: metadata_to_denom(timeout_fee_metadata), + amount: timeout_fee_amount + } + ] + }, + relayers: vector::empty() + } + ) ) } @@ -242,72 +413,14 @@ module minitia_std::cosmos { sender: address, data: vector, option: Options ); - native fun move_execute_internal( - sender: address, - module_address: address, - module_name: vector, - function_name: vector, - type_args: vector>, - args: vector>, - is_json: bool - ); - - native fun move_script_internal( - sender: address, - code_bytes: vector, - type_args: vector>, - args: vector>, - is_json: bool - ); - - native fun delegate_internal( - delegator: address, - validator: vector, - metadata: &Object, - amount: u64 - ); - - native fun fund_community_pool_internal( - sender: address, metadata: &Object, amount: u64 - ); - - native fun transfer_internal( - sender: address, - receiver: vector, - metadata: &Object, - token_amount: u64, - source_port: vector, - source_channel: vector, - revision_number: u64, - revision_height: u64, - timeout_timestamp: u64, - memo: vector - ); - - native fun nft_transfer_internal( - sender: address, - receiver: vector, - collection: &Object, - token_ids: vector>, - source_port: vector, - source_channel: vector, - revision_number: u64, - revision_height: u64, - timeout_timestamp: u64, - memo: vector - ); + #[test_only] + native public fun requested_messages(): vector; - native fun pay_fee_internal( - sender: address, - source_port: vector, - source_channel: vector, - recv_fee_metadata: &Object, - recv_fee_amount: u64, - ack_fee_metadata: &Object, - ack_fee_amount: u64, - timeout_fee_metadata: &Object, - timeout_fee_amount: u64 - ); + #[test_only] + public fun was_message_requested(msg: &String): bool { + use std::vector; + vector::contains(&requested_messages(), msg) + } // ================================================== Options ================================================= @@ -374,4 +487,30 @@ module minitia_std::cosmos { callback_fid: *string::bytes(&fid) } } + + //=========================================== Tests =========================================== + + #[test(sender = @0xcafe)] + public fun test_stargate_vote(sender: &signer) { + use std::string::utf8; + + let voter = utf8(b"voter"); + let proposal_id = 1; + let option = 1; + let metadata = utf8(b"metadata"); + stargate_vote(sender, proposal_id, voter, option, metadata); + + let msg = + json::marshal_to_string( + &VoteRequest { + _type_: utf8(b"/cosmos.gov.v1.MsgVote"), + proposal_id, + voter: voter, + option, + metadata: metadata + } + ); + + assert!(was_message_requested(&msg), 1); + } } diff --git a/precompile/modules/minitia_stdlib/sources/json.move b/precompile/modules/minitia_stdlib/sources/json.move index 932906b1..2bc9db6b 100644 --- a/precompile/modules/minitia_stdlib/sources/json.move +++ b/precompile/modules/minitia_stdlib/sources/json.move @@ -87,6 +87,7 @@ module minitia_std::json { /// /// NOTE: key `_type_` is converted to `@type` /// NOTE: key `_move_` is converted to `move` + /// NOTE: key `_signer_` is converted to `signer` public fun marshal(value: &T): vector { marshal_internal(value) } @@ -95,6 +96,7 @@ module minitia_std::json { /// /// NOTE: key `_type_` is converted to `@type` /// NOTE: key `_move_` is converted to `move` + /// /// NOTE: key `_signer_` is converted to `signer` public fun marshal_to_string(value: &T): String { marshal_to_string_internal(value) } @@ -103,6 +105,7 @@ module minitia_std::json { /// /// NOTE: key `@type` is converted to `_type_` /// NOTE: key `move` is converted to `_move_` + /// NOTE: key `signer` is converted to `_signer_` public fun unmarshal(json: vector): T { unmarshal_internal(json) } @@ -127,6 +130,7 @@ module minitia_std::json { f: Option, _type_: String, _move_: String, + _signer_: String, biguint: BigUint, bigdecimal: BigDecimal } @@ -179,6 +183,7 @@ module minitia_std::json { f: option::none(), _type_: string::utf8(b"/cosmos.gov.v1.MsgVote"), _move_: string::utf8(b"move"), + _signer_: string::utf8(b"signer"), biguint: biguint::from_u64(42), bigdecimal: bigdecimal::from_ratio_u64(123, 10000) }; @@ -186,7 +191,7 @@ module minitia_std::json { let json = marshal(&obj); assert!( json - == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"010203\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\"}", + == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"010203\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\",\"signer\":\"signer\"}", 1 ); @@ -242,7 +247,7 @@ module minitia_std::json { let json5 = marshal(&json_obj); assert!( json5 - == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"hello\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\"}", + == b"{\"@type\":\"/cosmos.gov.v1.MsgVote\",\"a\":\"42\",\"b\":true,\"bigdecimal\":\"0.0123\",\"biguint\":\"42\",\"c\":\"hello\",\"d\":\"0x1\",\"e\":{\"a\":\"42\",\"b\":true,\"c\":\"010203\"},\"f\":null,\"move\":\"move\",\"signer\":\"signer\"}", 9 ); } diff --git a/precompile/modules/minitia_stdlib/sources/token/collection.move b/precompile/modules/minitia_stdlib/sources/token/collection.move index 9c38847e..a069604e 100644 --- a/precompile/modules/minitia_stdlib/sources/token/collection.move +++ b/precompile/modules/minitia_stdlib/sources/token/collection.move @@ -22,9 +22,11 @@ module minitia_std::collection { use std::signer; use std::string::{Self, String}; use std::vector; + use std::bcs; use minitia_std::event; use minitia_std::object::{Self, ConstructorRef, Object}; use minitia_std::table::{Self, Table}; + use minitia_std::hex; use minitia_std::royalty::{Self, Royalty}; @@ -387,6 +389,21 @@ module minitia_std::collection { borrow(collection).uri } + #[view] + public fun collection_to_class_id(collection: Object): String acquires Collection { + let col = borrow(collection); + if (col.creator == @minitia_std) { + return col.name + }; + + let metadata_addr = object::object_address(&collection); + let denom = string::utf8(b"move/"); + let addr_bytes = bcs::to_bytes(&metadata_addr); + let addr_string = hex::encode_to_string(&addr_bytes); + string::append(&mut denom, addr_string); + return denom + } + #[view] /// get nft list from collection /// if `start_after` is not none, seach nfts in range (start_after, ...] diff --git a/tools/generate-bcs-go/src/main.rs b/tools/generate-bcs-go/src/main.rs index 5875d9e0..5fcd8054 100644 --- a/tools/generate-bcs-go/src/main.rs +++ b/tools/generate-bcs-go/src/main.rs @@ -10,9 +10,7 @@ use initia_move_types::{ CompilerCoverageSourceOptions, CompilerCoverageSummaryOptions, CompilerDocgenOptions, CompilerTestOptions, }, - cosmos::{ - CosmosCoin, CosmosMessage, IBCFee, IBCHeight, IBCMessage, MoveMessage, StakingMessage, - }, + cosmos::CosmosMessage, entry_function::EntryFunction, env::Env, gas_usage::GasUsage, @@ -39,12 +37,6 @@ fn main() { tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); - tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); diff --git a/types/bcs.go b/types/bcs.go index e7945855..d54f681e 100644 --- a/types/bcs.go +++ b/types/bcs.go @@ -458,20 +458,24 @@ func BcsDeserializeCompilerTestOptions(input []byte) (CompilerTestOptions, error return obj, err } -type CosmosCoin struct { - Metadata AccountAddress - Amount uint64 +type CosmosCallback struct { + Id uint64 + ModuleAddress AccountAddress + ModuleName string + FunctionName string } -func (obj *CosmosCoin) Serialize(serializer serde.Serializer) error { +func (obj *CosmosCallback) Serialize(serializer serde.Serializer) error { if err := serializer.IncreaseContainerDepth(); err != nil { return err } - if err := obj.Metadata.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeU64(obj.Amount); err != nil { return err } + if err := serializer.SerializeU64(obj.Id); err != nil { return err } + if err := obj.ModuleAddress.Serialize(serializer); err != nil { return err } + if err := serializer.SerializeStr(obj.ModuleName); err != nil { return err } + if err := serializer.SerializeStr(obj.FunctionName); err != nil { return err } serializer.DecreaseContainerDepth() return nil } -func (obj *CosmosCoin) BcsSerialize() ([]byte, error) { +func (obj *CosmosCallback) BcsSerialize() ([]byte, error) { if obj == nil { return nil, fmt.Errorf("Cannot serialize null object") } @@ -480,231 +484,48 @@ func (obj *CosmosCoin) BcsSerialize() ([]byte, error) { return serializer.GetBytes(), nil } -func DeserializeCosmosCoin(deserializer serde.Deserializer) (CosmosCoin, error) { - var obj CosmosCoin +func DeserializeCosmosCallback(deserializer serde.Deserializer) (CosmosCallback, error) { + var obj CosmosCallback if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Metadata = val } else { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.Amount = val } else { return obj, err } + if val, err := deserializer.DeserializeU64(); err == nil { obj.Id = val } else { return obj, err } + if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.ModuleAddress = val } else { return obj, err } + if val, err := deserializer.DeserializeStr(); err == nil { obj.ModuleName = val } else { return obj, err } + if val, err := deserializer.DeserializeStr(); err == nil { obj.FunctionName = val } else { return obj, err } deserializer.DecreaseContainerDepth() return obj, nil } -func BcsDeserializeCosmosCoin(input []byte) (CosmosCoin, error) { - if input == nil { - var obj CosmosCoin - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeCosmosCoin(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type CosmosMessage interface { - isCosmosMessage() - Serialize(serializer serde.Serializer) error - BcsSerialize() ([]byte, error) -} - -func DeserializeCosmosMessage(deserializer serde.Deserializer) (CosmosMessage, error) { - index, err := deserializer.DeserializeVariantIndex() - if err != nil { return nil, err } - - switch index { - case 0: - if val, err := load_CosmosMessage__Move(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 1: - if val, err := load_CosmosMessage__Staking(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 2: - if val, err := load_CosmosMessage__Distribution(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 3: - if val, err := load_CosmosMessage__Ibc(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 4: - if val, err := load_CosmosMessage__Stargate(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - default: - return nil, fmt.Errorf("Unknown variant index for CosmosMessage: %d", index) - } -} - -func BcsDeserializeCosmosMessage(input []byte) (CosmosMessage, error) { +func BcsDeserializeCosmosCallback(input []byte) (CosmosCallback, error) { if input == nil { - var obj CosmosMessage + var obj CosmosCallback return obj, fmt.Errorf("Cannot deserialize null array") } deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeCosmosMessage(deserializer) + obj, err := DeserializeCosmosCallback(deserializer) if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { return obj, fmt.Errorf("Some input bytes were not read") } return obj, err } -type CosmosMessage__Move struct { - Value MoveMessage -} - -func (*CosmosMessage__Move) isCosmosMessage() {} - -func (obj *CosmosMessage__Move) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(0) - if err := obj.Value.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *CosmosMessage__Move) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_CosmosMessage__Move(deserializer serde.Deserializer) (CosmosMessage__Move, error) { - var obj CosmosMessage__Move - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeMoveMessage(deserializer); err == nil { obj.Value = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type CosmosMessage__Staking struct { - Value StakingMessage -} - -func (*CosmosMessage__Staking) isCosmosMessage() {} - -func (obj *CosmosMessage__Staking) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(1) - if err := obj.Value.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *CosmosMessage__Staking) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_CosmosMessage__Staking(deserializer serde.Deserializer) (CosmosMessage__Staking, error) { - var obj CosmosMessage__Staking - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeStakingMessage(deserializer); err == nil { obj.Value = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type CosmosMessage__Distribution struct { - Value DistributionMessage -} - -func (*CosmosMessage__Distribution) isCosmosMessage() {} - -func (obj *CosmosMessage__Distribution) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(2) - if err := obj.Value.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *CosmosMessage__Distribution) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_CosmosMessage__Distribution(deserializer serde.Deserializer) (CosmosMessage__Distribution, error) { - var obj CosmosMessage__Distribution - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeDistributionMessage(deserializer); err == nil { obj.Value = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type CosmosMessage__Ibc struct { - Value IBCMessage -} - -func (*CosmosMessage__Ibc) isCosmosMessage() {} - -func (obj *CosmosMessage__Ibc) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(3) - if err := obj.Value.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *CosmosMessage__Ibc) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_CosmosMessage__Ibc(deserializer serde.Deserializer) (CosmosMessage__Ibc, error) { - var obj CosmosMessage__Ibc - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeIBCMessage(deserializer); err == nil { obj.Value = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type CosmosMessage__Stargate struct { - Value StargateMessage +type CosmosMessage struct { + Sender AccountAddress + Data []uint8 + AllowFailure bool + Callback *CosmosCallback } -func (*CosmosMessage__Stargate) isCosmosMessage() {} - -func (obj *CosmosMessage__Stargate) Serialize(serializer serde.Serializer) error { +func (obj *CosmosMessage) Serialize(serializer serde.Serializer) error { if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(4) - if err := obj.Value.Serialize(serializer); err != nil { return err } + if err := obj.Sender.Serialize(serializer); err != nil { return err } + if err := serialize_vector_u8(obj.Data, serializer); err != nil { return err } + if err := serializer.SerializeBool(obj.AllowFailure); err != nil { return err } + if err := serialize_option_CosmosCallback(obj.Callback, serializer); err != nil { return err } serializer.DecreaseContainerDepth() return nil } -func (obj *CosmosMessage__Stargate) BcsSerialize() ([]byte, error) { +func (obj *CosmosMessage) BcsSerialize() ([]byte, error) { if obj == nil { return nil, fmt.Errorf("Cannot serialize null object") } @@ -713,84 +534,30 @@ func (obj *CosmosMessage__Stargate) BcsSerialize() ([]byte, error) { return serializer.GetBytes(), nil } -func load_CosmosMessage__Stargate(deserializer serde.Deserializer) (CosmosMessage__Stargate, error) { - var obj CosmosMessage__Stargate +func DeserializeCosmosMessage(deserializer serde.Deserializer) (CosmosMessage, error) { + var obj CosmosMessage if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeStargateMessage(deserializer); err == nil { obj.Value = val } else { return obj, err } + if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } + if val, err := deserialize_vector_u8(deserializer); err == nil { obj.Data = val } else { return obj, err } + if val, err := deserializer.DeserializeBool(); err == nil { obj.AllowFailure = val } else { return obj, err } + if val, err := deserialize_option_CosmosCallback(deserializer); err == nil { obj.Callback = val } else { return obj, err } deserializer.DecreaseContainerDepth() return obj, nil } -type DistributionMessage interface { - isDistributionMessage() - Serialize(serializer serde.Serializer) error - BcsSerialize() ([]byte, error) -} - -func DeserializeDistributionMessage(deserializer serde.Deserializer) (DistributionMessage, error) { - index, err := deserializer.DeserializeVariantIndex() - if err != nil { return nil, err } - - switch index { - case 0: - if val, err := load_DistributionMessage__FundCommunityPool(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - default: - return nil, fmt.Errorf("Unknown variant index for DistributionMessage: %d", index) - } -} - -func BcsDeserializeDistributionMessage(input []byte) (DistributionMessage, error) { +func BcsDeserializeCosmosMessage(input []byte) (CosmosMessage, error) { if input == nil { - var obj DistributionMessage + var obj CosmosMessage return obj, fmt.Errorf("Cannot deserialize null array") } deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeDistributionMessage(deserializer) + obj, err := DeserializeCosmosMessage(deserializer) if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { return obj, fmt.Errorf("Some input bytes were not read") } return obj, err } -type DistributionMessage__FundCommunityPool struct { - SenderAddress AccountAddress - Amount CosmosCoin -} - -func (*DistributionMessage__FundCommunityPool) isDistributionMessage() {} - -func (obj *DistributionMessage__FundCommunityPool) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(0) - if err := obj.SenderAddress.Serialize(serializer); err != nil { return err } - if err := obj.Amount.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *DistributionMessage__FundCommunityPool) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_DistributionMessage__FundCommunityPool(deserializer serde.Deserializer) (DistributionMessage__FundCommunityPool, error) { - var obj DistributionMessage__FundCommunityPool - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.SenderAddress = val } else { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.Amount = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - type EntryFunction struct { Module ModuleId Function Identifier @@ -994,294 +761,6 @@ func BcsDeserializeGasUsage(input []byte) (GasUsage, error) { return obj, err } -type IBCFee struct { - RecvFee CosmosCoin - AckFee CosmosCoin - TimeoutFee CosmosCoin -} - -func (obj *IBCFee) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - if err := obj.RecvFee.Serialize(serializer); err != nil { return err } - if err := obj.AckFee.Serialize(serializer); err != nil { return err } - if err := obj.TimeoutFee.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *IBCFee) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func DeserializeIBCFee(deserializer serde.Deserializer) (IBCFee, error) { - var obj IBCFee - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.RecvFee = val } else { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.AckFee = val } else { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.TimeoutFee = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -func BcsDeserializeIBCFee(input []byte) (IBCFee, error) { - if input == nil { - var obj IBCFee - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeIBCFee(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type IBCHeight struct { - RevisionNumber uint64 - RevisionHeight uint64 -} - -func (obj *IBCHeight) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - if err := serializer.SerializeU64(obj.RevisionNumber); err != nil { return err } - if err := serializer.SerializeU64(obj.RevisionHeight); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *IBCHeight) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func DeserializeIBCHeight(deserializer serde.Deserializer) (IBCHeight, error) { - var obj IBCHeight - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.RevisionNumber = val } else { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.RevisionHeight = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -func BcsDeserializeIBCHeight(input []byte) (IBCHeight, error) { - if input == nil { - var obj IBCHeight - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeIBCHeight(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type IBCMessage interface { - isIBCMessage() - Serialize(serializer serde.Serializer) error - BcsSerialize() ([]byte, error) -} - -func DeserializeIBCMessage(deserializer serde.Deserializer) (IBCMessage, error) { - index, err := deserializer.DeserializeVariantIndex() - if err != nil { return nil, err } - - switch index { - case 0: - if val, err := load_IBCMessage__Transfer(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 1: - if val, err := load_IBCMessage__NftTransfer(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 2: - if val, err := load_IBCMessage__PayFee(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - default: - return nil, fmt.Errorf("Unknown variant index for IBCMessage: %d", index) - } -} - -func BcsDeserializeIBCMessage(input []byte) (IBCMessage, error) { - if input == nil { - var obj IBCMessage - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeIBCMessage(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type IBCMessage__Transfer struct { - SourcePort string - SourceChannel string - Token CosmosCoin - Sender AccountAddress - Receiver string - TimeoutHeight IBCHeight - TimeoutTimestamp uint64 - Memo string -} - -func (*IBCMessage__Transfer) isIBCMessage() {} - -func (obj *IBCMessage__Transfer) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(0) - if err := serializer.SerializeStr(obj.SourcePort); err != nil { return err } - if err := serializer.SerializeStr(obj.SourceChannel); err != nil { return err } - if err := obj.Token.Serialize(serializer); err != nil { return err } - if err := obj.Sender.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.Receiver); err != nil { return err } - if err := obj.TimeoutHeight.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeU64(obj.TimeoutTimestamp); err != nil { return err } - if err := serializer.SerializeStr(obj.Memo); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *IBCMessage__Transfer) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_IBCMessage__Transfer(deserializer serde.Deserializer) (IBCMessage__Transfer, error) { - var obj IBCMessage__Transfer - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourcePort = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourceChannel = val } else { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.Token = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.Receiver = val } else { return obj, err } - if val, err := DeserializeIBCHeight(deserializer); err == nil { obj.TimeoutHeight = val } else { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.TimeoutTimestamp = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.Memo = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type IBCMessage__NftTransfer struct { - SourcePort string - SourceChannel string - Collection AccountAddress - TokenIds []string - Sender AccountAddress - Receiver string - TimeoutHeight IBCHeight - TimeoutTimestamp uint64 - Memo string -} - -func (*IBCMessage__NftTransfer) isIBCMessage() {} - -func (obj *IBCMessage__NftTransfer) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(1) - if err := serializer.SerializeStr(obj.SourcePort); err != nil { return err } - if err := serializer.SerializeStr(obj.SourceChannel); err != nil { return err } - if err := obj.Collection.Serialize(serializer); err != nil { return err } - if err := serialize_vector_str(obj.TokenIds, serializer); err != nil { return err } - if err := obj.Sender.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.Receiver); err != nil { return err } - if err := obj.TimeoutHeight.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeU64(obj.TimeoutTimestamp); err != nil { return err } - if err := serializer.SerializeStr(obj.Memo); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *IBCMessage__NftTransfer) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_IBCMessage__NftTransfer(deserializer serde.Deserializer) (IBCMessage__NftTransfer, error) { - var obj IBCMessage__NftTransfer - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourcePort = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourceChannel = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Collection = val } else { return obj, err } - if val, err := deserialize_vector_str(deserializer); err == nil { obj.TokenIds = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.Receiver = val } else { return obj, err } - if val, err := DeserializeIBCHeight(deserializer); err == nil { obj.TimeoutHeight = val } else { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.TimeoutTimestamp = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.Memo = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type IBCMessage__PayFee struct { - Fee IBCFee - SourcePort string - SourceChannel string - Signer AccountAddress -} - -func (*IBCMessage__PayFee) isIBCMessage() {} - -func (obj *IBCMessage__PayFee) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(2) - if err := obj.Fee.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.SourcePort); err != nil { return err } - if err := serializer.SerializeStr(obj.SourceChannel); err != nil { return err } - if err := obj.Signer.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *IBCMessage__PayFee) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_IBCMessage__PayFee(deserializer serde.Deserializer) (IBCMessage__PayFee, error) { - var obj IBCMessage__PayFee - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeIBCFee(deserializer); err == nil { obj.Fee = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourcePort = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.SourceChannel = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Signer = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - type Identifier string func (obj *Identifier) Serialize(serializer serde.Serializer) error { @@ -1538,141 +1017,6 @@ func BcsDeserializeModuleId(input []byte) (ModuleId, error) { return obj, err } -type MoveMessage interface { - isMoveMessage() - Serialize(serializer serde.Serializer) error - BcsSerialize() ([]byte, error) -} - -func DeserializeMoveMessage(deserializer serde.Deserializer) (MoveMessage, error) { - index, err := deserializer.DeserializeVariantIndex() - if err != nil { return nil, err } - - switch index { - case 0: - if val, err := load_MoveMessage__Execute(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - case 1: - if val, err := load_MoveMessage__Script(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - default: - return nil, fmt.Errorf("Unknown variant index for MoveMessage: %d", index) - } -} - -func BcsDeserializeMoveMessage(input []byte) (MoveMessage, error) { - if input == nil { - var obj MoveMessage - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeMoveMessage(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type MoveMessage__Execute struct { - Sender AccountAddress - ModuleAddress AccountAddress - ModuleName string - FunctionName string - TypeArgs []string - Args [][]uint8 - IsJson bool -} - -func (*MoveMessage__Execute) isMoveMessage() {} - -func (obj *MoveMessage__Execute) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(0) - if err := obj.Sender.Serialize(serializer); err != nil { return err } - if err := obj.ModuleAddress.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.ModuleName); err != nil { return err } - if err := serializer.SerializeStr(obj.FunctionName); err != nil { return err } - if err := serialize_vector_str(obj.TypeArgs, serializer); err != nil { return err } - if err := serialize_vector_vector_u8(obj.Args, serializer); err != nil { return err } - if err := serializer.SerializeBool(obj.IsJson); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *MoveMessage__Execute) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_MoveMessage__Execute(deserializer serde.Deserializer) (MoveMessage__Execute, error) { - var obj MoveMessage__Execute - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.ModuleAddress = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.ModuleName = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.FunctionName = val } else { return obj, err } - if val, err := deserialize_vector_str(deserializer); err == nil { obj.TypeArgs = val } else { return obj, err } - if val, err := deserialize_vector_vector_u8(deserializer); err == nil { obj.Args = val } else { return obj, err } - if val, err := deserializer.DeserializeBool(); err == nil { obj.IsJson = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type MoveMessage__Script struct { - Sender AccountAddress - CodeBytes []uint8 - TypeArgs []string - Args [][]uint8 - IsJson bool -} - -func (*MoveMessage__Script) isMoveMessage() {} - -func (obj *MoveMessage__Script) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(1) - if err := obj.Sender.Serialize(serializer); err != nil { return err } - if err := serialize_vector_u8(obj.CodeBytes, serializer); err != nil { return err } - if err := serialize_vector_str(obj.TypeArgs, serializer); err != nil { return err } - if err := serialize_vector_vector_u8(obj.Args, serializer); err != nil { return err } - if err := serializer.SerializeBool(obj.IsJson); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *MoveMessage__Script) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_MoveMessage__Script(deserializer serde.Deserializer) (MoveMessage__Script, error) { - var obj MoveMessage__Script - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } - if val, err := deserialize_vector_u8(deserializer); err == nil { obj.CodeBytes = val } else { return obj, err } - if val, err := deserialize_vector_str(deserializer); err == nil { obj.TypeArgs = val } else { return obj, err } - if val, err := deserialize_vector_vector_u8(deserializer); err == nil { obj.Args = val } else { return obj, err } - if val, err := deserializer.DeserializeBool(); err == nil { obj.IsJson = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - type ResourceKey struct { Address AccountAddress Type StructTag @@ -1817,179 +1161,6 @@ func BcsDeserializeStakingDelta(input []byte) (StakingDelta, error) { return obj, err } -type StakingMessage interface { - isStakingMessage() - Serialize(serializer serde.Serializer) error - BcsSerialize() ([]byte, error) -} - -func DeserializeStakingMessage(deserializer serde.Deserializer) (StakingMessage, error) { - index, err := deserializer.DeserializeVariantIndex() - if err != nil { return nil, err } - - switch index { - case 0: - if val, err := load_StakingMessage__Delegate(deserializer); err == nil { - return &val, nil - } else { - return nil, err - } - - default: - return nil, fmt.Errorf("Unknown variant index for StakingMessage: %d", index) - } -} - -func BcsDeserializeStakingMessage(input []byte) (StakingMessage, error) { - if input == nil { - var obj StakingMessage - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeStakingMessage(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type StakingMessage__Delegate struct { - DelegatorAddress AccountAddress - ValidatorAddress string - Amount CosmosCoin -} - -func (*StakingMessage__Delegate) isStakingMessage() {} - -func (obj *StakingMessage__Delegate) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - serializer.SerializeVariantIndex(0) - if err := obj.DelegatorAddress.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.ValidatorAddress); err != nil { return err } - if err := obj.Amount.Serialize(serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *StakingMessage__Delegate) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func load_StakingMessage__Delegate(deserializer serde.Deserializer) (StakingMessage__Delegate, error) { - var obj StakingMessage__Delegate - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.DelegatorAddress = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.ValidatorAddress = val } else { return obj, err } - if val, err := DeserializeCosmosCoin(deserializer); err == nil { obj.Amount = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -type StargateCallback struct { - Id uint64 - ModuleAddress AccountAddress - ModuleName string - FunctionName string -} - -func (obj *StargateCallback) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - if err := serializer.SerializeU64(obj.Id); err != nil { return err } - if err := obj.ModuleAddress.Serialize(serializer); err != nil { return err } - if err := serializer.SerializeStr(obj.ModuleName); err != nil { return err } - if err := serializer.SerializeStr(obj.FunctionName); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *StargateCallback) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func DeserializeStargateCallback(deserializer serde.Deserializer) (StargateCallback, error) { - var obj StargateCallback - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := deserializer.DeserializeU64(); err == nil { obj.Id = val } else { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.ModuleAddress = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.ModuleName = val } else { return obj, err } - if val, err := deserializer.DeserializeStr(); err == nil { obj.FunctionName = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -func BcsDeserializeStargateCallback(input []byte) (StargateCallback, error) { - if input == nil { - var obj StargateCallback - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeStargateCallback(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - -type StargateMessage struct { - Sender AccountAddress - Data []uint8 - AllowFailure bool - Callback *StargateCallback -} - -func (obj *StargateMessage) Serialize(serializer serde.Serializer) error { - if err := serializer.IncreaseContainerDepth(); err != nil { return err } - if err := obj.Sender.Serialize(serializer); err != nil { return err } - if err := serialize_vector_u8(obj.Data, serializer); err != nil { return err } - if err := serializer.SerializeBool(obj.AllowFailure); err != nil { return err } - if err := serialize_option_StargateCallback(obj.Callback, serializer); err != nil { return err } - serializer.DecreaseContainerDepth() - return nil -} - -func (obj *StargateMessage) BcsSerialize() ([]byte, error) { - if obj == nil { - return nil, fmt.Errorf("Cannot serialize null object") - } - serializer := bcs.NewSerializer(); - if err := obj.Serialize(serializer); err != nil { return nil, err } - return serializer.GetBytes(), nil -} - -func DeserializeStargateMessage(deserializer serde.Deserializer) (StargateMessage, error) { - var obj StargateMessage - if err := deserializer.IncreaseContainerDepth(); err != nil { return obj, err } - if val, err := DeserializeAccountAddress(deserializer); err == nil { obj.Sender = val } else { return obj, err } - if val, err := deserialize_vector_u8(deserializer); err == nil { obj.Data = val } else { return obj, err } - if val, err := deserializer.DeserializeBool(); err == nil { obj.AllowFailure = val } else { return obj, err } - if val, err := deserialize_option_StargateCallback(deserializer); err == nil { obj.Callback = val } else { return obj, err } - deserializer.DecreaseContainerDepth() - return obj, nil -} - -func BcsDeserializeStargateMessage(input []byte) (StargateMessage, error) { - if input == nil { - var obj StargateMessage - return obj, fmt.Errorf("Cannot deserialize null array") - } - deserializer := bcs.NewDeserializer(input); - obj, err := DeserializeStargateMessage(deserializer) - if err == nil && deserializer.GetBufferOffset() < uint64(len(input)) { - return obj, fmt.Errorf("Some input bytes were not read") - } - return obj, err -} - type StructTag struct { Address AccountAddress Module Identifier @@ -2615,7 +1786,7 @@ func deserialize_array32_u8_array(deserializer serde.Deserializer) ([32]uint8, e return obj, nil } -func serialize_option_StargateCallback(value *StargateCallback, serializer serde.Serializer) error { +func serialize_option_CosmosCallback(value *CosmosCallback, serializer serde.Serializer) error { if value != nil { if err := serializer.SerializeOptionTag(true); err != nil { return err } if err := (*value).Serialize(serializer); err != nil { return err } @@ -2625,12 +1796,12 @@ func serialize_option_StargateCallback(value *StargateCallback, serializer serde return nil } -func deserialize_option_StargateCallback(deserializer serde.Deserializer) (*StargateCallback, error) { +func deserialize_option_CosmosCallback(deserializer serde.Deserializer) (*CosmosCallback, error) { tag, err := deserializer.DeserializeOptionTag() if err != nil { return nil, err } if tag { - value := new(StargateCallback) - if val, err := DeserializeStargateCallback(deserializer); err == nil { *value = val } else { return nil, err } + value := new(CosmosCallback) + if val, err := DeserializeCosmosCallback(deserializer); err == nil { *value = val } else { return nil, err } return value, nil } else { return nil, nil @@ -2816,24 +1987,6 @@ func deserialize_vector_bytes(deserializer serde.Deserializer) ([][]byte, error) return obj, nil } -func serialize_vector_str(value []string, serializer serde.Serializer) error { - if err := serializer.SerializeLen(uint64(len(value))); err != nil { return err } - for _, item := range(value) { - if err := serializer.SerializeStr(item); err != nil { return err } - } - return nil -} - -func deserialize_vector_str(deserializer serde.Deserializer) ([]string, error) { - length, err := deserializer.DeserializeLen() - if err != nil { return nil, err } - obj := make([]string, length) - for i := range(obj) { - if val, err := deserializer.DeserializeStr(); err == nil { obj[i] = val } else { return nil, err } - } - return obj, nil -} - func serialize_vector_tuple2_str_AccountAddress(value []struct {Field0 string; Field1 AccountAddress}, serializer serde.Serializer) error { if err := serializer.SerializeLen(uint64(len(value))); err != nil { return err } for _, item := range(value) { @@ -2870,21 +2023,3 @@ func deserialize_vector_u8(deserializer serde.Deserializer) ([]uint8, error) { return obj, nil } -func serialize_vector_vector_u8(value [][]uint8, serializer serde.Serializer) error { - if err := serializer.SerializeLen(uint64(len(value))); err != nil { return err } - for _, item := range(value) { - if err := serialize_vector_u8(item, serializer); err != nil { return err } - } - return nil -} - -func deserialize_vector_vector_u8(deserializer serde.Deserializer) ([][]uint8, error) { - length, err := deserializer.DeserializeLen() - if err != nil { return nil, err } - obj := make([][]uint8, length) - for i := range(obj) { - if val, err := deserialize_vector_u8(deserializer); err == nil { obj[i] = val } else { return nil, err } - } - return obj, nil -} -