From 019a62b8421d071b75f70c0df8a23669b62b3f9a Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Tue, 8 Apr 2025 13:00:01 +0200 Subject: [PATCH 1/8] Add --all flag to the sweep address command --- .../src/command_handler/mod.rs | 15 +++++++++++++-- wallet/wallet-cli-commands/src/lib.rs | 4 ++++ wallet/wallet-controller/src/synced_controller.rs | 2 +- .../src/rpc_client/client_impl.rs | 2 ++ wallet/wallet-rpc-lib/src/rpc/interface.rs | 1 + wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 7 +++++++ wallet/wallet-rpc-lib/src/rpc/types.rs | 3 +++ 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index 93932291f4..18ffbc8342 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -31,7 +31,10 @@ use itertools::Itertools; use mempool::tx_options::TxOptionsOverrides; use node_comm::node_traits::NodeInterface; use serialization::{hex::HexEncode, hex_encoded::HexEncoded}; -use utils::qrcode::{QrCode, QrCodeError}; +use utils::{ + ensure, + qrcode::{QrCode, QrCodeError}, +}; use wallet::version::get_version; use wallet_controller::types::GenericTokenTransfer; use wallet_rpc_client::wallet_rpc_traits::{PartialOrSignedTx, WalletInterface}; @@ -166,7 +169,7 @@ where let msg = match response.mnemonic { MnemonicInfo::NewlyGenerated { mnemonic } => { format!( - "New wallet created successfully\nYour mnemonic: {}\ + "New wallet created successfully\nYour mnemonic: {}\n\ Please write it somewhere safe to be able to restore your wallet. \ It's recommended that you attempt to recover the wallet now as practice\ to check that you arrive at the same addresses, \ @@ -1356,7 +1359,15 @@ where WalletCommand::SweepFromAddress { destination_address, addresses, + all, } => { + // Clap should already prevent this + ensure!( + all && addresses.is_empty() || !all && !addresses.is_empty(), + WalletCliCommandError::::InvalidInput( + "Either set `--all` to sweep all addresses, or provide specific addresses — not both".to_owned() + ) + ); let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; let new_tx = wallet diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index 30199516ed..5cd8fa8bff 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -643,7 +643,11 @@ pub enum WalletCommand { /// The receiving address of the coins or tokens destination_address: String, /// The addresses to be swept + #[arg(required_unless_present("all"))] addresses: Vec, + /// Sweep all addresses + #[arg(long = "all", default_value_t = false, conflicts_with_all(["addresses"]))] + all: bool, }, #[clap(name = "staking-sweep-delegation")] diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index c0e04df284..54ffc1763a 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -584,7 +584,7 @@ where .into_iter() .filter(|(_, output)| { get_tx_output_destination(output, &|_| None, HtlcSpendingCondition::Skip) - .is_some_and(|dest| from_addresses.contains(&dest)) + .is_some_and(|dest| from_addresses.is_empty() || from_addresses.contains(&dest)) }) .collect::>(); diff --git a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs index 188d2d2368..559568cf3d 100644 --- a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs +++ b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs @@ -477,11 +477,13 @@ impl WalletInterface for ClientWalletRpc { config: ControllerConfig, ) -> Result { let options = TransactionOptions::from_controller_config(&config); + let all = from_addresses.is_empty(); WalletRpcClient::sweep_addresses( &self.http_client, account_index.into(), destination_address.into(), from_addresses.into_iter().map(Into::into).collect(), + Some(all), options, ) .await diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index 7bc3225aab..232aa2d82a 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -390,6 +390,7 @@ trait WalletRpc { account: AccountArg, destination_address: RpcAddress, from_addresses: Vec>, + all: Option, options: TransactionOptions, ) -> rpc::RpcResult; diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index db3965d79e..3204363628 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -29,6 +29,7 @@ use common::{ use crypto::{key::PrivateKey, vrf::VRFPublicKey}; use p2p_types::{bannable_address::BannableAddress, socket_address::SocketAddress, PeerId}; use serialization::{hex::HexEncode, json_encoded::JsonEncoded}; +use utils::ensure; use utils_networking::IpOrSocketAddress; use wallet::{account::TxInfo, version::get_version}; use wallet_controller::{ @@ -555,12 +556,18 @@ where account: AccountArg, destination_address: RpcAddress, from_addresses: Vec>, + all: Option, options: TransactionOptions, ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, }; + let all = all.unwrap_or(false); + ensure!( + all && from_addresses.is_empty() || !all && !from_addresses.is_empty(), + RpcError::::InvalidSweepParameters + ); rpc::handle_result( self.sweep_addresses( account.index::()?, diff --git a/wallet/wallet-rpc-lib/src/rpc/types.rs b/wallet/wallet-rpc-lib/src/rpc/types.rs index ba51f72b92..9c9344426d 100644 --- a/wallet/wallet-rpc-lib/src/rpc/types.rs +++ b/wallet/wallet-rpc-lib/src/rpc/types.rs @@ -162,6 +162,9 @@ pub enum RpcError { #[error("Invalid HTLC secret hash")] InvalidHtlcSecretHash, + + #[error("Either set `all` to sweep all addresses, or provide specific addresses — not both")] + InvalidSweepParameters, } impl From> for rpc::Error { From adc786735487dc551f5b7631197424f6d4564a44 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Wed, 9 Apr 2025 13:05:03 +0200 Subject: [PATCH 2/8] Return hex tx for all RPC related functions --- node-gui/backend/src/backend_impl.rs | 17 +- wallet/src/wallet/mod.rs | 115 +++--- wallet/src/wallet/tests.rs | 256 +++++++++---- wallet/types/src/lib.rs | 18 + .../src/command_handler/mod.rs | 52 ++- .../wallet-controller/src/runtime_wallet.rs | 44 +-- .../src/synced_controller.rs | 109 +++--- wallet/wallet-controller/src/types/mod.rs | 1 + .../src/types/transaction.rs | 7 + .../src/handles_client/mod.rs | 76 ++-- .../src/rpc_client/client_impl.rs | 61 ++-- .../src/wallet_rpc_traits.rs | 57 +-- wallet/wallet-rpc-daemon/docs/RPC.md | 343 +++++++++++++++++- wallet/wallet-rpc-lib/src/rpc/interface.rs | 60 +-- wallet/wallet-rpc-lib/src/rpc/mod.rs | 124 ++++--- wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 75 ++-- wallet/wallet-rpc-lib/src/rpc/types.rs | 87 ++++- wallet/wallet-rpc-lib/tests/basic.rs | 4 +- 18 files changed, 1041 insertions(+), 465 deletions(-) diff --git a/node-gui/backend/src/backend_impl.rs b/node-gui/backend/src/backend_impl.rs index 7c98d6fd26..00f20519b1 100644 --- a/node-gui/backend/src/backend_impl.rs +++ b/node-gui/backend/src/backend_impl.rs @@ -819,7 +819,8 @@ impl Backend { }, ) .await - .map_err(|e| BackendError::WalletError(e.to_string()))?; + .map_err(|e| BackendError::WalletError(e.to_string()))? + .tx; Ok(TransactionInfo { wallet_id, @@ -872,7 +873,8 @@ impl Backend { }, ) .await - .map_err(|e| BackendError::WalletError(e.to_string()))?; + .map_err(|e| BackendError::WalletError(e.to_string()))? + .tx; Ok(TransactionInfo { wallet_id, @@ -904,7 +906,8 @@ impl Backend { }, ) .await - .map_err(|e| BackendError::WalletError(e.to_string()))?; + .map_err(|e| BackendError::WalletError(e.to_string()))? + .tx; Ok(TransactionInfo { wallet_id, @@ -940,7 +943,7 @@ impl Backend { Ok(TransactionInfo { wallet_id, - tx: SignedTransactionWrapper::new(tx), + tx: SignedTransactionWrapper::new(tx.tx), }) } @@ -975,7 +978,8 @@ impl Backend { }, ) .await - .map_err(|e| BackendError::WalletError(e.to_string()))?; + .map_err(|e| BackendError::WalletError(e.to_string()))? + .tx; Ok(TransactionInfo { wallet_id, @@ -1018,7 +1022,8 @@ impl Backend { }, ) .await - .map_err(|e| BackendError::WalletError(e.to_string()))?; + .map_err(|e| BackendError::WalletError(e.to_string()))? + .tx; Ok(TransactionInfo { wallet_id, diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 9ef13f0fa6..2ec0507ee8 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -88,6 +88,7 @@ use wallet_types::wallet_type::{WalletControllerMode, WalletType}; use wallet_types::with_locked::WithLocked; use wallet_types::{ AccountId, AccountKeyPurposeId, BlockInfo, Currency, KeyPurpose, KeychainUsageState, + SignedTxWithFees, }; pub const WALLET_VERSION_UNINITIALIZED: u32 = 0; @@ -1127,14 +1128,14 @@ where &mut StoreTxRwUnlocked, ) -> WalletResult<(SendRequest, AddlData)>, error_mapper: impl FnOnce(WalletError) -> WalletError, - ) -> WalletResult<(SignedTransaction, AddlData)> { + ) -> WalletResult<(SignedTxWithFees, AddlData)> { let (_, block_height) = self.get_best_block_for_account(account_index)?; self.for_account_rw_unlocked( account_index, |account, db_tx, chain_config, signer_provider| { - let (request, additional_data) = f(account, db_tx)?; - + let (mut request, additional_data) = f(account, db_tx)?; + let fees = request.get_fees(); let ptx = request.into_partially_signed_tx(additional_info)?; let mut signer = @@ -1171,6 +1172,7 @@ where })?; check_transaction(chain_config, block_height.next_height(), &tx)?; + let tx = SignedTxWithFees { tx, fees }; Ok((tx, additional_data)) }, ) @@ -1182,6 +1184,23 @@ where additional_info: TxAdditionalInfo, f: impl FnOnce(&mut Account, &mut StoreTxRwUnlocked) -> WalletResult, ) -> WalletResult { + Ok(self + .for_account_rw_unlocked_and_check_tx_generic( + account_index, + additional_info, + |account, db_tx| Ok((f(account, db_tx)?, ())), + |err| err, + )? + .0 + .tx) + } + + fn for_account_rw_unlocked_and_check_tx_with_fees( + &mut self, + account_index: U31, + additional_info: TxAdditionalInfo, + f: impl FnOnce(&mut Account, &mut StoreTxRwUnlocked) -> WalletResult, + ) -> WalletResult { Ok(self .for_account_rw_unlocked_and_check_tx_generic( account_index, @@ -1531,7 +1550,7 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { Ok(self .create_transaction_to_addresses_impl( account_index, @@ -1559,7 +1578,7 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult<(SignedTransaction, SignedTransactionIntent)> { + ) -> WalletResult<(SignedTxWithFees, SignedTransactionIntent)> { let (signed_tx, input_destinations) = self.create_transaction_to_addresses_impl( account_index, outputs, @@ -1578,7 +1597,7 @@ where signer_provider.provide(Arc::new(chain_config.clone()), account_index); Ok(signer.sign_transaction_intent( - signed_tx.transaction(), + signed_tx.tx.transaction(), &input_destinations, &intent, account.key_chain(), @@ -1601,7 +1620,7 @@ where consolidate_fee_rate: FeeRate, additional_data_getter: impl Fn(&SendRequest) -> AddlData, additional_info: TxAdditionalInfo, - ) -> WalletResult<(SignedTransaction, AddlData)> { + ) -> WalletResult<(SignedTxWithFees, AddlData)> { let request = SendRequest::new().with_outputs(outputs); let latest_median_time = self.latest_median_time; self.for_account_rw_unlocked_and_check_tx_generic( @@ -1665,7 +1684,7 @@ where inputs: Vec<(UtxoOutPoint, TxOutput)>, current_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { let request = SendRequest::new().with_inputs( inputs .into_iter() @@ -1673,9 +1692,11 @@ where &|_| None, )?; - self.for_account_rw_unlocked_and_check_tx(account_index, additional_info, |account, _| { - account.sweep_addresses(destination, request, current_fee_rate) - }) + self.for_account_rw_unlocked_and_check_tx_with_fees( + account_index, + additional_info, + |account, _| account.sweep_addresses(destination, request, current_fee_rate), + ) } pub fn create_sweep_from_delegation_transaction( @@ -1685,8 +1706,8 @@ where delegation_id: DelegationId, delegation_share: Amount, current_fee_rate: FeeRate, - ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx( + ) -> WalletResult { + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, _| { @@ -1703,8 +1724,8 @@ where delegation_id: DelegationId, delegation_share: Amount, current_fee_rate: FeeRate, - ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx( + ) -> WalletResult { + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, _| { @@ -1727,10 +1748,10 @@ where destination: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1756,10 +1777,10 @@ where amount: Amount, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1783,10 +1804,10 @@ where token_info: &UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1810,10 +1831,10 @@ where is_token_unfreezable: IsTokenUnfreezable, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1837,10 +1858,10 @@ where token_info: &UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1864,10 +1885,10 @@ where address: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1892,10 +1913,10 @@ where metadata_uri: Vec, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -1936,7 +1957,7 @@ where outputs: Vec, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(DelegationId, SignedTransaction)> { + ) -> WalletResult<(DelegationId, SignedTxWithFees)> { let tx = self.create_transaction_to_addresses( account_index, outputs, @@ -1956,7 +1977,7 @@ where token_issuance: TokenIssuance, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(TokenId, SignedTransaction)> { + ) -> WalletResult<(TokenId, SignedTxWithFees)> { let outputs = make_issue_token_outputs(token_issuance, self.chain_config.as_ref())?; let tx = self.create_transaction_to_addresses( @@ -1983,11 +2004,11 @@ where metadata: Metadata, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(TokenId, SignedTransaction)> { + ) -> WalletResult<(TokenId, SignedTxWithFees)> { let destination = address.into_object(); let latest_median_time = self.latest_median_time; - let signed_transaction = self.for_account_rw_unlocked_and_check_tx( + let signed_transaction = self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, db_tx| { @@ -2020,9 +2041,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, stake_pool_arguments: StakePoolCreationArguments, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, db_tx| { @@ -2046,7 +2067,7 @@ where staker_balance: Amount, output_address: Option, current_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let additional_info = TxAdditionalInfo::with_pool_info(pool_id, PoolAdditionalInfo { staker_balance }); Ok(self @@ -2151,9 +2172,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult<(OrderId, SignedTransaction)> { + ) -> WalletResult<(OrderId, SignedTxWithFees)> { let latest_median_time = self.latest_median_time; - let tx = self.for_account_rw_unlocked_and_check_tx( + let tx = self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -2170,7 +2191,7 @@ where ) }, )?; - let order_id = make_order_id(tx.inputs())?; + let order_id = make_order_id(tx.tx.inputs())?; Ok((order_id, tx)) } @@ -2184,9 +2205,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -2216,9 +2237,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { @@ -2245,9 +2266,9 @@ where order_info: RpcOrderInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, db_tx| { @@ -2517,9 +2538,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, stake_pool_arguments: StakePoolCreationArguments, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, TxAdditionalInfo::new(), |account, db_tx| { diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index 9def037b31..1a67602877 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -1063,7 +1063,8 @@ fn wallet_accounts_creation() { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; // even with an unconfirmed transaction we cannot create a new account wallet.add_unconfirmed_tx(tx.clone(), &WalletEventsNoOp).unwrap(); @@ -1299,7 +1300,8 @@ fn wallet_get_transaction(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let tx_id = tx.transaction().get_id(); @@ -1359,7 +1361,8 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let send_tx_id = tx.transaction().get_id(); @@ -1382,7 +1385,8 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let spend_from_tx_id = tx.transaction().get_id(); let _ = create_block( @@ -1490,7 +1494,8 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let tx_size = serialization::Encode::encoded_size(&transaction); @@ -1546,7 +1551,8 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let tx_size = serialization::Encode::encoded_size(&transaction); let exact_fee = feerate.compute_fee(tx_size).unwrap(); @@ -1681,7 +1687,8 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; // check that we only have the selected_utxo as inputs assert_eq!(tx.inputs().len(), selected_utxos.len()); @@ -1790,7 +1797,8 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let stake_pool_transaction_id = stake_pool_transaction.transaction().get_id(); let (addr, block2) = create_block( &chain_config, @@ -1888,7 +1896,8 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -1999,7 +2008,8 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) vrf_public_key: Some(staker_vrf_public_key.clone()), }, ) - .unwrap(); + .unwrap() + .tx; let stake_pool_transaction_id = stake_pool_transaction.transaction().get_id(); let stake_pool_transaction2 = wallet1 @@ -2016,7 +2026,8 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) vrf_public_key: Some(staker_vrf_public_key.clone()), }, ) - .unwrap(); + .unwrap() + .tx; let stake_pool_transaction_id2 = stake_pool_transaction2.transaction().get_id(); assert_eq!(stake_pool_transaction_id, stake_pool_transaction_id2); @@ -2156,7 +2167,8 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) - .unwrap(); + .unwrap() + .tx; let (_, block4) = create_block( &chain_config, @@ -2296,6 +2308,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block_height = 2; @@ -2329,7 +2342,8 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let block_height = 3; let (_, block) = create_block( @@ -2369,6 +2383,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let _ = create_block( @@ -2429,7 +2444,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let (address, _) = create_block( &chain_config, @@ -2456,6 +2472,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let _ = create_block( @@ -2485,7 +2502,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -2504,7 +2522,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(2), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( @@ -2536,7 +2555,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(1), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( DEFAULT_ACCOUNT_INDEX, @@ -2607,7 +2627,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(1), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx(DEFAULT_ACCOUNT_INDEX, delegation_tx3, &WalletEventsNoOp) .unwrap(); @@ -2707,6 +2728,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let freezable = token_issuance.is_freezable.as_bool(); @@ -2752,7 +2774,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( DEFAULT_ACCOUNT_INDEX, @@ -2773,7 +2796,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; ( issued_token_id, @@ -2799,6 +2823,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); random_issuing_wallet .add_unconfirmed_tx(nft_issuance_transaction.clone(), &WalletEventsNoOp) @@ -2817,7 +2842,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; (issued_token_id, vec![nft_issuance_transaction, transfer_tx]) }; @@ -2870,7 +2896,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info.clone(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( DEFAULT_ACCOUNT_INDEX, @@ -2924,8 +2951,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .err() - .unwrap(); + .unwrap_err(); let remaining_tokens = (token_amount_to_issue - tokens_to_transfer).unwrap(); if remaining_tokens == Amount::ZERO { @@ -3042,6 +3068,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -3080,7 +3107,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block(&chain_config, &mut wallet, vec![mint_tx], block2_amount, 2); @@ -3096,7 +3124,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(freeze_tx.clone(), &WalletEventsNoOp).unwrap(); @@ -3124,7 +3153,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(unfreeze_tx.clone(), &WalletEventsNoOp).unwrap(); @@ -3195,7 +3225,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let tokens_to_transfer = Amount::from_atoms(rng.gen_range(1..=amount_to_mint.into_atoms())); let some_other_address = PublicKeyHash::from_low_u64_be(1); @@ -3221,7 +3252,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; wallet .add_unconfirmed_tx(transfer_tokens_transaction.clone(), &WalletEventsNoOp) @@ -3340,6 +3372,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -3393,7 +3426,8 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(mint_transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -3508,7 +3542,8 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_unconfirmed_tx(unmint_transaction.clone(), &WalletEventsNoOp) @@ -3593,6 +3628,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -3647,7 +3683,8 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(mint_transaction.clone(), &WalletEventsNoOp).unwrap(); let unconfirmed_token_info = wallet @@ -3703,7 +3740,8 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_unconfirmed_tx(unmint_transaction.clone(), &WalletEventsNoOp) .unwrap(); @@ -3787,6 +3825,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -3841,7 +3880,8 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(mint_transaction.clone(), &WalletEventsNoOp).unwrap(); let unconfirmed_token_info = wallet .get_token_unconfirmed_info(DEFAULT_ACCOUNT_INDEX, token_info.clone()) @@ -3896,7 +3936,8 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_unconfirmed_tx(unmint_transaction.clone(), &WalletEventsNoOp) @@ -3936,7 +3977,8 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -4072,7 +4114,8 @@ fn lock_then_transfer(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_unconfirmed_tx(lock_then_transfer_transaction.clone(), &WalletEventsNoOp) .unwrap(); @@ -4193,7 +4236,8 @@ fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); for utxo in transaction.inputs().iter().map(|inp| inp.utxo_outpoint().unwrap()) { @@ -4281,7 +4325,8 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -4316,7 +4361,8 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); for utxo in transaction.inputs().iter().map(|inp| inp.utxo_outpoint().unwrap()) { @@ -4381,7 +4427,8 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); let transaction_id = transaction.transaction().get_id(); @@ -4462,7 +4509,8 @@ fn wallet_abandon_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( DEFAULT_ACCOUNT_INDEX, @@ -4697,7 +4745,8 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, &mut wallet, @@ -4732,7 +4781,8 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -4792,7 +4842,8 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, &mut wallet, @@ -4881,7 +4932,8 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; // remove the signatures and try to sign it again let tx = stake_pool_transaction.transaction().clone(); @@ -4995,7 +5047,8 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, &mut hot_wallet, @@ -5092,7 +5145,8 @@ fn filter_pools(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; // sync for wallet1 let _ = create_block( &chain_config, @@ -5790,6 +5844,7 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -5829,7 +5884,8 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -5867,6 +5923,7 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let _ = create_block( @@ -5916,6 +5973,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -5955,7 +6013,8 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -5993,6 +6052,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { conclude_key: address2.clone().into_object(), @@ -6037,7 +6097,8 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -6091,6 +6152,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -6133,7 +6195,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let (_, block3) = create_block( &chain_config, @@ -6182,6 +6245,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { conclude_key: address1.clone().into_object(), @@ -6243,7 +6307,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let (_, block5) = create_block( &chain_config, @@ -6307,7 +6372,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let (_, block6) = create_block( &chain_config, @@ -6363,7 +6429,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let (_, block7) = create_block( &chain_config, @@ -6428,6 +6495,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -6470,7 +6538,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let (_, block3) = create_block( &chain_config, @@ -6519,6 +6588,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { conclude_key: address1.clone().into_object(), @@ -6580,7 +6650,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let (_, block5) = create_block( &chain_config, @@ -6643,7 +6714,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) - .unwrap(); + .unwrap() + .tx; let (_, block6) = create_block( &chain_config, @@ -6727,7 +6799,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let (address, block2) = create_block( &chain_config, @@ -6756,6 +6829,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let (_, block3) = create_block( @@ -6787,7 +6861,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let (_, block4) = create_block( &chain_config, @@ -6815,7 +6890,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_tx_1_id = spend_from_delegation_tx_1.transaction().get_id(); wallet1 @@ -6836,7 +6912,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_tx_2_id = spend_from_delegation_tx_2.transaction().get_id(); wallet1 @@ -6865,7 +6942,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_tx_3_id = spend_from_delegation_tx_3.transaction().get_id(); let (_, block5) = create_block( @@ -7014,7 +7092,8 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let (address, _) = create_block( &chain_config, @@ -7042,6 +7121,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let _ = create_block( @@ -7072,7 +7152,8 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -7099,7 +7180,8 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( @@ -7120,7 +7202,8 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( @@ -7243,6 +7326,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let block2_amount = chain_config.token_supply_change_fee(BlockHeight::zero()); @@ -7282,7 +7366,8 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let _ = create_block( &chain_config, @@ -7307,6 +7392,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let _ = create_block( @@ -7357,7 +7443,8 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( @@ -7394,7 +7481,8 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; wallet .add_account_unconfirmed_tx( @@ -7518,7 +7606,8 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let (address, block2) = create_block( &chain_config, @@ -7547,6 +7636,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let (_, block3) = create_block( @@ -7579,7 +7669,8 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let (_, block4) = create_block( &chain_config, @@ -7661,7 +7752,8 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_confirmed_tx_id = spend_from_delegation_tx_confirmed.transaction().get_id(); @@ -7789,7 +7881,8 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { vrf_public_key: None, }, ) - .unwrap(); + .unwrap() + .tx; let (address, block2) = create_block( &chain_config, @@ -7818,6 +7911,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let (_, block3) = create_block( @@ -7849,7 +7943,8 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let (_, block4) = create_block( &chain_config, @@ -7879,7 +7974,8 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_tx_id_1 = spend_from_delegation_tx_1.transaction().get_id(); wallet @@ -7911,7 +8007,8 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) - .unwrap(); + .unwrap() + .tx; let spend_from_delegation_tx_id_2 = spend_from_delegation_tx_2.transaction().get_id(); let (_, block5) = create_block( @@ -8035,7 +8132,8 @@ fn rollback_utxos_after_abandon(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let tx_id = tx.transaction().get_id(); wallet @@ -8176,6 +8274,7 @@ fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let expected_token_id = TokenId::from_tx_input(&token_issuance_transaction.inputs()[0]); @@ -8201,6 +8300,7 @@ fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .map(|(id, tx)| (id, tx.tx)) .unwrap(); let expected_token_id = TokenId::from_tx_input(&nft_issuance_transaction.inputs()[0]); diff --git a/wallet/types/src/lib.rs b/wallet/types/src/lib.rs index 2a35f6ea2e..71b2fe8cdf 100644 --- a/wallet/types/src/lib.rs +++ b/wallet/types/src/lib.rs @@ -28,11 +28,29 @@ pub mod wallet_tx; pub mod wallet_type; pub mod with_locked; +use std::collections::BTreeMap; + pub use account_id::{ AccountDerivationPathId, AccountId, AccountKeyPurposeId, AccountWalletCreatedTxId, AccountWalletTxId, }; pub use account_info::AccountInfo; +use common::{ + chain::{SignedTransaction, Transaction}, + primitives::Amount, +}; pub use currency::Currency; pub use keys::{KeyPurpose, KeychainUsageState, RootKeys}; pub use wallet_tx::{BlockInfo, WalletTx}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SignedTxWithFees { + pub tx: SignedTransaction, + pub fees: BTreeMap, +} + +impl SignedTxWithFees { + pub fn transaction(&self) -> &Transaction { + self.tx.transaction() + } +} diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index 18ffbc8342..27f394f3ef 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -40,8 +40,9 @@ use wallet_controller::types::GenericTokenTransfer; use wallet_rpc_client::wallet_rpc_traits::{PartialOrSignedTx, WalletInterface}; use wallet_rpc_lib::types::{ Balances, ComposedTransaction, ControllerConfig, HardwareWalletType, MnemonicInfo, - NewTransaction, NftMetadata, RpcInspectTransaction, RpcSignatureStats, RpcSignatureStatus, - RpcStandaloneAddressDetails, RpcValidatedSignatures, TokenMetadata, + NewSubmittedTransaction, NftMetadata, RpcInspectTransaction, RpcNewTransaction, + RpcSignatureStats, RpcSignatureStatus, RpcStandaloneAddressDetails, RpcValidatedSignatures, + TokenMetadata, }; use wallet_types::partially_signed_transaction::PartiallySignedTransaction; @@ -124,7 +125,24 @@ where Ok(status) } - pub fn new_tx_submitted_command(new_tx: NewTransaction) -> ConsoleCommand { + pub fn new_tx_command(new_tx: RpcNewTransaction, chain_config: &ChainConfig) -> ConsoleCommand { + let status_text = if new_tx.broadcasted { + let summary = new_tx.tx.take().transaction().text_summary(chain_config); + format!( + "The transaction:\n{summary}\nWas submitted successfully with ID:\n{}", + id_to_hex_string(*new_tx.tx_id.as_hash()) + ) + } else { + let hex = new_tx.tx.to_string(); + let summary = new_tx.tx.take().transaction().text_summary(chain_config); + + format!("The transaction:\n{summary}\nWas created and ready to be submitted:\n{hex}",) + }; + + ConsoleCommand::Print(status_text) + } + + pub fn new_tx_submitted_command(new_tx: NewSubmittedTransaction) -> ConsoleCommand { let status_text = format!( "The transaction was submitted successfully with ID:\n{}", id_to_hex_string(*new_tx.tx_id.as_hash()) @@ -1150,7 +1168,7 @@ where .mint_tokens(selected_account, token_id, address, amount, self.config) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::UnmintTokens { token_id, amount } => { @@ -1158,7 +1176,7 @@ where let new_tx = wallet.unmint_tokens(selected_account, token_id, amount, self.config).await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::LockTokenSupply { token_id } => { @@ -1166,7 +1184,7 @@ where let new_tx = wallet.lock_token_supply(selected_account, token_id, self.config).await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::FreezeToken { @@ -1183,14 +1201,14 @@ where ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::UnfreezeToken { token_id } => { let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; let new_tx = wallet.unfreeze_token(selected_account, token_id, self.config).await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::ChangeTokenAuthority { token_id, address } => { @@ -1199,7 +1217,7 @@ where .change_token_authority(selected_account, token_id, address, self.config) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::ChangeTokenMetadataUri { @@ -1216,7 +1234,7 @@ where ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::Rescan => { @@ -1353,7 +1371,7 @@ where let new_tx = wallet .send_coins(selected_account, address, amount, input_utxos, self.config) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::SweepFromAddress { @@ -1379,7 +1397,7 @@ where ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::SweepFromDelegation { @@ -1397,7 +1415,7 @@ where ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::CreateTxFromColdInput { @@ -1510,7 +1528,7 @@ where .send_tokens(selected_account, token_id, address, amount, self.config) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::MakeTxToSendTokensToAddressWithIntent { @@ -1679,7 +1697,7 @@ where ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::DecommissionStakePool { @@ -1695,7 +1713,7 @@ where self.config, ) .await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::DecommissionStakePoolRequest { @@ -1730,7 +1748,7 @@ where WalletCommand::DepositData { hex_data } => { let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; let new_tx = wallet.deposit_data(selected_account, hex_data, self.config).await?; - Ok(Self::new_tx_submitted_command(new_tx)) + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::NodeVersion => { diff --git a/wallet/wallet-controller/src/runtime_wallet.rs b/wallet/wallet-controller/src/runtime_wallet.rs index cd85de7c67..61a915aea3 100644 --- a/wallet/wallet-controller/src/runtime_wallet.rs +++ b/wallet/wallet-controller/src/runtime_wallet.rs @@ -56,7 +56,7 @@ use wallet_types::{ utxo_types::{UtxoState, UtxoStates, UtxoTypes}, wallet_tx::TxData, with_locked::WithLocked, - Currency, KeyPurpose, KeychainUsageState, + Currency, KeyPurpose, KeychainUsageState, SignedTxWithFees, }; #[cfg(feature = "trezor")] @@ -615,7 +615,7 @@ impl RuntimeWallet { token_issuance: TokenIssuance, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(TokenId, SignedTransaction)> { + ) -> WalletResult<(TokenId, SignedTxWithFees)> { match self { RuntimeWallet::Software(w) => w.issue_new_token( account_index, @@ -640,7 +640,7 @@ impl RuntimeWallet { metadata: Metadata, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(TokenId, SignedTransaction)> { + ) -> WalletResult<(TokenId, SignedTxWithFees)> { match self { RuntimeWallet::Software(w) => w.issue_new_nft( account_index, @@ -668,7 +668,7 @@ impl RuntimeWallet { address: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.mint_tokens( account_index, @@ -697,7 +697,7 @@ impl RuntimeWallet { amount: Amount, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.unmint_tokens( account_index, @@ -723,7 +723,7 @@ impl RuntimeWallet { token_info: &UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.lock_token_supply( account_index, @@ -748,7 +748,7 @@ impl RuntimeWallet { is_token_unfreezable: IsTokenUnfreezable, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.freeze_token( account_index, @@ -774,7 +774,7 @@ impl RuntimeWallet { token_info: &UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.unfreeze_token( account_index, @@ -799,7 +799,7 @@ impl RuntimeWallet { address: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.change_token_authority( account_index, @@ -826,7 +826,7 @@ impl RuntimeWallet { metadata_uri: Vec, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> Result { + ) -> Result { match self { RuntimeWallet::Software(w) => w.change_token_metadata_uri( account_index, @@ -856,7 +856,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_transaction_to_addresses( account_index, @@ -887,7 +887,7 @@ impl RuntimeWallet { filtered_inputs: Vec<(UtxoOutPoint, TxOutput)>, current_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_sweep_transaction( account_index, @@ -926,7 +926,7 @@ impl RuntimeWallet { delegation_id: DelegationId, delegation_share: Amount, current_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_sweep_from_delegation_transaction( account_index, @@ -989,7 +989,7 @@ impl RuntimeWallet { output: TxOutput, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult<(DelegationId, SignedTransaction)> { + ) -> WalletResult<(DelegationId, SignedTxWithFees)> { match self { RuntimeWallet::Software(w) => w.create_delegation( account_index, @@ -1015,7 +1015,7 @@ impl RuntimeWallet { delegation_id: DelegationId, delegation_share: Amount, current_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_transaction_to_addresses_from_delegation( account_index, @@ -1043,7 +1043,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, stake_pool_arguments: StakePoolCreationArguments, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_stake_pool_tx( account_index, @@ -1068,7 +1068,7 @@ impl RuntimeWallet { staker_balance: Amount, output_address: Option, current_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.decommission_stake_pool( account_index, @@ -1155,7 +1155,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult<(OrderId, SignedTransaction)> { + ) -> WalletResult<(OrderId, SignedTxWithFees)> { match self { RuntimeWallet::Software(w) => w.create_order_tx( account_index, @@ -1189,7 +1189,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_conclude_order_tx( account_index, @@ -1224,7 +1224,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_fill_order_tx( account_index, @@ -1257,7 +1257,7 @@ impl RuntimeWallet { order_info: RpcOrderInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_freeze_order_tx( account_index, @@ -1317,7 +1317,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult<(SignedTransaction, SignedTransactionIntent)> { + ) -> WalletResult<(SignedTxWithFees, SignedTransactionIntent)> { match self { RuntimeWallet::Software(w) => w.create_transaction_to_addresses_with_intent( account_index, diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index 54ffc1763a..2d18c5a9bd 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -62,13 +62,13 @@ use wallet_types::{ signature_status::SignatureStatus, utxo_types::{UtxoState, UtxoType}, with_locked::WithLocked, - Currency, + Currency, SignedTxWithFees, }; use crate::{ helpers::{fetch_token_info, fetch_utxo, into_balances, tx_to_partially_signed_tx}, runtime_wallet::RuntimeWallet, - types::{Balances, GenericCurrencyTransfer}, + types::{Balances, GenericCurrencyTransfer, NewTransaction}, ControllerConfig, ControllerError, }; @@ -286,7 +286,7 @@ where metadata_uri: Vec, token_total_supply: TokenTotalSupply, is_freezable: IsTokenFreezable, - ) -> Result<(SignedTransaction, TokenId), ControllerError> { + ) -> Result<(NewTransaction, TokenId), ControllerError> { self.create_and_send_tx_with_id( move |current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, @@ -314,7 +314,7 @@ where &mut self, address: Address, metadata: Metadata, - ) -> Result<(SignedTransaction, TokenId), ControllerError> { + ) -> Result<(NewTransaction, TokenId), ControllerError> { self.create_and_send_tx_with_id( move |current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, @@ -337,7 +337,7 @@ where token_info: RPCTokenInfo, amount: Amount, address: Address, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -362,7 +362,7 @@ where &mut self, token_info: RPCTokenInfo, amount: Amount, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -386,7 +386,7 @@ where pub async fn lock_token_supply( &mut self, token_info: RPCTokenInfo, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -412,7 +412,7 @@ where &mut self, token_info: RPCTokenInfo, is_token_unfreezable: IsTokenUnfreezable, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -436,7 +436,7 @@ where pub async fn unfreeze_token( &mut self, token_info: RPCTokenInfo, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -461,7 +461,7 @@ where &mut self, token_info: RPCTokenInfo, address: Address, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -485,7 +485,7 @@ where &mut self, token_info: RPCTokenInfo, metadata_uri: Vec, - ) -> Result> { + ) -> Result> { self.create_and_send_token_tx( token_info, move |current_fee_rate: FeeRate, @@ -508,7 +508,7 @@ where pub async fn deposit_data( &mut self, data: Vec, - ) -> Result> { + ) -> Result> { let (_, best_block_height) = self.wallet.get_best_block_for_account(self.account_index)?; let outputs = make_data_deposit_output(self.chain_config, data, best_block_height)?; @@ -540,7 +540,7 @@ where address: Address, amount: Amount, selected_utxos: Vec, - ) -> Result> { + ) -> Result> { self.check_tokens_in_selected_utxo(&selected_utxos).await?; let output = make_address_output(address.into_object(), amount); @@ -569,7 +569,7 @@ where &mut self, destination_address: Destination, from_addresses: BTreeSet, - ) -> Result> { + ) -> Result> { let selected_utxos = self.wallet.get_utxos( self.account_index, UtxoType::Transfer | UtxoType::LockThenTransfer | UtxoType::IssueNft, @@ -611,7 +611,7 @@ where &mut self, destination_address: Address, delegation_id: DelegationId, - ) -> Result> { + ) -> Result> { let pool_id = self .wallet .get_delegation(self.account_index, delegation_id) @@ -854,7 +854,7 @@ where &mut self, address: Address, pool_id: PoolId, - ) -> Result<(SignedTransaction, DelegationId), ControllerError> { + ) -> Result<(NewTransaction, DelegationId), ControllerError> { let output = make_create_delegation_output(address, pool_id); self.create_and_send_tx_with_id( move |current_fee_rate: FeeRate, @@ -878,7 +878,7 @@ where &mut self, amount: Amount, delegation_id: DelegationId, - ) -> Result> { + ) -> Result> { let output = TxOutput::DelegateStaking(amount, delegation_id); self.create_and_send_tx( move |current_fee_rate: FeeRate, @@ -906,7 +906,7 @@ where address: Address, amount: Amount, delegation_id: DelegationId, - ) -> Result> { + ) -> Result> { let pool_id = self.wallet.get_delegation(self.account_index, delegation_id)?.pool_id; let delegation_share = self @@ -943,7 +943,7 @@ where token_info: RPCTokenInfo, address: Address, amount: Amount, - ) -> Result> { + ) -> Result> { let output = make_address_output_token(address.into_object(), amount, token_info.token_id()); self.create_and_send_token_tx( @@ -982,7 +982,7 @@ where address: Address, amount: Amount, intent: String, - ) -> Result<(SignedTransaction, SignedTransactionIntent), ControllerError> { + ) -> Result<(SignedTxWithFees, SignedTransactionIntent), ControllerError> { let output = make_address_output_token(address.into_object(), amount, token_info.token_id()); self.create_token_tx( @@ -1024,7 +1024,7 @@ where cost_per_block: Amount, staker_key: Option, vrf_public_key: Option, - ) -> Result> { + ) -> Result> { self.create_and_send_tx( move |current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, @@ -1053,7 +1053,7 @@ where &mut self, pool_id: PoolId, output_address: Option, - ) -> Result> { + ) -> Result> { let staker_balance = self .rpc_client .get_staker_balance(pool_id) @@ -1134,7 +1134,7 @@ where give_value: OutputValue, conclude_key: Address, token_infos: Vec, - ) -> Result<(SignedTransaction, OrderId), ControllerError> { + ) -> Result<(NewTransaction, OrderId), ControllerError> { let additional_info = self.additional_token_info(token_infos)?; self.create_and_send_tx_with_id( @@ -1162,7 +1162,7 @@ where order_info: RpcOrderInfo, output_address: Option, token_infos: Vec, - ) -> Result> { + ) -> Result> { let additional_info = self.additional_token_info(token_infos)?; self.create_and_send_tx( move |current_fee_rate: FeeRate, @@ -1190,7 +1190,7 @@ where fill_amount_in_ask_currency: Amount, output_address: Option, token_infos: Vec, - ) -> Result> { + ) -> Result> { let additional_info = self.additional_token_info(token_infos)?; self.create_and_send_tx( move |current_fee_rate: FeeRate, @@ -1216,7 +1216,7 @@ where &mut self, order_id: OrderId, order_info: RpcOrderInfo, - ) -> Result> { + ) -> Result> { self.create_and_send_tx( move |current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, @@ -1342,34 +1342,41 @@ where async fn broadcast_to_mempool_if_needed( &mut self, tx: SignedTransaction, - ) -> Result> { + ) -> Result<(SignedTransaction, bool), ControllerError> { if self.config.broadcast_to_mempool { - self.broadcast_to_mempool(tx).await + self.broadcast_to_mempool(tx).await.map(|tx| (tx, true)) } else { - Ok(tx) + Ok((tx, false)) } } - /// Create a transaction and broadcast it + /// Create a transaction and broadcast it if needed async fn create_and_send_tx( &mut self, tx_maker: F, - ) -> Result> + ) -> Result> where - F: FnOnce(FeeRate, FeeRate, &mut RuntimeWallet, U31) -> Result, + F: FnOnce(FeeRate, FeeRate, &mut RuntimeWallet, U31) -> Result, ControllerError: From, { let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; - let tx = tx_maker( + let SignedTxWithFees { tx, fees } = tx_maker( current_fee_rate, consolidate_fee_rate, self.wallet, self.account_index, )?; - self.broadcast_to_mempool_if_needed(tx).await + let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; + let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; + + Ok(NewTransaction { + tx, + fees, + broadcasted, + }) } /// Create a transaction that uses a token, check if that token can be used i.e. not frozen. @@ -1413,14 +1420,21 @@ where &mut RuntimeWallet, U31, &UnconfirmedTokenInfo, - ) -> WalletResult, + ) -> WalletResult, >( &mut self, token_info: RPCTokenInfo, tx_maker: F, - ) -> Result> { - let tx = self.create_token_tx(token_info, tx_maker).await?; - self.broadcast_to_mempool_if_needed(tx).await + ) -> Result> { + let SignedTxWithFees { tx, fees } = self.create_token_tx(token_info, tx_maker).await?; + let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; + let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; + + Ok(NewTransaction { + tx, + fees, + broadcasted, + }) } fn unconfiremd_token_info( @@ -1447,15 +1461,15 @@ where FeeRate, &mut RuntimeWallet, U31, - ) -> WalletResult<(ID, SignedTransaction)>, + ) -> WalletResult<(ID, SignedTxWithFees)>, >( &mut self, tx_maker: F, - ) -> Result<(SignedTransaction, ID), ControllerError> { + ) -> Result<(NewTransaction, ID), ControllerError> { let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; - let (id, tx) = tx_maker( + let (id, SignedTxWithFees { tx, fees }) = tx_maker( current_fee_rate, consolidate_fee_rate, self.wallet, @@ -1463,7 +1477,16 @@ where ) .map_err(ControllerError::WalletError)?; - let tx = self.broadcast_to_mempool_if_needed(tx).await?; - Ok((tx, id)) + let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; + let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; + + Ok(( + NewTransaction { + tx, + fees, + broadcasted, + }, + id, + )) } } diff --git a/wallet/wallet-controller/src/types/mod.rs b/wallet/wallet-controller/src/types/mod.rs index a3d2a15ffd..11219fe28d 100644 --- a/wallet/wallet-controller/src/types/mod.rs +++ b/wallet/wallet-controller/src/types/mod.rs @@ -35,6 +35,7 @@ use common::{ }; pub use seed_phrase::SeedWithPassPhrase; pub use standalone_key::AccountStandaloneKeyDetails; +pub use transaction::NewTransaction; pub use transaction::{ InspectTransaction, SignatureStats, TransactionToInspect, ValidatedSignatures, }; diff --git a/wallet/wallet-controller/src/types/transaction.rs b/wallet/wallet-controller/src/types/transaction.rs index df7d953ec1..5a9f3dcfe1 100644 --- a/wallet/wallet-controller/src/types/transaction.rs +++ b/wallet/wallet-controller/src/types/transaction.rs @@ -68,3 +68,10 @@ pub struct InspectTransaction { pub fees: Option, pub stats: SignatureStats, } + +/// Newly signed transaction with fees that might have been broadcasted to the mempool +pub struct NewTransaction { + pub tx: SignedTransaction, + pub fees: Balances, + pub broadcasted: bool, +} diff --git a/wallet/wallet-rpc-client/src/handles_client/mod.rs b/wallet/wallet-rpc-client/src/handles_client/mod.rs index 8397e4130f..8ac4baf004 100644 --- a/wallet/wallet-rpc-client/src/handles_client/mod.rs +++ b/wallet/wallet-rpc-client/src/handles_client/mod.rs @@ -41,11 +41,12 @@ use wallet_controller::{ use wallet_rpc_lib::{ types::{ AddressInfo, AddressWithUsageInfo, Balances, BlockInfo, ComposedTransaction, CreatedWallet, - DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, NewDelegation, - NewOrder, NewTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, - RpcHashedTimelockContract, RpcInspectTransaction, RpcStandaloneAddresses, RpcTokenId, - SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, - StandaloneAddressWithDetails, TokenMetadata, TxOptionsOverrides, UtxoInfo, + DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, + NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, + NewTokenTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, + RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, + RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, StakePoolBalance, + StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }, RpcError, WalletRpc, @@ -461,7 +462,7 @@ where tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> Result { + ) -> Result { self.wallet_rpc .submit_raw_transaction(tx, do_not_store, options) .await @@ -587,7 +588,7 @@ where amount: DecimalAmount, selected_utxos: Vec, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .send_coins( account_index, @@ -598,7 +599,7 @@ where ) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) } async fn sweep_addresses( @@ -607,7 +608,7 @@ where destination_address: String, from_addresses: Vec, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .sweep_addresses( account_index, @@ -625,7 +626,7 @@ where destination_address: String, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .sweep_delegation( account_index, @@ -647,7 +648,7 @@ where staker_address: Option, vrf_public_key: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .create_stake_pool( account_index, @@ -661,7 +662,7 @@ where ) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) } async fn decommission_stake_pool( @@ -670,7 +671,7 @@ where pool_id: String, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .decommission_stake_pool( account_index, @@ -680,7 +681,7 @@ where ) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) } async fn decommission_stake_pool_request( @@ -708,15 +709,12 @@ where address: String, pool_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .create_delegation(account_index, address.into(), pool_id.into(), config) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(|(tx, delegation_id)| NewDelegation { - tx_id: tx.transaction().get_id(), - delegation_id, - }) + .map(|(tx, delegation_id)| NewDelegationTransaction::new(tx, delegation_id)) } async fn delegate_staking( @@ -725,12 +723,12 @@ where amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .delegate_staking(account_index, amount.into(), delegation_id.into(), config) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) } async fn withdraw_from_delegation( @@ -740,7 +738,7 @@ where amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .withdraw_from_delegation( account_index, @@ -751,7 +749,7 @@ where ) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) } async fn start_staking(&self, account_index: U31) -> Result<(), Self::Error> { @@ -856,7 +854,7 @@ where destination_address: String, metadata: NftMetadata, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .issue_new_nft( account_index, @@ -874,7 +872,7 @@ where destination_address: String, metadata: TokenMetadata, config: ControllerConfig, - ) -> Result { + ) -> Result { let token_supply = metadata.token_supply()?; let is_freezable = metadata.is_freezable(); self.wallet_rpc @@ -898,7 +896,7 @@ where token_id: String, address: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .change_token_authority(account_index, token_id.into(), address.into(), config) .await @@ -911,7 +909,7 @@ where token_id: String, metadata_uri: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .change_token_metadata_uri( account_index, @@ -930,7 +928,7 @@ where address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .mint_tokens( account_index, @@ -949,7 +947,7 @@ where token_id: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .unmint_tokens(account_index, token_id.into(), amount.into(), config) .await @@ -961,7 +959,7 @@ where account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .lock_token_supply(account_index, token_id.into(), config) .await @@ -974,7 +972,7 @@ where token_id: String, is_unfreezable: bool, config: ControllerConfig, - ) -> Result { + ) -> Result { let is_unfreezable = if is_unfreezable { IsTokenUnfreezable::Yes } else { @@ -991,7 +989,7 @@ where account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .unfreeze_token(account_index, token_id.into(), config) .await @@ -1005,7 +1003,7 @@ where address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .send_tokens( account_index, @@ -1044,7 +1042,7 @@ where ) .await .map_err(WalletRpcHandlesClientError::WalletRpcError) - .map(|(tx, intent)| (HexEncoded::new(tx), HexEncoded::new(intent))) + .map(|(tx, intent)| (HexEncoded::new(tx.tx), HexEncoded::new(intent))) } async fn make_tx_to_send_tokens_from_multisig_address( @@ -1079,7 +1077,7 @@ where account_index: U31, data: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let data = hex::decode(data).map_err(|_| RpcError::::InvalidHexData)?; self.wallet_rpc @@ -1118,7 +1116,7 @@ where give_amount: DecimalAmount, conclude_address: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .create_order( account_index, @@ -1137,7 +1135,7 @@ where order_id: String, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .conclude_order( account_index, @@ -1156,7 +1154,7 @@ where fill_amount_in_ask_currency: DecimalAmount, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .fill_order( account_index, @@ -1174,7 +1172,7 @@ where account_index: U31, order_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .freeze_order(account_index, order_id.into(), config) .await diff --git a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs index 559568cf3d..044bfd649e 100644 --- a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs +++ b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs @@ -46,12 +46,13 @@ use wallet_controller::{ use wallet_rpc_lib::{ types::{ AddressInfo, AddressWithUsageInfo, BlockInfo, ComposedTransaction, CreatedWallet, - DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, NewDelegation, - NewOrder, NewTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, - RpcHashedTimelockContract, RpcInspectTransaction, RpcStandaloneAddresses, RpcTokenId, - SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, - StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TxOptionsOverrides, - UtxoInfo, VrfPublicKeyInfo, + DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, + NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, + NewTokenTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, + RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, + RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, StakePoolBalance, + StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, + TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }, ColdWalletRpcClient, WalletRpcClient, }; @@ -441,7 +442,7 @@ impl WalletInterface for ClientWalletRpc { tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> Result { + ) -> Result { WalletRpcClient::submit_raw_transaction(&self.http_client, tx, do_not_store, options) .await .map_err(WalletRpcError::ResponseError) @@ -454,7 +455,7 @@ impl WalletInterface for ClientWalletRpc { amount: DecimalAmount, selected_utxos: Vec, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); let selected_utxos = selected_utxos.into_iter().map(Into::into).collect(); WalletRpcClient::send_coins( @@ -475,7 +476,7 @@ impl WalletInterface for ClientWalletRpc { destination_address: String, from_addresses: Vec, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); let all = from_addresses.is_empty(); WalletRpcClient::sweep_addresses( @@ -496,7 +497,7 @@ impl WalletInterface for ClientWalletRpc { destination_address: String, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::sweep_delegation( &self.http_client, @@ -551,7 +552,7 @@ impl WalletInterface for ClientWalletRpc { staker_address: Option, vrf_public_key: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::create_stake_pool( &self.http_client, @@ -574,7 +575,7 @@ impl WalletInterface for ClientWalletRpc { pool_id: String, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::decommission_stake_pool( &self.http_client, @@ -612,7 +613,7 @@ impl WalletInterface for ClientWalletRpc { address: String, pool_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::create_delegation( &self.http_client, @@ -631,7 +632,7 @@ impl WalletInterface for ClientWalletRpc { amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::delegate_staking( &self.http_client, @@ -651,7 +652,7 @@ impl WalletInterface for ClientWalletRpc { amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::withdraw_from_delegation( &self.http_client, @@ -755,7 +756,7 @@ impl WalletInterface for ClientWalletRpc { destination_address: String, metadata: NftMetadata, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::issue_new_nft( &self.http_client, @@ -774,7 +775,7 @@ impl WalletInterface for ClientWalletRpc { destination_address: String, metadata: TokenMetadata, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::issue_new_token( &self.http_client, @@ -793,7 +794,7 @@ impl WalletInterface for ClientWalletRpc { token_id: String, address: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::change_token_authority( &self.http_client, @@ -812,7 +813,7 @@ impl WalletInterface for ClientWalletRpc { token_id: String, metadata_uri: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::change_token_metadata_uri( &self.http_client, @@ -832,7 +833,7 @@ impl WalletInterface for ClientWalletRpc { address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::mint_tokens( &self.http_client, @@ -852,7 +853,7 @@ impl WalletInterface for ClientWalletRpc { token_id: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::unmint_tokens( &self.http_client, @@ -870,7 +871,7 @@ impl WalletInterface for ClientWalletRpc { account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::lock_token_supply( &self.http_client, @@ -888,7 +889,7 @@ impl WalletInterface for ClientWalletRpc { token_id: String, is_unfreezable: bool, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::freeze_token( &self.http_client, @@ -906,7 +907,7 @@ impl WalletInterface for ClientWalletRpc { account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::unfreeze_token( &self.http_client, @@ -925,7 +926,7 @@ impl WalletInterface for ClientWalletRpc { address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::send_tokens( &self.http_client, @@ -994,7 +995,7 @@ impl WalletInterface for ClientWalletRpc { account_index: U31, data: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::deposit_data( &self.http_client, @@ -1036,7 +1037,7 @@ impl WalletInterface for ClientWalletRpc { give_amount: DecimalAmount, conclude_address: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::create_order( &self.http_client, @@ -1056,7 +1057,7 @@ impl WalletInterface for ClientWalletRpc { order_id: String, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::conclude_order( &self.http_client, @@ -1076,7 +1077,7 @@ impl WalletInterface for ClientWalletRpc { fill_amount_in_ask_currency: DecimalAmount, output_address: Option, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::fill_order( &self.http_client, @@ -1095,7 +1096,7 @@ impl WalletInterface for ClientWalletRpc { account_index: U31, order_id: String, config: ControllerConfig, - ) -> Result { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::freeze_order( &self.http_client, diff --git a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs index a1890873ee..e5c8270388 100644 --- a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs +++ b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs @@ -36,10 +36,11 @@ use wallet_controller::{ }; use wallet_rpc_lib::types::{ AddressInfo, AddressWithUsageInfo, Balances, BlockInfo, ComposedTransaction, CreatedWallet, - DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, NewDelegation, - NewOrder, NewTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, - RpcHashedTimelockContract, RpcInspectTransaction, RpcSignatureStatus, RpcStandaloneAddresses, - RpcTokenId, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, + DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, + NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, + NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcHashedTimelockContract, + RpcInspectTransaction, RpcNewTransaction, RpcSignatureStatus, RpcStandaloneAddresses, + SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }; use wallet_types::{ @@ -211,7 +212,7 @@ pub trait WalletInterface { tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> Result; + ) -> Result; async fn sign_challenge( &self, @@ -256,7 +257,7 @@ pub trait WalletInterface { amount: DecimalAmount, selected_utxos: Vec, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn sweep_addresses( &self, @@ -264,7 +265,7 @@ pub trait WalletInterface { destination_address: String, from_addresses: Vec, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn sweep_delegation( &self, @@ -272,7 +273,7 @@ pub trait WalletInterface { destination_address: String, delegation_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn transaction_from_cold_input( &self, @@ -300,7 +301,7 @@ pub trait WalletInterface { staker_address: Option, vrf_public_key: Option, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn decommission_stake_pool( &self, @@ -308,7 +309,7 @@ pub trait WalletInterface { pool_id: String, output_address: Option, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn decommission_stake_pool_request( &self, @@ -324,7 +325,7 @@ pub trait WalletInterface { address: String, pool_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn delegate_staking( &self, @@ -332,7 +333,7 @@ pub trait WalletInterface { amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn withdraw_from_delegation( &self, @@ -341,7 +342,7 @@ pub trait WalletInterface { amount: DecimalAmount, delegation_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn start_staking(&self, account_index: U31) -> Result<(), Self::Error>; @@ -387,7 +388,7 @@ pub trait WalletInterface { destination_address: String, metadata: NftMetadata, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn issue_new_token( &self, @@ -395,7 +396,7 @@ pub trait WalletInterface { destination_address: String, metadata: TokenMetadata, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn change_token_authority( &self, @@ -403,7 +404,7 @@ pub trait WalletInterface { token_id: String, address: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn change_token_metadata_uri( &self, @@ -411,7 +412,7 @@ pub trait WalletInterface { token_id: String, metadata_uri: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn mint_tokens( &self, @@ -420,7 +421,7 @@ pub trait WalletInterface { address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn unmint_tokens( &self, @@ -428,14 +429,14 @@ pub trait WalletInterface { token_id: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn lock_token_supply( &self, account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn freeze_token( &self, @@ -443,14 +444,14 @@ pub trait WalletInterface { token_id: String, is_unfreezable: bool, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn unfreeze_token( &self, account_index: U31, token_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn send_tokens( &self, @@ -459,7 +460,7 @@ pub trait WalletInterface { address: String, amount: DecimalAmount, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn make_tx_for_sending_tokens_with_intent( &self, @@ -491,7 +492,7 @@ pub trait WalletInterface { account_index: U31, data: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn create_htlc_transaction( &self, @@ -512,7 +513,7 @@ pub trait WalletInterface { give_amount: DecimalAmount, conclude_address: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn conclude_order( &self, @@ -520,7 +521,7 @@ pub trait WalletInterface { order_id: String, output_address: Option, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn fill_order( &self, @@ -529,14 +530,14 @@ pub trait WalletInterface { fill_amount_in_ask_currency: DecimalAmount, output_address: Option, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn freeze_order( &self, account_index: U31, order_id: String, config: ControllerConfig, - ) -> Result; + ) -> Result; async fn node_version(&self) -> Result; diff --git a/wallet/wallet-rpc-daemon/docs/RPC.md b/wallet/wallet-rpc-daemon/docs/RPC.md index 43111062f6..3169b28a3c 100644 --- a/wallet/wallet-rpc-daemon/docs/RPC.md +++ b/wallet/wallet-rpc-daemon/docs/RPC.md @@ -980,7 +980,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `address_sweep_spendable` @@ -996,6 +1010,9 @@ Parameters: "account": number, "destination_address": bech32 string, "from_addresses": [ bech32 string, .. ], + "all": EITHER OF + 1) bool + 2) null, "options": { "in_top_x_mb": EITHER OF 1) number 2) null }, @@ -1004,7 +1021,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `staking_sweep_delegation` @@ -1027,7 +1058,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `transaction_create_from_cold_input` @@ -1188,7 +1233,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `staking_decommission_pool` @@ -1213,7 +1272,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `staking_decommission_pool_request` @@ -1266,8 +1339,20 @@ Parameters: Returns: ``` { - "tx_id": hex string, "delegation_id": bech32 string, + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, } ``` @@ -1292,7 +1377,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `delegation_withdraw` @@ -1318,7 +1417,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `staking_start` @@ -1542,6 +1655,18 @@ Returns: { "token_id": bech32 string, "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, } ``` @@ -1587,6 +1712,18 @@ Returns: { "token_id": bech32 string, "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, } ``` @@ -1609,7 +1746,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_change_metadata_uri` @@ -1631,7 +1782,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_mint` @@ -1656,7 +1821,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_unmint` @@ -1682,7 +1861,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_lock_supply` @@ -1705,7 +1898,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_freeze` @@ -1730,7 +1937,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_unfreeze` @@ -1754,7 +1975,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_send` @@ -1779,7 +2014,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `token_make_tx_for_sending_with_intent` @@ -1893,7 +2142,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `create_htlc_transaction` @@ -1999,8 +2262,20 @@ Parameters: Returns: ``` { - "tx_id": hex string, "order_id": bech32 string, + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, } ``` @@ -2027,7 +2302,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `fill_order` @@ -2055,7 +2344,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `freeze_order` diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index 232aa2d82a..25de938ce5 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -41,19 +41,19 @@ use wallet_types::{ partially_signed_transaction::PartiallySignedTransaction, with_locked::WithLocked, }; +use super::types::{NewTokenTransaction, UtxoInfo}; use crate::types::{ AccountArg, AddressInfo, AddressWithUsageInfo, Balances, ChainInfo, ComposedTransaction, CreatedWallet, DelegationInfo, HardwareWalletType, HexEncoded, LegacyVrfPublicKeyInfo, - MaybeSignedTransaction, NewAccountInfo, NewDelegation, NewOrder, NewTransaction, NftMetadata, - NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcAmountIn, RpcHashedTimelockContract, - RpcInspectTransaction, RpcStandaloneAddresses, RpcTokenId, RpcUtxoOutpoint, RpcUtxoState, - RpcUtxoType, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, + MaybeSignedTransaction, NewAccountInfo, NewDelegationTransaction, NewOrderTransaction, + NewSubmittedTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, + RpcAmountIn, RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, + RpcStandaloneAddresses, RpcUtxoOutpoint, RpcUtxoState, RpcUtxoType, + SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TxOptionsOverrides, VrfPublicKeyInfo, }; -use super::types::UtxoInfo; - #[rpc::rpc(server)] trait WalletEventsRpc { #[subscription(name = "subscribe_wallet_events", item = Event)] @@ -367,7 +367,7 @@ trait WalletRpc { tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Send a given coin amount to a given address. The wallet will automatically calculate the required information /// Optionally, one can also mention the utxos to be used. @@ -379,7 +379,7 @@ trait WalletRpc { amount: RpcAmountIn, selected_utxos: Vec, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Sweep all spendable coins or tokens from an address or addresses to a given address. /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. @@ -392,7 +392,7 @@ trait WalletRpc { from_addresses: Vec>, all: Option, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Sweep all the coins from a delegation to a given address. /// The wallet will automatically calculate the required fees @@ -403,7 +403,7 @@ trait WalletRpc { destination_address: RpcAddress, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Creates a transaction that spends from a specific address, /// and returns the change to the same address (unless one is specified), without signature. @@ -461,7 +461,7 @@ trait WalletRpc { staker_address: Option>, vrf_public_key: Option>, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Decommission a staking pool, given its id. This assumes that the decommission key is owned /// by the selected account in this wallet. @@ -472,7 +472,7 @@ trait WalletRpc { pool_id: RpcAddress, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Create a request to decommission a pool. This assumes that the decommission key is owned /// by another wallet. The output of this command should be passed to account-sign-raw-transaction @@ -498,7 +498,7 @@ trait WalletRpc { address: RpcAddress, pool_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Send coins to a delegation id to be staked #[method(name = "delegation_stake")] @@ -508,7 +508,7 @@ trait WalletRpc { amount: RpcAmountIn, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Send coins from a delegation id (that you own) to stop staking them. /// Note that stopping the delegation requires a lock period. @@ -520,7 +520,7 @@ trait WalletRpc { amount: RpcAmountIn, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Start staking, assuming there are staking pools in the selected account in this wallet. #[method(name = "staking_start")] @@ -572,7 +572,7 @@ trait WalletRpc { destination_address: RpcAddress, metadata: NftMetadata, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Issue a new fungible token from scratch. /// Notice that issuing a token fills an issuers supply. To have tokens that are spendable, @@ -584,7 +584,7 @@ trait WalletRpc { destination_address: RpcAddress, metadata: TokenMetadata, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Change the authority of a token; i.e., the cryptographic authority that can do all authority token operations #[method(name = "token_change_authority")] @@ -594,7 +594,7 @@ trait WalletRpc { token_id: RpcAddress, address: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Change the metadata URI of a token #[method(name = "token_change_metadata_uri")] @@ -604,7 +604,7 @@ trait WalletRpc { token_id: RpcAddress, metadata_uri: RpcHexString, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Given a token that is already issued, mint new tokens and increase the total supply #[method(name = "token_mint")] @@ -615,7 +615,7 @@ trait WalletRpc { address: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Unmint existing tokens and reduce the total supply /// Unminting reduces the total supply and puts the unminted tokens back at the issuer's control. @@ -627,7 +627,7 @@ trait WalletRpc { token_id: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Lock the circulating supply for the token. THIS IS IRREVERSIBLE. /// @@ -638,7 +638,7 @@ trait WalletRpc { account_index: AccountArg, token_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Freezing the token (by token authority) forbids any operation with all the tokens (except for the optional unfreeze). /// @@ -651,7 +651,7 @@ trait WalletRpc { token_id: RpcAddress, is_unfreezable: bool, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// By unfreezing the token all operations are available for the tokens again. /// @@ -663,7 +663,7 @@ trait WalletRpc { account: AccountArg, token_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Send the given token amount to the given address. The wallet will automatically calculate the required information. #[method(name = "token_send")] @@ -674,7 +674,7 @@ trait WalletRpc { address: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Create a transaction for sending tokens to the given address, without submitting it. /// The wallet will automatically calculate the required information. @@ -724,7 +724,7 @@ trait WalletRpc { account: AccountArg, data: RpcHexString, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Creates a transaction that locks a given number of coins or tokens in a Hashed Timelock Contract. /// Created transaction is not broadcasted by this function. @@ -750,7 +750,7 @@ trait WalletRpc { give: RpcOutputValueIn, conclude_address: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Conclude an order, given its id. This assumes that the conclude key is owned /// by the selected account in this wallet. @@ -762,7 +762,7 @@ trait WalletRpc { order_id: RpcAddress, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Fill order completely or partially given its id and an amount that satisfy what an order can offer. /// Optionally output address can be provided where the exchanged funds from the order are transferred. @@ -774,7 +774,7 @@ trait WalletRpc { fill_amount_in_ask_currency: RpcAmountIn, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Freeze an order given its id. This prevents an order from being filled. /// Only a conclude operation is allowed afterwards. @@ -784,7 +784,7 @@ trait WalletRpc { account: AccountArg, order_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult; + ) -> rpc::RpcResult; /// Node version #[method(name = "node_version")] diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index 86d1e18e5c..12f449d92c 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -37,7 +37,10 @@ use mempool::tx_accumulator::PackingStrategy; use mempool_types::tx_options::TxOptionsOverrides; use p2p_types::{bannable_address::BannableAddress, socket_address::SocketAddress, PeerId}; use serialization::{hex_encoded::HexEncoded, Decode, DecodeAll}; -use types::{NewOrder, RpcHashedTimelockContract}; +use types::{ + NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, RpcHashedTimelockContract, + RpcNewTransaction, +}; use utils::{ensure, shallow_clone::ShallowClone}; use utils_networking::IpOrSocketAddress; use wallet::{ @@ -73,7 +76,7 @@ pub use rpc::{rpc_creds::RpcCreds, Rpc}; use wallet_controller::{ types::{ Balances, BlockInfo, CreatedBlockInfo, CreatedWallet, GenericTokenTransfer, - InspectTransaction, OpenedWallet, SeedWithPassPhrase, TransactionToInspect, + InspectTransaction, NewTransaction, OpenedWallet, SeedWithPassPhrase, TransactionToInspect, WalletCreationOptions, WalletInfo, WalletTypeArgs, }, ConnectedPeer, ControllerConfig, ControllerError, NodeInterface, UtxoState, UtxoStates, @@ -88,7 +91,7 @@ use wallet_types::{ signature_status::SignatureStatus, wallet_tx::TxData, with_locked::WithLocked, - Currency, + Currency, SignedTxWithFees, }; use crate::{service::WalletController, WalletHandle, WalletRpcConfig}; @@ -99,10 +102,10 @@ use wallet_types::wallet_type::WalletType; pub use self::types::RpcError; use self::types::{ AddressInfo, AddressWithUsageInfo, DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, - NewAccountInfo, NewTransaction, PoolInfo, PublicKeyInfo, RpcAddress, RpcAmountIn, RpcHexString, + NewAccountInfo, PoolInfo, PublicKeyInfo, RpcAddress, RpcAmountIn, RpcHexString, RpcStandaloneAddress, RpcStandaloneAddressDetails, RpcStandaloneAddresses, - RpcStandalonePrivateKeyAddress, RpcTokenId, RpcUtxoOutpoint, StakingStatus, - StandaloneAddressWithDetails, VrfPublicKeyInfo, + RpcStandalonePrivateKeyAddress, RpcUtxoOutpoint, StakingStatus, StandaloneAddressWithDetails, + VrfPublicKeyInfo, }; #[derive(Clone)] @@ -797,7 +800,7 @@ where tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> WRpcResult { + ) -> WRpcResult { let tx = tx.take(); let block_height = self.best_block().await?.height; check_transaction(&self.chain_config, block_height, &tx).map_err(|err| { @@ -830,7 +833,7 @@ where .await??; } - Ok(NewTransaction { tx_id }) + Ok(NewSubmittedTransaction { tx_id }) } pub async fn sign_raw_transaction( @@ -921,7 +924,7 @@ where destination_address: RpcAddress, from_addresses: Vec>, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let destination_address = destination_address .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidAddress)?; @@ -940,7 +943,7 @@ where .sweep_addresses(destination_address, from_addresses) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -952,7 +955,7 @@ where destination_address: RpcAddress, delegation_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let delegation_id = delegation_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidDelegationId)?; @@ -969,7 +972,7 @@ where .sweep_delegation(destination_address, delegation_id) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -982,7 +985,7 @@ where amount: RpcAmountIn, selected_utxos: Vec, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let decimals = self.chain_config.coin_decimals(); let amount = amount.to_amount(decimals).ok_or(RpcError::InvalidCoinAmount)?; let address = @@ -1071,7 +1074,7 @@ where address: RpcAddress, amount: RpcAmountIn, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -1092,7 +1095,7 @@ where .send_tokens_to_address(token_info, address, amount) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1106,7 +1109,7 @@ where amount: RpcAmountIn, intent: String, config: ControllerConfig, - ) -> WRpcResult<(SignedTransaction, SignedTransactionIntent), N> { + ) -> WRpcResult<(SignedTxWithFees, SignedTransactionIntent), N> { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -1272,7 +1275,7 @@ where staker_address: Option>, vrf_public_key: Option>, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let decimals = self.chain_config.coin_decimals(); let amount = amount.to_amount(decimals).ok_or(RpcError::InvalidCoinAmount)?; let cost_per_block = @@ -1326,7 +1329,7 @@ where pool_id: RpcAddress, output_address: Option>, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let pool_id = pool_id.decode_object(&self.chain_config).map_err(|_| RpcError::InvalidPoolId)?; @@ -1382,7 +1385,7 @@ where address: RpcAddress, pool_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult<(SignedTransaction, RpcAddress), N> { + ) -> WRpcResult<(NewTransaction, RpcAddress), N> { let address = address.into_address(&self.chain_config).map_err(|_| RpcError::InvalidAddress)?; @@ -1416,7 +1419,7 @@ where amount: RpcAmountIn, delegation_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let decimals = self.chain_config.coin_decimals(); let amount = amount.to_amount(decimals).ok_or(RpcError::InvalidCoinAmount)?; @@ -1445,7 +1448,7 @@ where amount: RpcAmountIn, delegation_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let decimals = self.chain_config.coin_decimals(); let amount = amount.to_amount(decimals).ok_or(RpcError::InvalidCoinAmount)?; let address = @@ -1603,7 +1606,7 @@ where give: RpcOutputValueIn, conclude_address: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let coin_decimals = self.chain_config.coin_decimals(); let convert_currency = |rpc_currency| -> Result<_, RpcError> { @@ -1654,10 +1657,11 @@ where }) }) .await? - .map(|(tx, order_id)| NewOrder { - tx_id: tx.transaction().get_id(), - order_id: RpcAddress::new(&self.chain_config, order_id) - .expect("addressable delegation id"), + .map(|(tx, order_id)| { + NewOrderTransaction::new( + tx, + RpcAddress::new(&self.chain_config, order_id).expect("addressable order id"), + ) }) } @@ -1667,7 +1671,7 @@ where order_id: RpcAddress, output_address: Option>, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let order_id = order_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -1699,7 +1703,7 @@ where .conclude_order(order_id, order_info, output_address, token_infos) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1712,7 +1716,7 @@ where fill_amount_in_ask_currency: RpcAmountIn, output_address: Option>, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let coin_decimals = self.chain_config.coin_decimals(); let order_id = order_id .decode_object(&self.chain_config) @@ -1763,7 +1767,7 @@ where ) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1774,7 +1778,7 @@ where account_index: U31, order_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let order_id = order_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -1789,7 +1793,7 @@ where .freeze_order(order_id, order_info) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1857,7 +1861,7 @@ where account_index: U31, data: Vec, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { self.wallet .call_async(move |controller| { Box::pin(async move { @@ -1867,7 +1871,7 @@ where .deposit_data(data) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1884,7 +1888,7 @@ where token_total_supply: TokenTotalSupply, is_freezable: IsTokenFreezable, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { ensure!( number_of_decimals <= self.chain_config.token_max_dec_count(), RpcError::Controller(ControllerError::WalletError(WalletError::TokenIssuance( @@ -1913,10 +1917,12 @@ where }) }) .await? - .map(|(tx, token_id)| RpcTokenId { - tx_id: tx.transaction().get_id(), - token_id: RpcAddress::new(&self.chain_config, token_id) - .expect("Encoding token id should never fail"), + .map(|(tx, token_id)| { + NewTokenTransaction::new( + tx, + RpcAddress::new(&self.chain_config, token_id) + .expect("Encoding token id should never fail"), + ) }) } @@ -1926,7 +1932,7 @@ where address: RpcAddress, metadata: Metadata, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let address = address.into_address(&self.chain_config).map_err(|_| RpcError::InvalidAddress)?; self.wallet @@ -1939,10 +1945,12 @@ where }) }) .await? - .map(|(tx, token_id)| RpcTokenId { - tx_id: tx.transaction().get_id(), - token_id: RpcAddress::new(&self.chain_config, token_id) - .expect("Encoding token id should never fail"), + .map(|(tx, token_id)| { + NewTokenTransaction::new( + tx, + RpcAddress::new(&self.chain_config, token_id) + .expect("Encoding token id should never fail"), + ) }) } @@ -1953,7 +1961,7 @@ where address: RpcAddress, amount: RpcAmountIn, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -1974,7 +1982,7 @@ where .mint_tokens(token_info, amount, address) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -1986,7 +1994,7 @@ where token_id: RpcAddress, amount: RpcAmountIn, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2005,7 +2013,7 @@ where .unmint_tokens(token_info, amount) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -2016,7 +2024,7 @@ where account_index: U31, token_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2030,7 +2038,7 @@ where .lock_token_supply(token_info) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -2042,7 +2050,7 @@ where token_id: RpcAddress, is_unfreezable: IsTokenUnfreezable, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2056,7 +2064,7 @@ where .freeze_token(token_info, is_unfreezable) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -2067,7 +2075,7 @@ where account_index: U31, token_id: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2081,7 +2089,7 @@ where .unfreeze_token(token_info) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -2093,7 +2101,7 @@ where token_id: RpcAddress, address: RpcAddress, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2109,7 +2117,7 @@ where .change_token_authority(token_info, address) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? @@ -2121,7 +2129,7 @@ where token_id: RpcAddress, metadata_uri: RpcHexString, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let token_id = token_id .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidTokenId)?; @@ -2135,7 +2143,7 @@ where .change_token_metadata_uri(token_info, metadata_uri.into_bytes()) .await .map_err(RpcError::Controller) - .map(NewTransaction::new) + .map(RpcNewTransaction::new) }) }) .await? diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index 3204363628..bd9565dea6 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -49,9 +49,9 @@ use crate::{ types::{ AccountArg, AddressInfo, AddressWithUsageInfo, Balances, ChainInfo, ComposedTransaction, CreatedWallet, DelegationInfo, HardwareWalletType, HexEncoded, LegacyVrfPublicKeyInfo, - MaybeSignedTransaction, NewAccountInfo, NewDelegation, NewTransaction, NftMetadata, - NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcAddress, RpcAmountIn, RpcHexString, - RpcInspectTransaction, RpcStandaloneAddresses, RpcTokenId, RpcUtxoOutpoint, RpcUtxoState, + MaybeSignedTransaction, NewAccountInfo, NewDelegationTransaction, NewSubmittedTransaction, + NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcAddress, RpcAmountIn, + RpcHexString, RpcInspectTransaction, RpcStandaloneAddresses, RpcUtxoOutpoint, RpcUtxoState, RpcUtxoType, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, @@ -59,7 +59,9 @@ use crate::{ RpcError, }; -use super::types::{NewOrder, RpcHashedTimelockContract}; +use super::types::{ + NewOrderTransaction, NewTokenTransaction, RpcHashedTimelockContract, RpcNewTransaction, +}; #[async_trait::async_trait] impl WalletEventsRpcServer for WalletRpc @@ -522,7 +524,7 @@ where tx: HexEncoded, do_not_store: bool, options: TxOptionsOverrides, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { rpc::handle_result(self.submit_raw_transaction(tx, do_not_store, options).await) } @@ -533,7 +535,7 @@ where amount: RpcAmountIn, selected_utxos: Vec, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -547,7 +549,7 @@ where config, ) .await - .map(NewTransaction::new), + .map(RpcNewTransaction::new), ) } @@ -558,7 +560,7 @@ where from_addresses: Vec>, all: Option, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -585,7 +587,7 @@ where destination_address: RpcAddress, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -650,7 +652,7 @@ where staker_address: Option>, vrf_public_key: Option>, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -667,7 +669,7 @@ where config, ) .await - .map(NewTransaction::new), + .map(RpcNewTransaction::new), ) } @@ -677,7 +679,7 @@ where pool_id: RpcAddress, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -690,7 +692,7 @@ where config, ) .await - .map(NewTransaction::new), + .map(RpcNewTransaction::new), ) } @@ -723,7 +725,7 @@ where address: RpcAddress, pool_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -731,10 +733,7 @@ where rpc::handle_result( self.create_delegation(account_arg.index::()?, address, pool_id, config) .await - .map(|(tx, delegation_id)| NewDelegation { - tx_id: tx.transaction().get_id(), - delegation_id, - }), + .map(|(tx, delegation_id)| NewDelegationTransaction::new(tx, delegation_id)), ) } @@ -744,7 +743,7 @@ where amount: RpcAmountIn, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -752,7 +751,7 @@ where rpc::handle_result( self.delegate_staking(account_arg.index::()?, amount, delegation_id, config) .await - .map(NewTransaction::new), + .map(RpcNewTransaction::new), ) } @@ -763,7 +762,7 @@ where amount: RpcAmountIn, delegation_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -777,7 +776,7 @@ where config, ) .await - .map(NewTransaction::new), + .map(RpcNewTransaction::new), ) } @@ -824,7 +823,7 @@ where destination_address: RpcAddress, metadata: NftMetadata, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -847,7 +846,7 @@ where destination_address: RpcAddress, metadata: TokenMetadata, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -876,7 +875,7 @@ where token_id: RpcAddress, address: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -894,7 +893,7 @@ where token_id: RpcAddress, metadata_uri: RpcHexString, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -918,7 +917,7 @@ where address: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -936,7 +935,7 @@ where token_id: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -952,7 +951,7 @@ where account_arg: AccountArg, token_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -969,7 +968,7 @@ where token_id: RpcAddress, is_unfreezable: bool, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -992,7 +991,7 @@ where account_arg: AccountArg, token_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1008,7 +1007,7 @@ where address: RpcAddress, amount: RpcAmountIn, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1047,7 +1046,7 @@ where config, ) .await - .map(|(tx, intent)| (HexEncoded::new(tx), HexEncoded::new(intent))), + .map(|(tx, intent)| (HexEncoded::new(tx.tx), HexEncoded::new(intent))), ) } @@ -1087,7 +1086,7 @@ where account_arg: AccountArg, data: RpcHexString, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1125,7 +1124,7 @@ where give: RpcOutputValueIn, conclude_address: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1149,7 +1148,7 @@ where order_id: RpcAddress, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1168,7 +1167,7 @@ where fill_amount_in_ask_currency: RpcAmountIn, output_address: Option>, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1191,7 +1190,7 @@ where account_arg: AccountArg, order_id: RpcAddress, options: TransactionOptions, - ) -> rpc::RpcResult { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, diff --git a/wallet/wallet-rpc-lib/src/rpc/types.rs b/wallet/wallet-rpc-lib/src/rpc/types.rs index 9c9344426d..6b60a18f3d 100644 --- a/wallet/wallet-rpc-lib/src/rpc/types.rs +++ b/wallet/wallet-rpc-lib/src/rpc/types.rs @@ -453,9 +453,27 @@ impl PoolInfo { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] -pub struct NewDelegation { - pub tx_id: Id, +pub struct NewDelegationTransaction { pub delegation_id: RpcAddress, + pub tx_id: Id, + pub tx: HexEncoded, + pub fees: Balances, + pub broadcasted: bool, +} + +impl NewDelegationTransaction { + pub fn new( + tx: wallet_controller::types::NewTransaction, + delegation_id: RpcAddress, + ) -> Self { + Self { + delegation_id, + tx_id: tx.tx.transaction().get_id(), + tx: tx.tx.into(), + fees: tx.fees, + broadcasted: tx.broadcasted, + } + } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] @@ -632,17 +650,35 @@ pub struct StakePoolBalance { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] -pub struct RpcTokenId { +pub struct NewTokenTransaction { pub token_id: RpcAddress, pub tx_id: Id, + pub tx: HexEncoded, + pub fees: Balances, + pub broadcasted: bool, +} + +impl NewTokenTransaction { + pub fn new( + tx: wallet_controller::types::NewTransaction, + token_id: RpcAddress, + ) -> Self { + Self { + token_id, + tx_id: tx.tx.transaction().get_id(), + tx: tx.tx.into(), + fees: tx.fees, + broadcasted: tx.broadcasted, + } + } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] -pub struct NewTransaction { +pub struct NewSubmittedTransaction { pub tx_id: Id, } -impl NewTransaction { +impl NewSubmittedTransaction { pub fn new(tx: SignedTransaction) -> Self { Self { tx_id: tx.transaction().get_id(), @@ -650,6 +686,25 @@ impl NewTransaction { } } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] +pub struct RpcNewTransaction { + pub tx_id: Id, + pub tx: HexEncoded, + pub fees: Balances, + pub broadcasted: bool, +} + +impl RpcNewTransaction { + pub fn new(tx: wallet_controller::types::NewTransaction) -> Self { + Self { + tx_id: tx.tx.transaction().get_id(), + tx: tx.tx.into(), + fees: tx.fees, + broadcasted: tx.broadcasted, + } + } +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] pub struct NodeVersion { pub version: String, @@ -870,9 +925,27 @@ pub struct RpcHashedTimelockContract { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] -pub struct NewOrder { - pub tx_id: Id, +pub struct NewOrderTransaction { pub order_id: RpcAddress, + pub tx_id: Id, + pub tx: HexEncoded, + pub fees: Balances, + pub broadcasted: bool, +} + +impl NewOrderTransaction { + pub fn new( + tx: wallet_controller::types::NewTransaction, + order_id: RpcAddress, + ) -> Self { + Self { + order_id, + tx_id: tx.tx.transaction().get_id(), + tx: tx.tx.into(), + fees: tx.fees, + broadcasted: tx.broadcasted, + } + } } #[derive(Debug, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] diff --git a/wallet/wallet-rpc-lib/tests/basic.rs b/wallet/wallet-rpc-lib/tests/basic.rs index 279ef305e1..7e1c218e23 100644 --- a/wallet/wallet-rpc-lib/tests/basic.rs +++ b/wallet/wallet-rpc-lib/tests/basic.rs @@ -28,7 +28,7 @@ use utils::{ }; use wallet_rpc_lib::{ types::{ - AddressInfo, Balances, BlockInfo, NewAccountInfo, NewTransaction, RpcAmountIn, + AddressInfo, Balances, BlockInfo, NewAccountInfo, NewSubmittedTransaction, RpcAmountIn, RpcUtxoState, TransactionOptions, }, TxState, @@ -164,7 +164,7 @@ async fn stake_and_send_coins_to_acct1(#[case] seed: Seed) { assert_eq!(utxo_amount, coins_before.into_atoms()); let to_send_amount = Amount::from_atoms(utxo_amount / 2); - let _: NewTransaction = { + let _: NewSubmittedTransaction = { let send_to_addr = acct1_addr.address; let options = TransactionOptions { in_top_x_mb: Some(3), From fbe1a0f62a4106c8c445f898419ced175d08339c Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Thu, 10 Apr 2025 07:41:07 +0200 Subject: [PATCH 3/8] add config-broadcast command for CLI wallet --- wallet/wallet-cli-commands/src/command_handler/mod.rs | 7 +++++++ wallet/wallet-cli-commands/src/lib.rs | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index 27f394f3ef..b083bfbe24 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -774,6 +774,13 @@ where self.handle_cold_wallet_command(command, chain_config).await } + WalletCommand::ConfigBroadcast { broadcast } => { + self.config.broadcast_to_mempool = broadcast; + Ok(ConsoleCommand::Print(format!( + "Broadcast to Mempool set to: {broadcast:?}" + ))) + } + WalletCommand::ChainstateInfo => { let info = self.wallet().await?.chainstate_info().await?; Ok(ConsoleCommand::Print(format!("{info:#?}"))) diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index 5cd8fa8bff..4fe882abaf 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -394,6 +394,12 @@ pub enum WalletCommand { #[command(flatten)] ColdCommands(ColdWalletCommand), + /// Configure broadcasting to Mempool to true of false. + /// By default it is set to true. If set to false, any command that creates a transaction will + /// return it to the user and will need to be submitted manually with the command `node-submit-transaction` + #[clap(name = "config-broadcast")] + ConfigBroadcast { broadcast: bool }, + #[clap(name = "account-create")] CreateNewAccount { name: Option }, From 1d0a77e0bae57510849a6ea08f0f6dfd3a910ef5 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Thu, 10 Apr 2025 08:06:44 +0200 Subject: [PATCH 4/8] fix after rebase --- test/functional/wallet_multisig_address.py | 2 +- test/functional/wallet_watch_address.py | 6 +++--- .../src/command_handler/mod.rs | 4 ++-- wallet/wallet-cli-lib/tests/basic.rs | 8 ++++---- wallet/wallet-rpc-daemon/docs/RPC.md | 16 +++++++++++++++- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/test/functional/wallet_multisig_address.py b/test/functional/wallet_multisig_address.py index 5694e61587..5b09dc9dcd 100644 --- a/test/functional/wallet_multisig_address.py +++ b/test/functional/wallet_multisig_address.py @@ -180,7 +180,7 @@ async def async_test(self): await wallet.open_wallet('wallet0') output = await wallet.send_to_address(multisig_address, 1) assert_in("The transaction was submitted successfully", output) - multisig_tx_id = output.splitlines()[1] + multisig_tx_id = output.splitlines()[-1] self.generate_block() assert not node.mempool_contains_tx(multisig_tx_id) assert_not_in("No transaction found", await wallet.get_raw_signed_transaction(multisig_tx_id)) diff --git a/test/functional/wallet_watch_address.py b/test/functional/wallet_watch_address.py index 289d758a44..dd7e487310 100644 --- a/test/functional/wallet_watch_address.py +++ b/test/functional/wallet_watch_address.py @@ -109,7 +109,7 @@ async def async_test(self): if store_tx_in_wallet: assert_in(f"Coins amount: {coins_to_send}", await wallet.get_balance(utxo_states=['inactive'])) else: - assert_in(f"Coins amount: 0", await wallet.get_balance(utxo_states=['inactive'])) + assert_in("Coins amount: 0", await wallet.get_balance(utxo_states=['inactive'])) assert node.mempool_contains_tx(receive_coins_tx_id) @@ -145,7 +145,7 @@ async def async_test(self): # send coins to that address output = await wallet.send_to_address(address_from_wallet1, 1) assert_in("The transaction was submitted successfully", output) - receive_coins_tx_id = output.splitlines()[1] + receive_coins_tx_id = output.splitlines()[-1] # check in wallet2 await wallet.close_wallet() @@ -173,7 +173,7 @@ async def async_test(self): other_address = await wallet.new_address() output = await wallet.send_to_address(other_address, 0.1) assert_in("The transaction was submitted successfully", output) - send_coins_tx_id = output.splitlines()[1] + send_coins_tx_id = output.splitlines()[-1] # go back to wallet 2 diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index b083bfbe24..275cb56328 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -129,14 +129,14 @@ where let status_text = if new_tx.broadcasted { let summary = new_tx.tx.take().transaction().text_summary(chain_config); format!( - "The transaction:\n{summary}\nWas submitted successfully with ID:\n{}", + "{summary}\nThe transaction was submitted successfully with ID:\n{}", id_to_hex_string(*new_tx.tx_id.as_hash()) ) } else { let hex = new_tx.tx.to_string(); let summary = new_tx.tx.take().transaction().text_summary(chain_config); - format!("The transaction:\n{summary}\nWas created and ready to be submitted:\n{hex}",) + format!("{summary}\nThe transaction was created and ready to be submitted:\n{hex}",) }; ConsoleCommand::Print(status_text) diff --git a/wallet/wallet-cli-lib/tests/basic.rs b/wallet/wallet-cli-lib/tests/basic.rs index c2be6d7050..199d2b3f02 100644 --- a/wallet/wallet-cli-lib/tests/basic.rs +++ b/wallet/wallet-cli-lib/tests/basic.rs @@ -109,7 +109,7 @@ async fn produce_blocks_decommission_genesis_pool(#[case] seed: Seed) { rng.gen_range(1..100), address, ),) - .starts_with("The transaction was submitted successfully with ID")); + .contains("The transaction was submitted successfully with ID")); // create some blocks assert_eq!(test.exec("node-generate-blocks 20"), "Success"); @@ -123,7 +123,7 @@ async fn produce_blocks_decommission_genesis_pool(#[case] seed: Seed) { assert_eq!(test.exec("account-select 0"), "Success"); assert!(test .exec(&format!("address-send {} 50000", acc2_address)) - .starts_with("The transaction was submitted successfully with ID")); + .contains("The transaction was submitted successfully with ID")); // create a block assert_eq!(test.exec("node-generate-blocks 1"), "Success"); @@ -135,7 +135,7 @@ async fn produce_blocks_decommission_genesis_pool(#[case] seed: Seed) { rng.gen_range(1..100), address, ),) - .starts_with("The transaction was submitted successfully with ID")); + .contains("The transaction was submitted successfully with ID")); assert_eq!(test.exec("account-select 0"), "Success"); // create some blocks @@ -167,7 +167,7 @@ async fn produce_blocks_decommission_genesis_pool(#[case] seed: Seed) { assert_eq!(test.exec("wallet-sync"), "Success"); assert!(test .exec(&format!("node-submit-transaction {signed_tx}")) - .starts_with("The transaction was submitted successfully with ID")); + .contains("The transaction was submitted successfully with ID")); // stake with the other acc assert_eq!(test.exec("account-select 1"), "Success"); diff --git a/wallet/wallet-rpc-daemon/docs/RPC.md b/wallet/wallet-rpc-daemon/docs/RPC.md index 3169b28a3c..6417501584 100644 --- a/wallet/wallet-rpc-daemon/docs/RPC.md +++ b/wallet/wallet-rpc-daemon/docs/RPC.md @@ -2380,7 +2380,21 @@ Parameters: Returns: ``` -{ "tx_id": hex string } +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `node_version` From b92ef5fd0c76561a45505aa8d84c79aae937db8c Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Thu, 24 Apr 2025 10:14:55 +0200 Subject: [PATCH 5/8] move create HTLC to return tx fees --- wallet/src/wallet/mod.rs | 21 ++----------------- wallet/src/wallet/tests.rs | 6 ++++-- wallet/types/src/lib.rs | 10 ++++----- .../src/command_handler/mod.rs | 2 +- wallet/wallet-cli-commands/src/lib.rs | 9 +++++--- .../wallet-controller/src/runtime_wallet.rs | 2 +- .../src/synced_controller.rs | 13 +++++++++--- wallet/wallet-controller/src/types/mod.rs | 3 +-- .../src/handles_client/mod.rs | 3 +-- .../src/rpc_client/client_impl.rs | 2 +- .../src/wallet_rpc_traits.rs | 2 +- wallet/wallet-rpc-lib/src/rpc/interface.rs | 2 +- wallet/wallet-rpc-lib/src/rpc/mod.rs | 3 ++- wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 5 ++--- 14 files changed, 38 insertions(+), 45 deletions(-) diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 2ec0507ee8..2a1001996c 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -1178,23 +1178,6 @@ where ) } - fn for_account_rw_unlocked_and_check_tx( - &mut self, - account_index: U31, - additional_info: TxAdditionalInfo, - f: impl FnOnce(&mut Account, &mut StoreTxRwUnlocked) -> WalletResult, - ) -> WalletResult { - Ok(self - .for_account_rw_unlocked_and_check_tx_generic( - account_index, - additional_info, - |account, db_tx| Ok((f(account, db_tx)?, ())), - |err| err, - )? - .0 - .tx) - } - fn for_account_rw_unlocked_and_check_tx_with_fees( &mut self, account_index: U31, @@ -2134,9 +2117,9 @@ where current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx( + self.for_account_rw_unlocked_and_check_tx_with_fees( account_index, additional_info, |account, db_tx| { diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index 1a67602877..f693d8e2d6 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -5579,7 +5579,8 @@ fn create_htlc_and_spend(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); let (_, block2) = create_block( &chain_config, @@ -5719,7 +5720,8 @@ fn create_htlc_and_refund(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) - .unwrap(); + .unwrap() + .tx; let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); let refund_tx = Transaction::new( diff --git a/wallet/types/src/lib.rs b/wallet/types/src/lib.rs index 71b2fe8cdf..049cbefa07 100644 --- a/wallet/types/src/lib.rs +++ b/wallet/types/src/lib.rs @@ -28,20 +28,20 @@ pub mod wallet_tx; pub mod wallet_type; pub mod with_locked; -use std::collections::BTreeMap; - pub use account_id::{ AccountDerivationPathId, AccountId, AccountKeyPurposeId, AccountWalletCreatedTxId, AccountWalletTxId, }; pub use account_info::AccountInfo; +pub use currency::Currency; +pub use keys::{KeyPurpose, KeychainUsageState, RootKeys}; +pub use wallet_tx::{BlockInfo, WalletTx}; + use common::{ chain::{SignedTransaction, Transaction}, primitives::Amount, }; -pub use currency::Currency; -pub use keys::{KeyPurpose, KeychainUsageState, RootKeys}; -pub use wallet_tx::{BlockInfo, WalletTx}; +use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SignedTxWithFees { diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index 275cb56328..abf9940b36 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -136,7 +136,7 @@ where let hex = new_tx.tx.to_string(); let summary = new_tx.tx.take().transaction().text_summary(chain_config); - format!("{summary}\nThe transaction was created and ready to be submitted:\n{hex}",) + format!("{summary}\nThe transaction was created and is ready to be submitted:\n{hex}",) }; ConsoleCommand::Print(status_text) diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index 4fe882abaf..14a4e7c3ee 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -394,9 +394,12 @@ pub enum WalletCommand { #[command(flatten)] ColdCommands(ColdWalletCommand), - /// Configure broadcasting to Mempool to true of false. - /// By default it is set to true. If set to false, any command that creates a transaction will - /// return it to the user and will need to be submitted manually with the command `node-submit-transaction` + /// Configure broadcasting to Mempool to true or false. + /// + /// If set to false, any command that creates a transaction will return it to the user and not submit it automatically. + /// The transaction will need to be submitted manually with the command `node-submit-transaction`. + /// + /// The effect of this is not preserved when the CLI wallet is closed. #[clap(name = "config-broadcast")] ConfigBroadcast { broadcast: bool }, diff --git a/wallet/wallet-controller/src/runtime_wallet.rs b/wallet/wallet-controller/src/runtime_wallet.rs index 61a915aea3..cf0a5670ea 100644 --- a/wallet/wallet-controller/src/runtime_wallet.rs +++ b/wallet/wallet-controller/src/runtime_wallet.rs @@ -1123,7 +1123,7 @@ impl RuntimeWallet { current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, - ) -> WalletResult { + ) -> WalletResult { match self { RuntimeWallet::Software(w) => w.create_htlc_tx( account_index, diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index 2d18c5a9bd..1c9aa47cd4 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -1113,11 +1113,11 @@ where output_value: OutputValue, htlc: HashedTimelockContract, additional_info: TxAdditionalInfo, - ) -> Result> { + ) -> Result> { let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; - let result = self.wallet.create_htlc_tx( + let SignedTxWithFees { tx, fees } = self.wallet.create_htlc_tx( self.account_index, output_value, htlc, @@ -1125,7 +1125,14 @@ where consolidate_fee_rate, additional_info, )?; - Ok(result) + + let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; + + Ok(NewTransaction { + tx, + fees, + broadcasted: false, + }) } pub async fn create_order( diff --git a/wallet/wallet-controller/src/types/mod.rs b/wallet/wallet-controller/src/types/mod.rs index 11219fe28d..683856b037 100644 --- a/wallet/wallet-controller/src/types/mod.rs +++ b/wallet/wallet-controller/src/types/mod.rs @@ -35,9 +35,8 @@ use common::{ }; pub use seed_phrase::SeedWithPassPhrase; pub use standalone_key::AccountStandaloneKeyDetails; -pub use transaction::NewTransaction; pub use transaction::{ - InspectTransaction, SignatureStats, TransactionToInspect, ValidatedSignatures, + InspectTransaction, NewTransaction, SignatureStats, TransactionToInspect, ValidatedSignatures, }; use utils::ensure; use wallet::signer::trezor_signer::FoundDevice; diff --git a/wallet/wallet-rpc-client/src/handles_client/mod.rs b/wallet/wallet-rpc-client/src/handles_client/mod.rs index 8ac4baf004..6f381c5353 100644 --- a/wallet/wallet-rpc-client/src/handles_client/mod.rs +++ b/wallet/wallet-rpc-client/src/handles_client/mod.rs @@ -1093,7 +1093,7 @@ where token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result, Self::Error> { + ) -> Result { self.wallet_rpc .create_htlc_transaction( account_index, @@ -1103,7 +1103,6 @@ where config, ) .await - .map(HexEncoded::new) .map_err(WalletRpcHandlesClientError::WalletRpcError) } diff --git a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs index 044bfd649e..fd43af2f16 100644 --- a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs +++ b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs @@ -1014,7 +1014,7 @@ impl WalletInterface for ClientWalletRpc { token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result, Self::Error> { + ) -> Result { let options = TransactionOptions::from_controller_config(&config); WalletRpcClient::create_htlc_transaction( &self.http_client, diff --git a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs index e5c8270388..c3778bbc72 100644 --- a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs +++ b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs @@ -501,7 +501,7 @@ pub trait WalletInterface { token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result, Self::Error>; + ) -> Result; #[allow(clippy::too_many_arguments)] async fn create_order( diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index 25de938ce5..90ae2625d0 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -736,7 +736,7 @@ trait WalletRpc { token_id: Option>, htlc: RpcHashedTimelockContract, options: TransactionOptions, - ) -> rpc::RpcResult>; + ) -> rpc::RpcResult; /// Create an order for exchanging "given" amount of an arbitrary currency (coins or tokens) for /// an arbitrary amount of "asked" currency. diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index 12f449d92c..b8f7aeac5f 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -1512,7 +1512,7 @@ where token_id: Option>, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let secret_hash = HtlcSecretHash::decode_all(&mut htlc.secret_hash.as_bytes()) .map_err(|_| RpcError::InvalidHtlcSecretHash)?; @@ -1572,6 +1572,7 @@ where .create_htlc_tx(value, htlc, additional_info) .await .map_err(RpcError::Controller) + .map(RpcNewTransaction::new) }) }) .await? diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index bd9565dea6..9d8df367f9 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -1104,7 +1104,7 @@ where token_id: Option>, htlc: RpcHashedTimelockContract, options: TransactionOptions, - ) -> rpc::RpcResult> { + ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, @@ -1112,8 +1112,7 @@ where rpc::handle_result( self.create_htlc_transaction(account_arg.index::()?, amount, token_id, htlc, config) - .await - .map(HexEncoded::new), + .await, ) } From 5061c534b7bd8be2419f9f03ff4816842afe89a7 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Sat, 26 Apr 2025 15:19:10 +0200 Subject: [PATCH 6/8] fix comments --- .../test_framework/wallet_cli_controller.py | 5 +-- .../test_framework/wallet_rpc_controller.py | 28 +++++++++++----- test/functional/wallet_htlc_refund.py | 28 ++++++++-------- test/functional/wallet_htlc_spend.py | 18 +++++----- test/functional/wallet_sweep_address.py | 4 +-- wallet/src/account/mod.rs | 3 +- wallet/src/wallet/tests.rs | 33 ++++++++----------- .../src/command_handler/mod.rs | 10 ++++-- wallet/wallet-cli-commands/src/lib.rs | 5 ++- .../src/synced_controller.rs | 6 ++-- wallet/wallet-controller/src/types/mod.rs | 16 +++++++++ .../src/handles_client/mod.rs | 2 ++ .../src/rpc_client/client_impl.rs | 4 +-- .../src/wallet_rpc_traits.rs | 1 + wallet/wallet-rpc-daemon/docs/RPC.md | 25 +++++++++++--- wallet/wallet-rpc-lib/src/rpc/interface.rs | 7 ++-- wallet/wallet-rpc-lib/src/rpc/mod.rs | 25 ++++++++++---- wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 9 ++--- 18 files changed, 144 insertions(+), 85 deletions(-) diff --git a/test/functional/test_framework/wallet_cli_controller.py b/test/functional/test_framework/wallet_cli_controller.py index 77fe7965fa..691fcb75c8 100644 --- a/test/functional/test_framework/wallet_cli_controller.py +++ b/test/functional/test_framework/wallet_cli_controller.py @@ -301,8 +301,9 @@ async def create_from_cold_address(self, address: str, amount: int, selected_utx change_address_str = '' if change_address is None else f"--change {change_address}" return await self._write_command(f"transaction-create-from-cold-input {address} {amount} {str(selected_utxo)} {change_address_str}\n") - async def sweep_addresses(self, destination_address: str, from_addresses: List[str] = []) -> str: - return await self._write_command(f"address-sweep-spendable {destination_address} {' '.join(from_addresses)}\n") + async def sweep_addresses(self, destination_address: str, from_addresses: List[str] = [], all_addresses: bool = False) -> str: + all_addresses_str = "--all" if all_addresses else "" + return await self._write_command(f"address-sweep-spendable {destination_address} {' '.join(from_addresses)} {all_addresses_str}\n") async def sweep_delegation(self, destination_address: str, delegation_id: str) -> str: return await self._write_command(f"staking-sweep-delegation {destination_address} {delegation_id}\n") diff --git a/test/functional/test_framework/wallet_rpc_controller.py b/test/functional/test_framework/wallet_rpc_controller.py index aaa28863d4..95bda8ab74 100644 --- a/test/functional/test_framework/wallet_rpc_controller.py +++ b/test/functional/test_framework/wallet_rpc_controller.py @@ -25,7 +25,7 @@ import base64 from operator import itemgetter -from typing import Optional, List, Union +from typing import Optional, List, Union, TypedDict from test_framework.util import assert_in, rpc_port from test_framework.wallet_controller_common import PartialSigInfo, TokenTxOutput, UtxoOutpoint, WalletCliControllerBase @@ -46,6 +46,16 @@ def to_json(self): else: return {'Transfer': [ { 'Coin': {"atoms": str(self.atoms)} }, f"HexifiedDestination{{0x02{self.pub_key_hex}}}" ]} +@dataclass +class Balances: + coins: str + tokens: dict + +class NewTxResult(TypedDict): + tx_id: str + tx: str + fees: Balances + broadcasted: bool @dataclass class PoolData: @@ -295,7 +305,7 @@ async def issue_new_token(self, else: return None, None, result['error'] - async def mint_tokens(self, token_id: str, address: str, amount: int) -> str: + async def mint_tokens(self, token_id: str, address: str, amount: int) -> NewTxResult: return self._write_command("token_mint", [self.account, token_id, address, {'decimal': str(amount)}, {'in_top_x_mb': 5}])['result'] # Note: unlike mint_tokens, this function behaves identically both for wallet_cli_controller and wallet_rpc_controller. @@ -303,22 +313,22 @@ async def mint_tokens_or_fail(self, token_id: str, address: str, amount: int): # self.mint_tokens already fails on error await self.mint_tokens(token_id, address, amount) - async def unmint_tokens(self, token_id: str, amount: int) -> str: + async def unmint_tokens(self, token_id: str, amount: int) -> NewTxResult: return self._write_command("token_unmint", [self.account, token_id, {'decimal': str(amount)}, {'in_top_x_mb': 5}])['result'] - async def lock_token_supply(self, token_id: str) -> str: + async def lock_token_supply(self, token_id: str) -> NewTxResult: return self._write_command("token_lock_supply", [self.account, token_id, {'in_top_x_mb': 5}])['result'] - async def freeze_token(self, token_id: str, is_unfreezable: str) -> str: + async def freeze_token(self, token_id: str, is_unfreezable: str) -> NewTxResult: return self._write_command("token_freeze", [self.account, token_id, is_unfreezable, {'in_top_x_mb': 5}])['result'] - async def unfreeze_token(self, token_id: str) -> str: + async def unfreeze_token(self, token_id: str) -> NewTxResult: return self._write_command("token_unfreeze", [self.account, token_id, {'in_top_x_mb': 5}])['result'] - async def change_token_authority(self, token_id: str, new_authority: str) -> str: + async def change_token_authority(self, token_id: str, new_authority: str) -> NewTxResult: return self._write_command("token_change_authority", [self.account, token_id, new_authority, {'in_top_x_mb': 5}])['result'] - async def change_token_metadata_uri(self, token_id: str, new_metadata_uri: str) -> str: + async def change_token_metadata_uri(self, token_id: str, new_metadata_uri: str) -> NewTxResult: return self._write_command("token_change_metadata_uri", [self.account, token_id, new_metadata_uri, {'in_top_x_mb': 5}])['result'] async def issue_new_nft(self, @@ -571,7 +581,7 @@ async def create_htlc_transaction(self, secret_hash: str, spend_address: str, refund_address: str, - refund_lock_for_blocks: int) -> str: + refund_lock_for_blocks: int) -> NewTxResult: timelock = { "type": "ForBlockCount", "content": refund_lock_for_blocks } htlc = { "secret_hash": secret_hash, "spend_address": spend_address, "refund_address": refund_address, "refund_timelock": timelock } object = [self.account, {'decimal': str(amount)}, token_id, htlc, {'in_top_x_mb': 5}] diff --git a/test/functional/wallet_htlc_refund.py b/test/functional/wallet_htlc_refund.py index 22edadf05a..ed0ff1db07 100644 --- a/test/functional/wallet_htlc_refund.py +++ b/test/functional/wallet_htlc_refund.py @@ -128,7 +128,7 @@ async def async_test(self): assert_equal(await wallet.get_best_block(), block_id) balance = await wallet.get_balance() - assert_in(f"Coins amount: 151", balance) + assert_in("Coins amount: 151", balance) assert_not_in("Tokens", balance) # issue a valid token @@ -142,7 +142,7 @@ async def async_test(self): self.generate_block() assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 50", balance) + assert_in("Coins amount: 50", balance) assert_not_in("Tokens", balance) amount_to_mint = random.randint(1, 10000) @@ -153,7 +153,7 @@ async def async_test(self): assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() print(balance) - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_in(f"Token: {token_id} amount: {amount_to_mint}", balance) ######################################################################################## @@ -165,7 +165,7 @@ async def async_test(self): alice_amount_to_swap = amount_to_mint alice_htlc_tx = await wallet.create_htlc_transaction(alice_amount_to_swap, token_id, alice_secret_hash, bob_address, refund_address, 6) - alice_signed_tx_obj = signed_tx_obj.decode(ScaleBytes("0x" + alice_htlc_tx)) + alice_signed_tx_obj = signed_tx_obj.decode(ScaleBytes("0x" + alice_htlc_tx['tx'])) alice_htlc_outputs = alice_signed_tx_obj['transaction']['outputs'] alice_htlc_change_dest = alice_htlc_outputs[1]['Transfer'][1] alice_htlc_tx_id = hash_object(base_tx_obj, alice_signed_tx_obj['transaction']) @@ -200,7 +200,7 @@ async def async_test(self): bob_amount_to_swap = 150 bob_htlc_tx = await wallet.create_htlc_transaction(bob_amount_to_swap, None, alice_secret_hash, alice_address, refund_address, 6) - bob_signed_tx_obj = signed_tx_obj.decode(ScaleBytes("0x" + bob_htlc_tx)) + bob_signed_tx_obj = signed_tx_obj.decode(ScaleBytes("0x" + bob_htlc_tx['tx'])) bob_htlc_outputs = bob_signed_tx_obj['transaction']['outputs'] bob_htlc_change_dest = bob_htlc_outputs[1]['Transfer'][1] bob_htlc_tx_id = hash_object(base_tx_obj, bob_signed_tx_obj['transaction']) @@ -227,7 +227,7 @@ async def async_test(self): alice_refund_ptx = output.split('\n')[2] # Alice's htlc tx can now be broadcasted - output = await wallet.submit_transaction(alice_htlc_tx) + output = await wallet.submit_transaction(alice_htlc_tx['tx']) assert_in("The transaction was submitted successfully", output) # Alice signs Bob's refund @@ -238,7 +238,7 @@ async def async_test(self): bob_refund_ptx = output.split('\n')[2] # Bob's htlc tx can now be broadcasted - output = await wallet.submit_transaction(bob_htlc_tx) + output = await wallet.submit_transaction(bob_htlc_tx['tx']) assert_in("The transaction was submitted successfully", output) self.generate_block() @@ -246,14 +246,14 @@ async def async_test(self): # Check Alice's balance balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) # Check Bob's balance now await self.switch_to_wallet(wallet, 'bob_wallet') assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) ######################################################################################## @@ -270,7 +270,7 @@ async def async_test(self): assert_in("Spending at height 9, locked until height 10", output) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) # Bob signs and spends the refund @@ -286,7 +286,7 @@ async def async_test(self): assert_in("Spending at height 9, locked until height 10", output) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) ######################################################################################## @@ -304,7 +304,7 @@ async def async_test(self): self.generate_block() assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) self.generate_block() @@ -316,13 +316,13 @@ async def async_test(self): await self.switch_to_wallet(wallet, 'alice_wallet') assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_in(f"Token: {token_id} amount: {alice_amount_to_swap}", balance) await self.switch_to_wallet(wallet, 'bob_wallet') assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 150", balance) + assert_in(f"Coins amount: {bob_amount_to_swap}", balance) assert_not_in("Tokens", balance) diff --git a/test/functional/wallet_htlc_spend.py b/test/functional/wallet_htlc_spend.py index ffb4cfce4a..44dea05df1 100644 --- a/test/functional/wallet_htlc_spend.py +++ b/test/functional/wallet_htlc_spend.py @@ -131,7 +131,7 @@ async def async_test(self): assert_equal(await wallet.get_best_block(), block_id) balance = await wallet.get_balance() - assert_in(f"Coins amount: 151", balance) + assert_in("Coins amount: 151", balance) assert_not_in("Tokens", balance) # issue a valid token @@ -142,7 +142,7 @@ async def async_test(self): self.generate_block() assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 50", balance) + assert_in("Coins amount: 50", balance) assert_not_in("Tokens", balance) amount_to_mint = random.randint(1, 10000) @@ -152,7 +152,7 @@ async def async_test(self): self.generate_block() assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_in(f"Token: {token_id} amount: {amount_to_mint}", balance) ######################################################################################## @@ -164,7 +164,7 @@ async def async_test(self): alice_amount_to_swap = amount_to_mint refund_address = await wallet.add_standalone_multisig_address(2, [alice_pub_key, bob_pub_key], None) alice_htlc_tx = await wallet.create_htlc_transaction(alice_amount_to_swap, token_id, alice_secret_hash, bob_address, refund_address, 2) - output = await wallet.submit_transaction(alice_htlc_tx) + output = await wallet.submit_transaction(alice_htlc_tx['tx']) alice_htlc_tx_id = output.split('\n')[2] self.generate_block() assert_in("Success", await wallet.sync()) @@ -175,7 +175,7 @@ async def async_test(self): bob_amount_to_swap = 150 bob_htlc_tx = await wallet.create_htlc_transaction(bob_amount_to_swap, None, alice_secret_hash, alice_address, refund_address, 2) - output = await wallet.submit_transaction(bob_htlc_tx) + output = await wallet.submit_transaction(bob_htlc_tx['tx']) bob_htlc_tx_id = output.split('\n')[2] self.generate_block() assert_in("Success", await wallet.sync()) @@ -189,7 +189,7 @@ async def async_test(self): random_secret_hex = random_secret.hex() balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) # Alice can't spend Alice's htlc without a secret @@ -214,7 +214,7 @@ async def async_test(self): assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_not_in("Tokens", balance) # Bob can't spend it without secret @@ -264,7 +264,7 @@ async def async_test(self): assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 150", balance) + assert_in(f"Coins amount: {bob_amount_to_swap}", balance) assert_not_in("Tokens", balance) ######################################################################################## @@ -283,7 +283,7 @@ async def async_test(self): assert_in("Success", await wallet.sync()) balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) assert_in(f"Token: {token_id} amount: {alice_amount_to_swap}", balance) diff --git a/test/functional/wallet_sweep_address.py b/test/functional/wallet_sweep_address.py index a6cb39db97..3dbfde8837 100644 --- a/test/functional/wallet_sweep_address.py +++ b/test/functional/wallet_sweep_address.py @@ -149,14 +149,14 @@ def make_locked_output(pub_key_bytes): acc1_address = await wallet.new_address() await wallet.select_account(0) - assert_in("The transaction was submitted successfully", await wallet.sweep_addresses(acc1_address, addresses)) + assert_in("The transaction was submitted successfully", await wallet.sweep_addresses(acc1_address, all_addresses=True)) block_id = self.generate_block() assert_in("Success", await wallet.sync()) # check we sent all our coins balance = await wallet.get_balance() - assert_in(f"Coins amount: 0", balance) + assert_in("Coins amount: 0", balance) # check we still have the locked balance balance = await wallet.get_balance('locked') diff --git a/wallet/src/account/mod.rs b/wallet/src/account/mod.rs index 6c72e630dc..e7395ddb6e 100644 --- a/wallet/src/account/mod.rs +++ b/wallet/src/account/mod.rs @@ -532,7 +532,7 @@ impl Account { pub fn sweep_addresses( &mut self, destination: Destination, - request: SendRequest, + mut request: SendRequest, current_fee_rate: FeeRate, ) -> WalletResult { let mut grouped_inputs = group_preselected_inputs( @@ -592,6 +592,7 @@ impl Account { destination, ); outputs.push(coin_output); + request.add_fee(Currency::Coin, total_fee)?; Ok(request.with_outputs(outputs)) } diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index f693d8e2d6..5a79d8a55a 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -1484,7 +1484,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { .collect(); let feerate = FeeRate::from_amount_per_kb(Amount::from_atoms(rng.gen_range(1..1000))); - let transaction = wallet + let SignedTxWithFees { tx, fees } = wallet .create_transaction_to_addresses( DEFAULT_ACCOUNT_INDEX, outputs, @@ -1494,10 +1494,9 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) - .unwrap() - .tx; + .unwrap(); - let tx_size = serialization::Encode::encoded_size(&transaction); + let tx_size = serialization::Encode::encoded_size(&tx); // 16 bytes (u128) is the max tx size difference in the estimation, // because of the compact encoding for the change amount which is unknown beforehand @@ -1507,11 +1506,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { // register the successful transaction and check the balance wallet - .add_account_unconfirmed_tx( - DEFAULT_ACCOUNT_INDEX, - transaction.clone(), - &WalletEventsNoOp, - ) + .add_account_unconfirmed_tx(DEFAULT_ACCOUNT_INDEX, tx.clone(), &WalletEventsNoOp) .unwrap(); let coin_balance1 = get_coin_balance_with_inactive(&wallet); let expected_balance_max = @@ -1521,6 +1516,10 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { assert!(coin_balance1 >= expected_balance_min); assert!(coin_balance1 <= expected_balance_max); + let fee = *fees.get(&Currency::Coin).unwrap(); + eprintln!("{fee:?} {min_fee:?} {max_fee:?}"); + assert!(fee >= *min_fee); + assert!(fee <= *max_fee); let selected_utxos = wallet .get_utxos( @@ -1543,7 +1542,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { let account1 = wallet.create_next_account(None).unwrap().0; let address2 = wallet.get_new_address(account1).unwrap().1.into_object(); let feerate = FeeRate::from_amount_per_kb(Amount::from_atoms(rng.gen_range(1..1000))); - let transaction = wallet + let SignedTxWithFees { tx, fees } = wallet .create_sweep_transaction( DEFAULT_ACCOUNT_INDEX, address2, @@ -1551,19 +1550,14 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) - .unwrap() - .tx; + .unwrap(); - let tx_size = serialization::Encode::encoded_size(&transaction); + let tx_size = serialization::Encode::encoded_size(&tx); let exact_fee = feerate.compute_fee(tx_size).unwrap(); // register the successful transaction and check the balance wallet - .add_account_unconfirmed_tx( - DEFAULT_ACCOUNT_INDEX, - transaction.clone(), - &WalletEventsNoOp, - ) + .add_account_unconfirmed_tx(DEFAULT_ACCOUNT_INDEX, tx.clone(), &WalletEventsNoOp) .unwrap(); let coin_balance2 = get_coin_balance_with_inactive(&wallet); // sweep pays fees from the transfer amount itself @@ -1571,7 +1565,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { // add the tx to the new account and check the balance wallet - .add_account_unconfirmed_tx(account1, transaction.clone(), &WalletEventsNoOp) + .add_account_unconfirmed_tx(account1, tx.clone(), &WalletEventsNoOp) .unwrap(); let coin_balance3 = wallet @@ -1588,6 +1582,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { // the sweep command should pay exactly the correct fee as it has no change outputs let expected_balance3 = (amount_to_transfer - exact_fee.into()).unwrap(); assert_eq!(coin_balance3, expected_balance3); + assert_eq!(*exact_fee, *fees.get(&Currency::Coin).unwrap()); } #[test] diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index abf9940b36..6616680402 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -127,14 +127,17 @@ where pub fn new_tx_command(new_tx: RpcNewTransaction, chain_config: &ChainConfig) -> ConsoleCommand { let status_text = if new_tx.broadcasted { - let summary = new_tx.tx.take().transaction().text_summary(chain_config); + let mut summary = new_tx.tx.take().transaction().text_summary(chain_config); + format_fees(&mut summary, &new_tx.fees); + format!( "{summary}\nThe transaction was submitted successfully with ID:\n{}", id_to_hex_string(*new_tx.tx_id.as_hash()) ) } else { let hex = new_tx.tx.to_string(); - let summary = new_tx.tx.take().transaction().text_summary(chain_config); + let mut summary = new_tx.tx.take().transaction().text_summary(chain_config); + format_fees(&mut summary, &new_tx.fees); format!("{summary}\nThe transaction was created and is ready to be submitted:\n{hex}",) }; @@ -775,7 +778,7 @@ where } WalletCommand::ConfigBroadcast { broadcast } => { - self.config.broadcast_to_mempool = broadcast; + self.config.broadcast_to_mempool = broadcast.to_bool(); Ok(ConsoleCommand::Print(format!( "Broadcast to Mempool set to: {broadcast:?}" ))) @@ -1400,6 +1403,7 @@ where selected_account, destination_address, addresses, + all, self.config, ) .await?; diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index 14a4e7c3ee..bbac5b7d54 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -401,7 +401,10 @@ pub enum WalletCommand { /// /// The effect of this is not preserved when the CLI wallet is closed. #[clap(name = "config-broadcast")] - ConfigBroadcast { broadcast: bool }, + ConfigBroadcast { + #[arg(value_enum)] + broadcast: YesNo, + }, #[clap(name = "account-create")] CreateNewAccount { name: Option }, diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index 1c9aa47cd4..9fcc359639 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -68,7 +68,7 @@ use wallet_types::{ use crate::{ helpers::{fetch_token_info, fetch_utxo, into_balances, tx_to_partially_signed_tx}, runtime_wallet::RuntimeWallet, - types::{Balances, GenericCurrencyTransfer, NewTransaction}, + types::{Balances, GenericCurrencyTransfer, NewTransaction, SweepFromAddresses}, ControllerConfig, ControllerError, }; @@ -568,7 +568,7 @@ where pub async fn sweep_addresses( &mut self, destination_address: Destination, - from_addresses: BTreeSet, + from_addresses: SweepFromAddresses, ) -> Result> { let selected_utxos = self.wallet.get_utxos( self.account_index, @@ -584,7 +584,7 @@ where .into_iter() .filter(|(_, output)| { get_tx_output_destination(output, &|_| None, HtlcSpendingCondition::Skip) - .is_some_and(|dest| from_addresses.is_empty() || from_addresses.contains(&dest)) + .is_some_and(|dest| from_addresses.should_sweep_address(&dest)) }) .collect::>(); diff --git a/wallet/wallet-controller/src/types/mod.rs b/wallet/wallet-controller/src/types/mod.rs index 683856b037..3372063802 100644 --- a/wallet/wallet-controller/src/types/mod.rs +++ b/wallet/wallet-controller/src/types/mod.rs @@ -21,6 +21,8 @@ mod seed_phrase; mod standalone_key; mod transaction; +use std::collections::BTreeSet; + pub use balances::Balances; use bip39::{Language, Mnemonic}; pub use block_info::{BlockInfo, CreatedBlockInfo}; @@ -247,3 +249,17 @@ pub enum WalletTypeArgsComputed { #[cfg(feature = "trezor")] Trezor { device_id: Option }, } + +pub enum SweepFromAddresses { + All, + SpecificAddresses(BTreeSet), +} + +impl SweepFromAddresses { + pub fn should_sweep_address(&self, dest: &Destination) -> bool { + match self { + Self::All => true, + Self::SpecificAddresses(destinations) => destinations.contains(dest), + } + } +} diff --git a/wallet/wallet-rpc-client/src/handles_client/mod.rs b/wallet/wallet-rpc-client/src/handles_client/mod.rs index 6f381c5353..6b6a14fdac 100644 --- a/wallet/wallet-rpc-client/src/handles_client/mod.rs +++ b/wallet/wallet-rpc-client/src/handles_client/mod.rs @@ -607,6 +607,7 @@ where account_index: U31, destination_address: String, from_addresses: Vec, + all: bool, config: ControllerConfig, ) -> Result { self.wallet_rpc @@ -614,6 +615,7 @@ where account_index, destination_address.into(), from_addresses.into_iter().map(Into::into).collect(), + all, config, ) .await diff --git a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs index fd43af2f16..52b456ec22 100644 --- a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs +++ b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs @@ -475,16 +475,16 @@ impl WalletInterface for ClientWalletRpc { account_index: U31, destination_address: String, from_addresses: Vec, + all: bool, config: ControllerConfig, ) -> Result { let options = TransactionOptions::from_controller_config(&config); - let all = from_addresses.is_empty(); WalletRpcClient::sweep_addresses( &self.http_client, account_index.into(), destination_address.into(), from_addresses.into_iter().map(Into::into).collect(), - Some(all), + all, options, ) .await diff --git a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs index c3778bbc72..ab472cc1b4 100644 --- a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs +++ b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs @@ -264,6 +264,7 @@ pub trait WalletInterface { account_index: U31, destination_address: String, from_addresses: Vec, + all: bool, config: ControllerConfig, ) -> Result; diff --git a/wallet/wallet-rpc-daemon/docs/RPC.md b/wallet/wallet-rpc-daemon/docs/RPC.md index 6417501584..b92603c317 100644 --- a/wallet/wallet-rpc-daemon/docs/RPC.md +++ b/wallet/wallet-rpc-daemon/docs/RPC.md @@ -999,7 +999,10 @@ Returns: ### Method `address_sweep_spendable` -Sweep all spendable coins or tokens from an address or addresses to a given address. +Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` +or all addresses from this account if all is set to true, to a given destination address. +Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or +`from_addresses` needs to be empty and all set to true. Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. The wallet will automatically calculate the required fees @@ -1010,9 +1013,7 @@ Parameters: "account": number, "destination_address": bech32 string, "from_addresses": [ bech32 string, .. ], - "all": EITHER OF - 1) bool - 2) null, + "all": bool, "options": { "in_top_x_mb": EITHER OF 1) number 2) null }, @@ -2205,7 +2206,21 @@ Parameters: Returns: ``` -hex string +{ + "tx_id": hex string, + "tx": hex string, + "fees": { + "coins": { + "atoms": number string, + "decimal": decimal string, + }, + "tokens": { bech32 string: { + "atoms": number string, + "decimal": decimal string, + }, .. }, + }, + "broadcasted": bool, +} ``` ### Method `create_order` diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index 90ae2625d0..2d0746382c 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -381,7 +381,10 @@ trait WalletRpc { options: TransactionOptions, ) -> rpc::RpcResult; - /// Sweep all spendable coins or tokens from an address or addresses to a given address. + /// Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` + /// or all addresses from this account if all is set to true, to a given destination address. + /// Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or + /// `from_addresses` needs to be empty and all set to true. /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. /// The wallet will automatically calculate the required fees #[method(name = "address_sweep_spendable")] @@ -390,7 +393,7 @@ trait WalletRpc { account: AccountArg, destination_address: RpcAddress, from_addresses: Vec>, - all: Option, + all: bool, options: TransactionOptions, ) -> rpc::RpcResult; diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index b8f7aeac5f..79aabd9b26 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -76,8 +76,8 @@ pub use rpc::{rpc_creds::RpcCreds, Rpc}; use wallet_controller::{ types::{ Balances, BlockInfo, CreatedBlockInfo, CreatedWallet, GenericTokenTransfer, - InspectTransaction, NewTransaction, OpenedWallet, SeedWithPassPhrase, TransactionToInspect, - WalletCreationOptions, WalletInfo, WalletTypeArgs, + InspectTransaction, NewTransaction, OpenedWallet, SeedWithPassPhrase, SweepFromAddresses, + TransactionToInspect, WalletCreationOptions, WalletInfo, WalletTypeArgs, }, ConnectedPeer, ControllerConfig, ControllerError, NodeInterface, UtxoState, UtxoStates, UtxoType, UtxoTypes, DEFAULT_ACCOUNT_INDEX, @@ -923,16 +923,29 @@ where account_index: U31, destination_address: RpcAddress, from_addresses: Vec>, + all: bool, config: ControllerConfig, ) -> WRpcResult { + ensure!( + all && from_addresses.is_empty() || !all && !from_addresses.is_empty(), + RpcError::::InvalidSweepParameters + ); + let destination_address = destination_address .decode_object(&self.chain_config) .map_err(|_| RpcError::InvalidAddress)?; - let from_addresses = from_addresses - .into_iter() - .map(|a| a.decode_object(&self.chain_config).map_err(|_| RpcError::InvalidAddress)) - .collect::, _>>()?; + let from_addresses = match all { + true => SweepFromAddresses::All, + false => SweepFromAddresses::SpecificAddresses( + from_addresses + .into_iter() + .map(|a| { + a.decode_object(&self.chain_config).map_err(|_| RpcError::InvalidAddress) + }) + .collect::, _>>()?, + ), + }; self.wallet .call_async(move |controller| { diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index 9d8df367f9..68c6bb7b48 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -29,7 +29,6 @@ use common::{ use crypto::{key::PrivateKey, vrf::VRFPublicKey}; use p2p_types::{bannable_address::BannableAddress, socket_address::SocketAddress, PeerId}; use serialization::{hex::HexEncode, json_encoded::JsonEncoded}; -use utils::ensure; use utils_networking::IpOrSocketAddress; use wallet::{account::TxInfo, version::get_version}; use wallet_controller::{ @@ -558,23 +557,19 @@ where account: AccountArg, destination_address: RpcAddress, from_addresses: Vec>, - all: Option, + all: bool, options: TransactionOptions, ) -> rpc::RpcResult { let config = ControllerConfig { in_top_x_mb: options.in_top_x_mb(), broadcast_to_mempool: true, }; - let all = all.unwrap_or(false); - ensure!( - all && from_addresses.is_empty() || !all && !from_addresses.is_empty(), - RpcError::::InvalidSweepParameters - ); rpc::handle_result( self.sweep_addresses( account.index::()?, destination_address, from_addresses, + all, config, ) .await, From 2d3714e6388528ae97b26b9d71fff33e480bed19 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Sat, 10 May 2025 14:58:41 +0200 Subject: [PATCH 7/8] fix added change --- wallet/src/account/mod.rs | 1 + wallet/types/src/lib.rs | 3 +- .../src/command_handler/mod.rs | 94 +++-- wallet/wallet-cli-commands/src/lib.rs | 40 ++- wallet/wallet-rpc-daemon/docs/RPC.md | 322 +++++++++++++----- wallet/wallet-rpc-lib/src/rpc/interface.rs | 3 +- wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 260 +++++--------- wallet/wallet-rpc-lib/src/rpc/types.rs | 23 +- wallet/wallet-rpc-lib/tests/basic.rs | 1 + 9 files changed, 436 insertions(+), 311 deletions(-) diff --git a/wallet/src/account/mod.rs b/wallet/src/account/mod.rs index e7395ddb6e..66b32c1486 100644 --- a/wallet/src/account/mod.rs +++ b/wallet/src/account/mod.rs @@ -444,6 +444,7 @@ impl Account { selection_result = selection_result.add_change( (total_fees_not_paid - new_total_fees_not_paid).unwrap_or(Amount::ZERO), )?; + let change_amount = selection_result.get_change(); let change_output = match pay_fee_with_currency { Currency::Coin => make_address_output(change_address.clone(), change_amount), Currency::Token(token_id) => { diff --git a/wallet/types/src/lib.rs b/wallet/types/src/lib.rs index 049cbefa07..7ab6dc057b 100644 --- a/wallet/types/src/lib.rs +++ b/wallet/types/src/lib.rs @@ -37,11 +37,12 @@ pub use currency::Currency; pub use keys::{KeyPurpose, KeychainUsageState, RootKeys}; pub use wallet_tx::{BlockInfo, WalletTx}; +use std::collections::BTreeMap; + use common::{ chain::{SignedTransaction, Transaction}, primitives::Amount, }; -use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SignedTxWithFees { diff --git a/wallet/wallet-cli-commands/src/command_handler/mod.rs b/wallet/wallet-cli-commands/src/command_handler/mod.rs index 6616680402..071895167b 100644 --- a/wallet/wallet-cli-commands/src/command_handler/mod.rs +++ b/wallet/wallet-cli-commands/src/command_handler/mod.rs @@ -135,11 +135,7 @@ where id_to_hex_string(*new_tx.tx_id.as_hash()) ) } else { - let hex = new_tx.tx.to_string(); - let mut summary = new_tx.tx.take().transaction().text_summary(chain_config); - format_fees(&mut summary, &new_tx.fees); - - format!("{summary}\nThe transaction was created and is ready to be submitted:\n{hex}",) + format_tx_to_be_broadcasted(new_tx.tx, &new_tx.fees, chain_config) }; ConsoleCommand::Print(status_text) @@ -1127,11 +1123,17 @@ where ) .await?; - Ok(ConsoleCommand::Print(format!( - "A new token has been issued with ID: {} in tx: {}", - new_token.token_id, - id_to_hex_string(*new_token.tx_id.as_hash()) - ))) + let result = if new_token.broadcasted { + format!( + "A new token has been issued with ID: {} in tx: {}", + new_token.token_id, + id_to_hex_string(*new_token.tx_id.as_hash()) + ) + } else { + format_tx_to_be_broadcasted(new_token.tx, &new_token.fees, chain_config) + }; + + Ok(ConsoleCommand::Print(result)) } WalletCommand::IssueNewNft { @@ -1161,11 +1163,17 @@ where .issue_new_nft(selected_account, destination_address, metadata, self.config) .await?; - Ok(ConsoleCommand::Print(format!( - "A new NFT has been issued with ID: {} in tx: {}", - new_token.token_id, - id_to_hex_string(*new_token.tx_id.as_hash()) - ))) + let result = if new_token.broadcasted { + format!( + "A new NFT has been issued with ID: {} in tx: {}", + new_token.token_id, + id_to_hex_string(*new_token.tx_id.as_hash()) + ) + } else { + format_tx_to_be_broadcasted(new_token.tx, &new_token.fees, chain_config) + }; + + Ok(ConsoleCommand::Print(result)) } WalletCommand::MintTokens { @@ -1640,15 +1648,24 @@ where WalletCommand::CreateDelegation { owner, pool_id } => { let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; - let delegation_id = wallet - .create_delegation(selected_account, owner, pool_id, self.config) - .await? - .delegation_id; + let new_delegation = + wallet.create_delegation(selected_account, owner, pool_id, self.config).await?; - Ok(ConsoleCommand::Print(format!( - "Success, the creation of delegation transaction was broadcast to the network. Delegation id: {}", - delegation_id - ))) + let result = if new_delegation.broadcasted { + format!( + "Success, the creation of delegation transaction was broadcast to the network. Delegation id: {} in tx: {}", + new_delegation.delegation_id, + id_to_hex_string(*new_delegation.tx_id.as_hash()) + ) + } else { + format_tx_to_be_broadcasted( + new_delegation.tx, + &new_delegation.fees, + chain_config, + ) + }; + + Ok(ConsoleCommand::Print(result)) } WalletCommand::DelegateStaking { @@ -1656,14 +1673,18 @@ where delegation_id, } => { let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; - wallet + let new_tx = wallet .delegate_staking(selected_account, amount, delegation_id, self.config) .await?; - Ok(ConsoleCommand::Print( + let result = if new_tx.broadcasted { "Success, the delegation staking transaction was broadcast to the network" - .to_owned(), - )) + .to_owned() + } else { + format_tx_to_be_broadcasted(new_tx.tx, &new_tx.fees, chain_config) + }; + + Ok(ConsoleCommand::Print(result)) } WalletCommand::WithdrawFromDelegation { @@ -1672,7 +1693,7 @@ where delegation_id, } => { let (wallet, selected_account) = wallet_and_selected_acc(&mut self.wallet).await?; - wallet + let new_tx = wallet .withdraw_from_delegation( selected_account, address, @@ -1681,9 +1702,8 @@ where self.config, ) .await?; - Ok(ConsoleCommand::Print( - "Success. The transaction was broadcast to the network".to_owned(), - )) + + Ok(Self::new_tx_command(new_tx, chain_config)) } WalletCommand::CreateStakePool { @@ -1923,6 +1943,18 @@ where } } +fn format_tx_to_be_broadcasted( + tx: HexEncoded, + fees: &Balances, + chain_config: &ChainConfig, +) -> String { + let hex = tx.to_string(); + let mut summary = tx.take().transaction().text_summary(chain_config); + format_fees(&mut summary, fees); + + format!("{summary}\nThe transaction was created and is ready to be submitted:\n{hex}") +} + fn format_signature_status((idx, status): (usize, &RpcSignatureStatus)) -> String { let status = match status { RpcSignatureStatus::FullySigned => "FullySigned".to_owned(), diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index bbac5b7d54..d4d664c428 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -394,9 +394,9 @@ pub enum WalletCommand { #[command(flatten)] ColdCommands(ColdWalletCommand), - /// Configure broadcasting to Mempool to true or false. + /// Configure broadcasting to Mempool to yes or no. /// - /// If set to false, any command that creates a transaction will return it to the user and not submit it automatically. + /// If set to no, any command that creates a transaction will return it to the user and not submit it automatically. /// The transaction will need to be submitted manually with the command `node-submit-transaction`. /// /// The effect of this is not preserved when the CLI wallet is closed. @@ -651,6 +651,13 @@ pub enum WalletCommand { }, #[clap(name = "address-sweep-spendable")] + /// Sweep all spendable coins or tokens from an address or addresses specified in `addresses` + /// or all addresses from this account if all is set to true, to the given destination address. + /// Either 1 or more addresses need to be specified in `addresses` without `all` being set, or + /// `addresses` needs to be empty and --all being set. + /// + /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. + /// The wallet will automatically calculate the required fees SweepFromAddress { /// The receiving address of the coins or tokens destination_address: String, @@ -1175,20 +1182,23 @@ pub fn get_repl_command(cold_wallet: bool, mutable_wallet: bool) -> Command { // Customize the help template for all commands to make it more REPL friendly for subcommand in repl_command.get_subcommands_mut() { - if let Some(desc) = - COLD_WALLET_DESC.methods.iter().chain(WALLET_DESC.methods).find_map(|method| { - method - .name - .split('_') - .zip(subcommand.get_name().split('-')) - .all(|(x, y)| x == y) - .then_some(method.description) - }) - { - *subcommand = subcommand.clone().help_template(COMMAND_HELP_TEMPLATE).about(desc); - } else { - *subcommand = subcommand.clone().help_template(COMMAND_HELP_TEMPLATE); + let mut new_subcommand = subcommand.clone().help_template(COMMAND_HELP_TEMPLATE); + if new_subcommand.get_about().is_none() { + if let Some(desc) = + COLD_WALLET_DESC.methods.iter().chain(WALLET_DESC.methods).find_map(|method| { + method + .name + .split('_') + .zip(subcommand.get_name().split('-')) + .all(|(x, y)| x == y) + .then_some(method.description) + }) + { + new_subcommand = new_subcommand.about(desc); + } } + + *subcommand = new_subcommand; } repl_command diff --git a/wallet/wallet-rpc-daemon/docs/RPC.md b/wallet/wallet-rpc-daemon/docs/RPC.md index b92603c317..231a9df543 100644 --- a/wallet/wallet-rpc-daemon/docs/RPC.md +++ b/wallet/wallet-rpc-daemon/docs/RPC.md @@ -972,9 +972,14 @@ Parameters: }, "index": number, }, .. ], - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1000,9 +1005,10 @@ Returns: ### Method `address_sweep_spendable` Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` -or all addresses from this account if all is set to true, to a given destination address. +or all addresses from this account if all is set to true, to the given destination address. Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or `from_addresses` needs to be empty and all set to true. + Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. The wallet will automatically calculate the required fees @@ -1014,9 +1020,14 @@ Parameters: "destination_address": bech32 string, "from_addresses": [ bech32 string, .. ], "all": bool, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1051,9 +1062,14 @@ Parameters: "account": number, "destination_address": bech32 string, "delegation_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1111,9 +1127,14 @@ Parameters: "change_address": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1226,9 +1247,14 @@ Parameters: "vrf_public_key": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1265,9 +1291,14 @@ Parameters: "output_address": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1306,9 +1337,14 @@ Parameters: "output_address": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1331,9 +1367,14 @@ Parameters: "account": number, "address": bech32 string, "pool_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1370,9 +1411,14 @@ Parameters: 1) { "atoms": number string } 2) { "decimal": decimal string }, "delegation_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1410,9 +1456,14 @@ Parameters: 1) { "atoms": number string } 2) { "decimal": decimal string }, "delegation_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1645,9 +1696,14 @@ Parameters: 2) { "hex": hex string } 3) null, }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1702,9 +1758,14 @@ Parameters: 3) { "type": "Unlimited" }, "is_freezable": bool, }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1739,9 +1800,14 @@ Parameters: "account": number, "token_id": bech32 string, "address": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1775,9 +1841,14 @@ Parameters: "account": number, "token_id": bech32 string, "metadata_uri": hex string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1814,9 +1885,14 @@ Parameters: "amount": EITHER OF 1) { "atoms": number string } 2) { "decimal": decimal string }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1854,9 +1930,14 @@ Parameters: "amount": EITHER OF 1) { "atoms": number string } 2) { "decimal": decimal string }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1891,9 +1972,14 @@ Parameters: { "account_index": number, "token_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1930,9 +2016,14 @@ Parameters: "account": number, "token_id": bech32 string, "is_unfreezable": bool, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -1968,9 +2059,14 @@ Parameters: { "account": number, "token_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2007,9 +2103,14 @@ Parameters: "amount": EITHER OF 1) { "atoms": number string } 2) { "decimal": decimal string }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2056,9 +2157,14 @@ Parameters: 1) { "atoms": number string } 2) { "decimal": decimal string }, "intent": string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2089,9 +2195,14 @@ Parameters: 1) bech32 string 2) null, "outputs": [ object, .. ], - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2135,9 +2246,14 @@ Parameters: { "account": number, "data": hex string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2198,9 +2314,14 @@ Parameters: "content": number, }, }, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2268,9 +2389,14 @@ Parameters: }, }, "conclude_address": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2309,9 +2435,14 @@ Parameters: "output_address": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2351,9 +2482,14 @@ Parameters: "output_address": EITHER OF 1) bech32 string 2) null, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -2387,9 +2523,14 @@ Parameters: { "account": number, "order_id": bech32 string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` @@ -3589,9 +3730,14 @@ Parameters: { "account": number, "raw_tx": hex string, - "options": { "in_top_x_mb": EITHER OF - 1) number - 2) null }, + "options": { + "in_top_x_mb": EITHER OF + 1) number + 2) null, + "broadcast_to_mempool": EITHER OF + 1) bool + 2) null, + }, } ``` diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index 2d0746382c..c888166048 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -382,9 +382,10 @@ trait WalletRpc { ) -> rpc::RpcResult; /// Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` - /// or all addresses from this account if all is set to true, to a given destination address. + /// or all addresses from this account if all is set to true, to the given destination address. /// Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or /// `from_addresses` needs to be empty and all set to true. + /// /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. /// The wallet will automatically calculate the required fees #[method(name = "address_sweep_spendable")] diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index 68c6bb7b48..9fe4982447 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -36,7 +36,7 @@ use wallet_controller::{ BlockInfo, CreatedBlockInfo, GenericTokenTransfer, SeedWithPassPhrase, WalletCreationOptions, WalletInfo, }, - ConnectedPeer, ControllerConfig, NodeInterface, UtxoState, UtxoStates, UtxoType, UtxoTypes, + ConnectedPeer, NodeInterface, UtxoState, UtxoStates, UtxoType, UtxoTypes, }; use wallet_types::{ partially_signed_transaction::PartiallySignedTransaction, scan_blockchain::ScanBlockchain, @@ -268,13 +268,10 @@ where raw_tx: RpcHexString, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( - self.sign_raw_transaction(account_arg.index::()?, raw_tx, config).await.map( - |(tx, prev_signatures, cur_signatures)| { + self.sign_raw_transaction(account_arg.index::()?, raw_tx, options.into()) + .await + .map(|(tx, prev_signatures, cur_signatures)| { let is_complete = tx.all_signatures_available() && cur_signatures.iter().all(|s| *s == SignatureStatus::FullySigned); let hex = if is_complete { @@ -293,8 +290,7 @@ where previous_signatures, current_signatures, } - }, - ), + }), ) } @@ -535,17 +531,13 @@ where selected_utxos: Vec, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.send_coins( account_arg.index::()?, address, amount, selected_utxos.into_iter().map(|o| o.into_outpoint()).collect(), - config, + options.into(), ) .await .map(RpcNewTransaction::new), @@ -560,17 +552,13 @@ where all: bool, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.sweep_addresses( account.index::()?, destination_address, from_addresses, all, - config, + options.into(), ) .await, ) @@ -583,16 +571,12 @@ where delegation_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.sweep_delegation( account.index::()?, destination_address, delegation_id, - config, + options.into(), ) .await, ) @@ -607,10 +591,6 @@ where change_address: Option>, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.request_send_coins( account_arg.index::()?, @@ -618,7 +598,7 @@ where amount, selected_utxo.into_outpoint(), change_address, - config, + options.into(), ) .await .map(|(tx, fees)| ComposedTransaction { @@ -648,10 +628,6 @@ where vrf_public_key: Option>, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.create_stake_pool( account_arg.index::()?, @@ -661,7 +637,7 @@ where decommission_address, staker_address, vrf_public_key, - config, + options.into(), ) .await .map(RpcNewTransaction::new), @@ -675,16 +651,12 @@ where output_address: Option>, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.decommission_stake_pool( account_arg.index::()?, pool_id, output_address, - config, + options.into(), ) .await .map(RpcNewTransaction::new), @@ -698,16 +670,12 @@ where output_address: Option>, options: TransactionOptions, ) -> rpc::RpcResult> { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.decommission_stake_pool_request( account_arg.index::()?, pool_id, output_address, - config, + options.into(), ) .await .map(HexEncoded::new), @@ -721,12 +689,8 @@ where pool_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( - self.create_delegation(account_arg.index::()?, address, pool_id, config) + self.create_delegation(account_arg.index::()?, address, pool_id, options.into()) .await .map(|(tx, delegation_id)| NewDelegationTransaction::new(tx, delegation_id)), ) @@ -739,14 +703,15 @@ where delegation_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( - self.delegate_staking(account_arg.index::()?, amount, delegation_id, config) - .await - .map(RpcNewTransaction::new), + self.delegate_staking( + account_arg.index::()?, + amount, + delegation_id, + options.into(), + ) + .await + .map(RpcNewTransaction::new), ) } @@ -758,17 +723,13 @@ where delegation_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.withdraw_from_delegation( account_arg.index::()?, address, amount, delegation_id, - config, + options.into(), ) .await .map(RpcNewTransaction::new), @@ -819,17 +780,12 @@ where metadata: NftMetadata, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( self.issue_new_nft( account_arg.index::()?, destination_address, metadata.into_metadata(), - config, + options.into(), ) .await, ) @@ -842,11 +798,6 @@ where metadata: TokenMetadata, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - let token_supply = metadata.token_supply::()?; let is_freezable = metadata.is_freezable(); rpc::handle_result( @@ -858,7 +809,7 @@ where metadata.metadata_uri.into_bytes(), token_supply, is_freezable, - config, + options.into(), ) .await, ) @@ -871,14 +822,14 @@ where address: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.change_token_authority(account_arg.index::()?, token_id, address, config) - .await, + self.change_token_authority( + account_arg.index::()?, + token_id, + address, + options.into(), + ) + .await, ) } @@ -889,17 +840,12 @@ where metadata_uri: RpcHexString, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( self.change_token_metadata_uri( account_arg.index::()?, token_id, metadata_uri, - config, + options.into(), ) .await, ) @@ -913,14 +859,15 @@ where amount: RpcAmountIn, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.mint_tokens(account_arg.index::()?, token_id, address, amount, config) - .await, + self.mint_tokens( + account_arg.index::()?, + token_id, + address, + amount, + options.into(), + ) + .await, ) } @@ -931,13 +878,9 @@ where amount: RpcAmountIn, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.unmint_tokens(account_arg.index::()?, token_id, amount, config).await, + self.unmint_tokens(account_arg.index::()?, token_id, amount, options.into()) + .await, ) } @@ -947,13 +890,9 @@ where token_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.lock_token_supply(account_arg.index::()?, token_id, config).await, + self.lock_token_supply(account_arg.index::()?, token_id, options.into()) + .await, ) } @@ -964,11 +903,6 @@ where is_unfreezable: bool, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - let is_unfreezable = if is_unfreezable { IsTokenUnfreezable::Yes } else { @@ -976,8 +910,13 @@ where }; rpc::handle_result( - self.freeze_token(account_arg.index::()?, token_id, is_unfreezable, config) - .await, + self.freeze_token( + account_arg.index::()?, + token_id, + is_unfreezable, + options.into(), + ) + .await, ) } @@ -987,12 +926,9 @@ where token_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - - rpc::handle_result(self.unfreeze_token(account_arg.index::()?, token_id, config).await) + rpc::handle_result( + self.unfreeze_token(account_arg.index::()?, token_id, options.into()).await, + ) } async fn send_tokens( @@ -1003,14 +939,15 @@ where amount: RpcAmountIn, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.send_tokens(account_arg.index::()?, token_id, address, amount, config) - .await, + self.send_tokens( + account_arg.index::()?, + token_id, + address, + amount, + options.into(), + ) + .await, ) } @@ -1026,11 +963,6 @@ where HexEncoded, HexEncoded, )> { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( self.create_transaction_for_sending_tokens_with_intent( account_arg.index::()?, @@ -1038,7 +970,7 @@ where address, amount, intent, - config, + options.into(), ) .await .map(|(tx, intent)| (HexEncoded::new(tx.tx), HexEncoded::new(intent))), @@ -1053,17 +985,13 @@ where outputs: Vec, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; rpc::handle_result( self.make_tx_to_send_tokens_from_multisig_address( account_arg.index::()?, from_address, fee_change_address, outputs, - config, + options.into(), ) .await .map( @@ -1082,13 +1010,9 @@ where data: RpcHexString, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.deposit_data(account_arg.index::()?, data.into_bytes(), config).await, + self.deposit_data(account_arg.index::()?, data.into_bytes(), options.into()) + .await, ) } @@ -1100,14 +1024,15 @@ where htlc: RpcHashedTimelockContract, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.create_htlc_transaction(account_arg.index::()?, amount, token_id, htlc, config) - .await, + self.create_htlc_transaction( + account_arg.index::()?, + amount, + token_id, + htlc, + options.into(), + ) + .await, ) } @@ -1119,18 +1044,13 @@ where conclude_address: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( self.create_order( account_arg.index::()?, ask, give, conclude_address, - config, + options.into(), ) .await, ) @@ -1143,14 +1063,14 @@ where output_address: Option>, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( - self.conclude_order(account_arg.index::()?, order_id, output_address, config) - .await, + self.conclude_order( + account_arg.index::()?, + order_id, + output_address, + options.into(), + ) + .await, ) } @@ -1162,18 +1082,13 @@ where output_address: Option>, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - rpc::handle_result( self.fill_order( account_arg.index::()?, order_id, fill_amount_in_ask_currency, output_address, - config, + options.into(), ) .await, ) @@ -1185,12 +1100,9 @@ where order_id: RpcAddress, options: TransactionOptions, ) -> rpc::RpcResult { - let config = ControllerConfig { - in_top_x_mb: options.in_top_x_mb(), - broadcast_to_mempool: true, - }; - - rpc::handle_result(self.freeze_order(account_arg.index::()?, order_id, config).await) + rpc::handle_result( + self.freeze_order(account_arg.index::()?, order_id, options.into()).await, + ) } async fn stake_pool_balance( diff --git a/wallet/wallet-rpc-lib/src/rpc/types.rs b/wallet/wallet-rpc-lib/src/rpc/types.rs index 6b60a18f3d..bc291c4765 100644 --- a/wallet/wallet-rpc-lib/src/rpc/types.rs +++ b/wallet/wallet-rpc-lib/src/rpc/types.rs @@ -391,19 +391,40 @@ impl NewAccountInfo { #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] pub struct TransactionOptions { pub in_top_x_mb: Option, + pub broadcast_to_mempool: Option, } impl TransactionOptions { const DEFAULT_IN_TOP_X_MB: usize = 5; + const DEFAULT_BROADCAST: bool = true; pub fn from_controller_config(config: &ControllerConfig) -> Self { let in_top_x_mb = Some(config.in_top_x_mb); - Self { in_top_x_mb } + let broadcast_to_mempool = Some(config.broadcast_to_mempool); + Self { + in_top_x_mb, + broadcast_to_mempool, + } } pub fn in_top_x_mb(&self) -> usize { self.in_top_x_mb.unwrap_or(Self::DEFAULT_IN_TOP_X_MB) } + + pub fn broadcast_to_mempool(&self) -> bool { + self.broadcast_to_mempool.unwrap_or(Self::DEFAULT_BROADCAST) + } +} + +impl From for ControllerConfig { + fn from(value: TransactionOptions) -> Self { + Self { + broadcast_to_mempool: value + .broadcast_to_mempool + .unwrap_or(TransactionOptions::DEFAULT_BROADCAST), + in_top_x_mb: value.in_top_x_mb.unwrap_or(TransactionOptions::DEFAULT_IN_TOP_X_MB), + } + } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] diff --git a/wallet/wallet-rpc-lib/tests/basic.rs b/wallet/wallet-rpc-lib/tests/basic.rs index 7e1c218e23..e09448677a 100644 --- a/wallet/wallet-rpc-lib/tests/basic.rs +++ b/wallet/wallet-rpc-lib/tests/basic.rs @@ -168,6 +168,7 @@ async fn stake_and_send_coins_to_acct1(#[case] seed: Seed) { let send_to_addr = acct1_addr.address; let options = TransactionOptions { in_top_x_mb: Some(3), + broadcast_to_mempool: Some(true), }; let params = ( ACCOUNT0_ARG, From 291f5a10c1522d78c8230b189bb3ac4267306d50 Mon Sep 17 00:00:00 2001 From: Boris Oncev Date: Mon, 19 May 2025 18:39:22 +0200 Subject: [PATCH 8/8] fix comments --- wallet/src/account/mod.rs | 10 +-- wallet/src/wallet/mod.rs | 8 +- wallet/src/wallet/tests.rs | 32 ++++---- wallet/wallet-cli-commands/src/lib.rs | 6 +- .../wallet-controller/src/runtime_wallet.rs | 6 +- .../src/synced_controller.rs | 16 ++-- wallet/wallet-controller/src/types/mod.rs | 3 +- .../src/types/transaction.rs | 6 ++ .../src/handles_client/mod.rs | 8 +- .../src/rpc_client/client_impl.rs | 21 +++--- .../src/wallet_rpc_traits.rs | 6 +- wallet/wallet-rpc-daemon/docs/RPC.md | 73 ++++++------------- wallet/wallet-rpc-lib/src/rpc/interface.rs | 26 +++---- wallet/wallet-rpc-lib/src/rpc/mod.rs | 8 +- wallet/wallet-rpc-lib/src/rpc/server_impl.rs | 19 ++--- wallet/wallet-rpc-lib/src/rpc/types.rs | 55 +++++++++++++- 16 files changed, 163 insertions(+), 140 deletions(-) diff --git a/wallet/src/account/mod.rs b/wallet/src/account/mod.rs index 66b32c1486..238838bb84 100644 --- a/wallet/src/account/mod.rs +++ b/wallet/src/account/mod.rs @@ -1446,7 +1446,7 @@ impl Account { ) } - pub fn create_stake_pool_tx_with_vrf_key( + pub fn create_stake_pool_with_vrf_key( &mut self, db_tx: &mut impl WalletStorageWriteUnlocked, mut stake_pool_arguments: StakePoolCreationArguments, @@ -1457,7 +1457,7 @@ impl Account { return Err(WalletError::VrfKeyMustBeProvided); }; - self.create_stake_pool_tx_impl( + self.create_stake_pool_impl( stake_pool_arguments, db_tx, vrf_public_key, @@ -1466,7 +1466,7 @@ impl Account { ) } - fn create_stake_pool_tx_impl( + fn create_stake_pool_impl( &mut self, stake_pool_arguments: StakePoolCreationArguments, db_tx: &mut impl WalletStorageWriteUnlocked, @@ -2493,7 +2493,7 @@ impl Account { Ok(data) } - pub fn create_stake_pool_tx( + pub fn create_stake_pool( &mut self, db_tx: &mut impl WalletStorageWriteUnlocked, mut stake_pool_arguments: StakePoolCreationArguments, @@ -2504,7 +2504,7 @@ impl Account { Some(vrf_public_key) => vrf_public_key, None => self.get_vrf_public_key(db_tx)?, }; - self.create_stake_pool_tx_impl( + self.create_stake_pool_impl( stake_pool_arguments, db_tx, vrf_public_key, diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 2a1001996c..8151a7fdf8 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -2018,7 +2018,7 @@ where Ok((token_id, signed_transaction)) } - pub fn create_stake_pool_tx_with_vrf_key( + pub fn create_stake_pool_with_vrf_key( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -2030,7 +2030,7 @@ where account_index, TxAdditionalInfo::new(), |account, db_tx| { - account.create_stake_pool_tx_with_vrf_key( + account.create_stake_pool_with_vrf_key( db_tx, stake_pool_arguments, latest_median_time, @@ -2515,7 +2515,7 @@ where Ok(account.get_legacy_vrf_public_key()) } - pub fn create_stake_pool_tx( + pub fn create_stake_pool( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -2527,7 +2527,7 @@ where account_index, TxAdditionalInfo::new(), |account, db_tx| { - account.create_stake_pool_tx( + account.create_stake_pool( db_tx, stake_pool_arguments, latest_median_time, diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index 5a79d8a55a..57f0e7dabf 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -1762,7 +1762,7 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { let decommission_key = Destination::PublicKey(standalone_pk); let err = wallet - .create_stake_pool_tx_with_vrf_key( + .create_stake_pool_with_vrf_key( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -1779,7 +1779,7 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { assert_eq!(err, WalletError::VrfKeyMustBeProvided); let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -1967,7 +1967,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) // First, try to create the pool using staker_key_hash_dest as the staker address; this should fail. let err = wallet1 - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -1990,7 +1990,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) // Now use staker_key_dest. let stake_pool_transaction = wallet1 - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -2008,7 +2008,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) let stake_pool_transaction_id = stake_pool_transaction.transaction().get_id(); let stake_pool_transaction2 = wallet1 - .create_stake_pool_tx_with_vrf_key( + .create_stake_pool_with_vrf_key( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -2211,7 +2211,7 @@ fn reset_keys_after_failed_transaction(#[case] seed: Seed) { .unwrap() .last_issued(); - let result = wallet.create_stake_pool_tx( + let result = wallet.create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -2426,7 +2426,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { let pool_amount = chain_config.min_stake_pool_pledge(); let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -4727,7 +4727,7 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { let decommission_key = wallet.get_new_address(acc_1_index).unwrap().1; let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( acc_0_index, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -4824,7 +4824,7 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { let decommission_key = wallet.get_new_address(acc_1_index).unwrap().1; let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( acc_0_index, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -4914,7 +4914,7 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { let decommission_key = wallet.get_new_address(acc_1_index).unwrap().1; let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( acc_0_index, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -5029,7 +5029,7 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { assert_eq!(res, (U31::from_u32(1).unwrap(), Some("name".into()))); let stake_pool_transaction = hot_wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -5127,7 +5127,7 @@ fn filter_pools(#[case] seed: Seed) { let pool_amount = block1_amount; let stake_pool_transaction = wallet1 - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -6783,7 +6783,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { let pool_amount = chain_config.min_stake_pool_pledge(); let stake_pool_transaction = wallet1 - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -7076,7 +7076,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { let pool_amount = chain_config.min_stake_pool_pledge(); let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -7590,7 +7590,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { let pool_amount = chain_config.min_stake_pool_pledge(); let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), @@ -7865,7 +7865,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { let pool_amount = chain_config.min_stake_pool_pledge(); let stake_pool_transaction = wallet - .create_stake_pool_tx( + .create_stake_pool( DEFAULT_ACCOUNT_INDEX, FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), diff --git a/wallet/wallet-cli-commands/src/lib.rs b/wallet/wallet-cli-commands/src/lib.rs index d4d664c428..0908d40f04 100644 --- a/wallet/wallet-cli-commands/src/lib.rs +++ b/wallet/wallet-cli-commands/src/lib.rs @@ -652,9 +652,9 @@ pub enum WalletCommand { #[clap(name = "address-sweep-spendable")] /// Sweep all spendable coins or tokens from an address or addresses specified in `addresses` - /// or all addresses from this account if all is set to true, to the given destination address. - /// Either 1 or more addresses need to be specified in `addresses` without `all` being set, or - /// `addresses` needs to be empty and --all being set. + /// or all addresses from this account if `--all` is specified, to the given destination address. + /// Either 1 or more addresses need to be specified in `addresses` without `--all` being set, or + /// `addresses` needs to be empty and `--all` being set. /// /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. /// The wallet will automatically calculate the required fees diff --git a/wallet/wallet-controller/src/runtime_wallet.rs b/wallet/wallet-controller/src/runtime_wallet.rs index cf0a5670ea..5c0bb58f53 100644 --- a/wallet/wallet-controller/src/runtime_wallet.rs +++ b/wallet/wallet-controller/src/runtime_wallet.rs @@ -1037,7 +1037,7 @@ impl RuntimeWallet { } } - pub fn create_stake_pool_tx( + pub fn create_stake_pool( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -1045,14 +1045,14 @@ impl RuntimeWallet { stake_pool_arguments: StakePoolCreationArguments, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_stake_pool_tx( + RuntimeWallet::Software(w) => w.create_stake_pool( account_index, current_fee_rate, consolidate_fee_rate, stake_pool_arguments, ), #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_stake_pool_tx_with_vrf_key( + RuntimeWallet::Trezor(w) => w.create_stake_pool_with_vrf_key( account_index, current_fee_rate, consolidate_fee_rate, diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index 9fcc359639..c8ff5a088f 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -68,7 +68,9 @@ use wallet_types::{ use crate::{ helpers::{fetch_token_info, fetch_utxo, into_balances, tx_to_partially_signed_tx}, runtime_wallet::RuntimeWallet, - types::{Balances, GenericCurrencyTransfer, NewTransaction, SweepFromAddresses}, + types::{ + Balances, GenericCurrencyTransfer, NewTransaction, PreparedTransaction, SweepFromAddresses, + }, ControllerConfig, ControllerError, }; @@ -1016,7 +1018,7 @@ where } /// Creates a transaction that creates a new stake pool and broadcasts it to the mempool. - pub async fn create_stake_pool_tx( + pub async fn create_stake_pool( &mut self, amount: Amount, decommission_key: Destination, @@ -1030,7 +1032,7 @@ where consolidate_fee_rate: FeeRate, wallet: &mut RuntimeWallet, account_index: U31| { - wallet.create_stake_pool_tx( + wallet.create_stake_pool( account_index, current_fee_rate, consolidate_fee_rate, @@ -1113,7 +1115,7 @@ where output_value: OutputValue, htlc: HashedTimelockContract, additional_info: TxAdditionalInfo, - ) -> Result> { + ) -> Result> { let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; @@ -1128,11 +1130,7 @@ where let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; - Ok(NewTransaction { - tx, - fees, - broadcasted: false, - }) + Ok(PreparedTransaction { tx, fees }) } pub async fn create_order( diff --git a/wallet/wallet-controller/src/types/mod.rs b/wallet/wallet-controller/src/types/mod.rs index 3372063802..937b821267 100644 --- a/wallet/wallet-controller/src/types/mod.rs +++ b/wallet/wallet-controller/src/types/mod.rs @@ -38,7 +38,8 @@ use common::{ pub use seed_phrase::SeedWithPassPhrase; pub use standalone_key::AccountStandaloneKeyDetails; pub use transaction::{ - InspectTransaction, NewTransaction, SignatureStats, TransactionToInspect, ValidatedSignatures, + InspectTransaction, NewTransaction, PreparedTransaction, SignatureStats, TransactionToInspect, + ValidatedSignatures, }; use utils::ensure; use wallet::signer::trezor_signer::FoundDevice; diff --git a/wallet/wallet-controller/src/types/transaction.rs b/wallet/wallet-controller/src/types/transaction.rs index 5a9f3dcfe1..48948d3776 100644 --- a/wallet/wallet-controller/src/types/transaction.rs +++ b/wallet/wallet-controller/src/types/transaction.rs @@ -75,3 +75,9 @@ pub struct NewTransaction { pub fees: Balances, pub broadcasted: bool, } + +/// Newly signed transaction with fees that is ready to be broadcasted to the mempool +pub struct PreparedTransaction { + pub tx: SignedTransaction, + pub fees: Balances, +} diff --git a/wallet/wallet-rpc-client/src/handles_client/mod.rs b/wallet/wallet-rpc-client/src/handles_client/mod.rs index 6b6a14fdac..79b7e508f0 100644 --- a/wallet/wallet-rpc-client/src/handles_client/mod.rs +++ b/wallet/wallet-rpc-client/src/handles_client/mod.rs @@ -45,9 +45,9 @@ use wallet_rpc_lib::{ NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, - RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, StakePoolBalance, - StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TxOptionsOverrides, UtxoInfo, - VrfPublicKeyInfo, + RpcPreparedTransaction, RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, + StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, + TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }, RpcError, WalletRpc, }; @@ -1095,7 +1095,7 @@ where token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result { + ) -> Result { self.wallet_rpc .create_htlc_transaction( account_index, diff --git a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs index 52b456ec22..3460590bcb 100644 --- a/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs +++ b/wallet/wallet-rpc-client/src/rpc_client/client_impl.rs @@ -50,9 +50,10 @@ use wallet_rpc_lib::{ NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, - RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, StakePoolBalance, - StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, - TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, + RpcPreparedTransaction, RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, + StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, + TransactionOptions, TransactionRequestOptions, TxOptionsOverrides, UtxoInfo, + VrfPublicKeyInfo, }, ColdWalletRpcClient, WalletRpcClient, }; @@ -519,7 +520,7 @@ impl WalletInterface for ClientWalletRpc { change_address: Option, config: ControllerConfig, ) -> Result { - let options = TransactionOptions::from_controller_config(&config); + let options = TransactionRequestOptions::from_controller_config(&config); WalletRpcClient::transaction_from_cold_input( &self.http_client, account_index.into(), @@ -595,7 +596,7 @@ impl WalletInterface for ClientWalletRpc { output_address: Option, config: ControllerConfig, ) -> Result, Self::Error> { - let options = TransactionOptions::from_controller_config(&config); + let options = TransactionRequestOptions::from_controller_config(&config); WalletRpcClient::decommission_stake_pool_request( &self.http_client, account_index.into(), @@ -955,7 +956,7 @@ impl WalletInterface for ClientWalletRpc { ), Self::Error, > { - let options = TransactionOptions::from_controller_config(&config); + let options = TransactionRequestOptions::from_controller_config(&config); WalletRpcClient::make_tx_for_sending_tokens_with_intent( &self.http_client, account_index.into(), @@ -977,7 +978,7 @@ impl WalletInterface for ClientWalletRpc { outputs: Vec, config: ControllerConfig, ) -> Result { - let options = TransactionOptions::from_controller_config(&config); + let options = TransactionRequestOptions::from_controller_config(&config); WalletRpcClient::make_tx_to_send_tokens_from_multisig_address( &self.http_client, account_index.into(), @@ -1014,8 +1015,8 @@ impl WalletInterface for ClientWalletRpc { token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result { - let options = TransactionOptions::from_controller_config(&config); + ) -> Result { + let options = TransactionRequestOptions::from_controller_config(&config); WalletRpcClient::create_htlc_transaction( &self.http_client, account_index.into(), @@ -1303,7 +1304,7 @@ impl WalletInterface for ClientWalletRpc { raw_tx: String, config: ControllerConfig, ) -> Result { - let options = TransactionOptions::from_controller_config(&config); + let options = TransactionRequestOptions::from_controller_config(&config); ColdWalletRpcClient::sign_raw_transaction( &self.http_client, account_index.into(), diff --git a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs index ab472cc1b4..777bbd2fba 100644 --- a/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs +++ b/wallet/wallet-rpc-client/src/wallet_rpc_traits.rs @@ -39,8 +39,8 @@ use wallet_rpc_lib::types::{ DelegationInfo, HardwareWalletType, LegacyVrfPublicKeyInfo, NewAccountInfo, NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcHashedTimelockContract, - RpcInspectTransaction, RpcNewTransaction, RpcSignatureStatus, RpcStandaloneAddresses, - SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, + RpcInspectTransaction, RpcNewTransaction, RpcPreparedTransaction, RpcSignatureStatus, + RpcStandaloneAddresses, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, StandaloneAddressWithDetails, TokenMetadata, TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }; use wallet_types::{ @@ -502,7 +502,7 @@ pub trait WalletInterface { token_id: Option, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> Result; + ) -> Result; #[allow(clippy::too_many_arguments)] async fn create_order( diff --git a/wallet/wallet-rpc-daemon/docs/RPC.md b/wallet/wallet-rpc-daemon/docs/RPC.md index 231a9df543..0149a70635 100644 --- a/wallet/wallet-rpc-daemon/docs/RPC.md +++ b/wallet/wallet-rpc-daemon/docs/RPC.md @@ -1005,9 +1005,9 @@ Returns: ### Method `address_sweep_spendable` Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` -or all addresses from this account if all is set to true, to the given destination address. -Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or -`from_addresses` needs to be empty and all set to true. +or all addresses from this account if `all` is set to true, to the given destination address. +Either 1 or more addresses need to be specified in `from_addresses` with `all` set to false, or +`from_addresses` needs to be empty and `all` set to true. Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. The wallet will automatically calculate the required fees @@ -1127,14 +1127,9 @@ Parameters: "change_address": EITHER OF 1) bech32 string 2) null, - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` @@ -1337,14 +1332,9 @@ Parameters: "output_address": EITHER OF 1) bech32 string 2) null, - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` @@ -2157,14 +2147,9 @@ Parameters: 1) { "atoms": number string } 2) { "decimal": decimal string }, "intent": string, - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` @@ -2195,14 +2180,9 @@ Parameters: 1) bech32 string 2) null, "outputs": [ object, .. ], - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` @@ -2314,14 +2294,9 @@ Parameters: "content": number, }, }, - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` @@ -2340,7 +2315,6 @@ Returns: "decimal": decimal string, }, .. }, }, - "broadcasted": bool, } ``` @@ -3730,14 +3704,9 @@ Parameters: { "account": number, "raw_tx": hex string, - "options": { - "in_top_x_mb": EITHER OF - 1) number - 2) null, - "broadcast_to_mempool": EITHER OF - 1) bool - 2) null, - }, + "options": { "in_top_x_mb": EITHER OF + 1) number + 2) null }, } ``` diff --git a/wallet/wallet-rpc-lib/src/rpc/interface.rs b/wallet/wallet-rpc-lib/src/rpc/interface.rs index c888166048..effa733317 100644 --- a/wallet/wallet-rpc-lib/src/rpc/interface.rs +++ b/wallet/wallet-rpc-lib/src/rpc/interface.rs @@ -48,10 +48,10 @@ use crate::types::{ MaybeSignedTransaction, NewAccountInfo, NewDelegationTransaction, NewOrderTransaction, NewSubmittedTransaction, NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcAmountIn, RpcHashedTimelockContract, RpcInspectTransaction, RpcNewTransaction, - RpcStandaloneAddresses, RpcUtxoOutpoint, RpcUtxoState, RpcUtxoType, + RpcPreparedTransaction, RpcStandaloneAddresses, RpcUtxoOutpoint, RpcUtxoState, RpcUtxoType, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, - StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TxOptionsOverrides, - VrfPublicKeyInfo, + StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TransactionRequestOptions, + TxOptionsOverrides, VrfPublicKeyInfo, }; #[rpc::rpc(server)] @@ -225,7 +225,7 @@ trait ColdWalletRpc { &self, account: AccountArg, raw_tx: RpcHexString, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult; #[method(name = "challenge_sign_plain")] @@ -382,9 +382,9 @@ trait WalletRpc { ) -> rpc::RpcResult; /// Sweep all spendable coins or tokens from an address or addresses specified in `from_addresses` - /// or all addresses from this account if all is set to true, to the given destination address. - /// Either 1 or more addresses need to be specified in `from_addresses` with all set to false, or - /// `from_addresses` needs to be empty and all set to true. + /// or all addresses from this account if `all` is set to true, to the given destination address. + /// Either 1 or more addresses need to be specified in `from_addresses` with `all` set to false, or + /// `from_addresses` needs to be empty and `all` set to true. /// /// Spendable coins are any coins that are not locked, and tokens that are not frozen or locked. /// The wallet will automatically calculate the required fees @@ -425,7 +425,7 @@ trait WalletRpc { amount: RpcAmountIn, selected_utxo: RpcUtxoOutpoint, change_address: Option>, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult; /// Print the summary of the transaction @@ -488,7 +488,7 @@ trait WalletRpc { account: AccountArg, pool_id: RpcAddress, output_address: Option>, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult>; /// Create a delegation to a given pool id and the owner address/destination. @@ -698,7 +698,7 @@ trait WalletRpc { address: RpcAddress, amount: RpcAmountIn, intent: String, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult<( HexEncoded, HexEncoded, @@ -717,7 +717,7 @@ trait WalletRpc { from_address: RpcAddress, fee_change_address: Option>, outputs: Vec, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult; /// Store data on the blockchain, the data is provided as hex encoded string. @@ -739,8 +739,8 @@ trait WalletRpc { amount: RpcAmountIn, token_id: Option>, htlc: RpcHashedTimelockContract, - options: TransactionOptions, - ) -> rpc::RpcResult; + options: TransactionRequestOptions, + ) -> rpc::RpcResult; /// Create an order for exchanging "given" amount of an arbitrary currency (coins or tokens) for /// an arbitrary amount of "asked" currency. diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index 79aabd9b26..7da717ae71 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -39,7 +39,7 @@ use p2p_types::{bannable_address::BannableAddress, socket_address::SocketAddress use serialization::{hex_encoded::HexEncoded, Decode, DecodeAll}; use types::{ NewOrderTransaction, NewSubmittedTransaction, NewTokenTransaction, RpcHashedTimelockContract, - RpcNewTransaction, + RpcNewTransaction, RpcPreparedTransaction, }; use utils::{ensure, shallow_clone::ShallowClone}; use utils_networking::IpOrSocketAddress; @@ -1321,7 +1321,7 @@ where controller .synced_controller(account_index, config) .await? - .create_stake_pool_tx( + .create_stake_pool( amount, decommission_destination, margin_ratio_per_thousand, @@ -1525,7 +1525,7 @@ where token_id: Option>, htlc: RpcHashedTimelockContract, config: ControllerConfig, - ) -> WRpcResult { + ) -> WRpcResult { let secret_hash = HtlcSecretHash::decode_all(&mut htlc.secret_hash.as_bytes()) .map_err(|_| RpcError::InvalidHtlcSecretHash)?; @@ -1585,7 +1585,7 @@ where .create_htlc_tx(value, htlc, additional_info) .await .map_err(RpcError::Controller) - .map(RpcNewTransaction::new) + .map(RpcPreparedTransaction::new) }) }) .await? diff --git a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs index 9fe4982447..6f00d5ee06 100644 --- a/wallet/wallet-rpc-lib/src/rpc/server_impl.rs +++ b/wallet/wallet-rpc-lib/src/rpc/server_impl.rs @@ -52,14 +52,15 @@ use crate::{ NftMetadata, NodeVersion, OpenedWallet, PoolInfo, PublicKeyInfo, RpcAddress, RpcAmountIn, RpcHexString, RpcInspectTransaction, RpcStandaloneAddresses, RpcUtxoOutpoint, RpcUtxoState, RpcUtxoType, SendTokensFromMultisigAddressResult, StakePoolBalance, StakingStatus, - StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TxOptionsOverrides, - UtxoInfo, VrfPublicKeyInfo, + StandaloneAddressWithDetails, TokenMetadata, TransactionOptions, TransactionRequestOptions, + TxOptionsOverrides, UtxoInfo, VrfPublicKeyInfo, }, RpcError, }; use super::types::{ NewOrderTransaction, NewTokenTransaction, RpcHashedTimelockContract, RpcNewTransaction, + RpcPreparedTransaction, }; #[async_trait::async_trait] @@ -266,7 +267,7 @@ where &self, account_arg: AccountArg, raw_tx: RpcHexString, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult { rpc::handle_result( self.sign_raw_transaction(account_arg.index::()?, raw_tx, options.into()) @@ -589,7 +590,7 @@ where amount: RpcAmountIn, selected_utxo: RpcUtxoOutpoint, change_address: Option>, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult { rpc::handle_result( self.request_send_coins( @@ -668,7 +669,7 @@ where account_arg: AccountArg, pool_id: RpcAddress, output_address: Option>, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult> { rpc::handle_result( self.decommission_stake_pool_request( @@ -958,7 +959,7 @@ where address: RpcAddress, amount: RpcAmountIn, intent: String, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult<( HexEncoded, HexEncoded, @@ -983,7 +984,7 @@ where from_address: RpcAddress, fee_change_address: Option>, outputs: Vec, - options: TransactionOptions, + options: TransactionRequestOptions, ) -> rpc::RpcResult { rpc::handle_result( self.make_tx_to_send_tokens_from_multisig_address( @@ -1022,8 +1023,8 @@ where amount: RpcAmountIn, token_id: Option>, htlc: RpcHashedTimelockContract, - options: TransactionOptions, - ) -> rpc::RpcResult { + options: TransactionRequestOptions, + ) -> rpc::RpcResult { rpc::handle_result( self.create_htlc_transaction( account_arg.index::()?, diff --git a/wallet/wallet-rpc-lib/src/rpc/types.rs b/wallet/wallet-rpc-lib/src/rpc/types.rs index bc291c4765..4c96036422 100644 --- a/wallet/wallet-rpc-lib/src/rpc/types.rs +++ b/wallet/wallet-rpc-lib/src/rpc/types.rs @@ -419,10 +419,40 @@ impl TransactionOptions { impl From for ControllerConfig { fn from(value: TransactionOptions) -> Self { Self { - broadcast_to_mempool: value - .broadcast_to_mempool - .unwrap_or(TransactionOptions::DEFAULT_BROADCAST), - in_top_x_mb: value.in_top_x_mb.unwrap_or(TransactionOptions::DEFAULT_IN_TOP_X_MB), + broadcast_to_mempool: value.broadcast_to_mempool(), + in_top_x_mb: value.in_top_x_mb(), + } + } +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] +pub struct TransactionRequestOptions { + pub in_top_x_mb: Option, +} + +impl TransactionRequestOptions { + const DEFAULT_IN_TOP_X_MB: usize = 5; + const DEFAULT_BROADCAST: bool = false; + + pub fn from_controller_config(config: &ControllerConfig) -> Self { + let in_top_x_mb = Some(config.in_top_x_mb); + Self { in_top_x_mb } + } + + pub fn in_top_x_mb(&self) -> usize { + self.in_top_x_mb.unwrap_or(Self::DEFAULT_IN_TOP_X_MB) + } + + pub fn broadcast_to_mempool(&self) -> bool { + Self::DEFAULT_BROADCAST + } +} + +impl From for ControllerConfig { + fn from(value: TransactionRequestOptions) -> Self { + Self { + broadcast_to_mempool: value.broadcast_to_mempool(), + in_top_x_mb: value.in_top_x_mb(), } } } @@ -726,6 +756,23 @@ impl RpcNewTransaction { } } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] +pub struct RpcPreparedTransaction { + pub tx_id: Id, + pub tx: HexEncoded, + pub fees: Balances, +} + +impl RpcPreparedTransaction { + pub fn new(tx: wallet_controller::types::PreparedTransaction) -> Self { + Self { + tx_id: tx.tx.transaction().get_id(), + tx: tx.tx.into(), + fees: tx.fees, + } + } +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, HasValueHint)] pub struct NodeVersion { pub version: String,