From ddd23131076643c23fef2d671f7e5c03df64abb9 Mon Sep 17 00:00:00 2001 From: jolestar Date: Wed, 3 Jan 2024 02:19:35 +0800 Subject: [PATCH 1/2] [bitcoin] Cli bitcoin address binding --- Cargo.lock | 2 + crates/rooch/Cargo.toml | 2 + .../src/commands/account/commands/binding.rs | 101 ++++++++++++++++++ .../src/commands/account/commands/mod.rs | 1 + crates/rooch/src/commands/account/mod.rs | 5 +- 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 crates/rooch/src/commands/account/commands/binding.rs diff --git a/Cargo.lock b/Cargo.lock index 87719118a6..f0a6ac4231 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7690,6 +7690,8 @@ dependencies = [ "async-trait", "bcs", "bcs-ext", + "bitcoin 0.31.0", + "bitcoincore-rpc", "clap 4.4.1", "codespan-reporting", "datatest-stable 0.1.1", diff --git a/crates/rooch/Cargo.toml b/crates/rooch/Cargo.toml index f4b4c6e569..17c9c3267c 100644 --- a/crates/rooch/Cargo.toml +++ b/crates/rooch/Cargo.toml @@ -39,6 +39,8 @@ parking_lot = { workspace = true } bcs-ext = { workspace = true } rpassword = { workspace = true } fastcrypto = { workspace = true } +bitcoin = { workspace = true } +bitcoincore-rpc = { workspace = true } move-bytecode-utils = { workspace = true } move-binary-format = { workspace = true } diff --git a/crates/rooch/src/commands/account/commands/binding.rs b/crates/rooch/src/commands/account/commands/binding.rs new file mode 100644 index 0000000000..c384c19234 --- /dev/null +++ b/crates/rooch/src/commands/account/commands/binding.rs @@ -0,0 +1,101 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli_types::{TransactionOptions, WalletContextOptions}; +use bitcoincore_rpc::{Auth, Client, RpcApi}; +use clap::Parser; +use rooch_types::{ + address::{BitcoinAddress, MultiChainAddress, RoochAddress}, + error::{RoochError, RoochResult}, + multichain_id::RoochMultiChainID, +}; + +/// Binding a +#[derive(Debug, Parser)] +pub struct BindingCommand { + /// L1 chain id + #[clap(long, short = 'c')] + pub l1_chain: RoochMultiChainID, + + /// L1 chain address + #[clap(long)] + pub l1_address: String, + + #[clap( + long, + env = "BITCOIN_RPC_URL", + requires = "btc-rpc-username", + requires = "btc-rpc-password" + )] + pub btc_rpc_url: String, + + #[clap(long, id = "btc-rpc-username", env = "BTC_RPC_USERNAME")] + pub btc_rpc_username: String, + + #[clap(long, id = "btc-rpc-password", env = "BTC_RPC_PASSWORD")] + pub btc_rpc_password: String, + + #[clap(flatten)] + pub tx_options: TransactionOptions, + + #[clap(flatten)] + pub context_options: WalletContextOptions, +} + +impl BindingCommand { + pub async fn execute(self) -> RoochResult<()> { + let multichain_address = MultiChainAddress::try_from_str_with_multichain_id( + self.l1_chain, + &self.l1_address.as_str(), + )?; + let wallet_context = self.context_options.build()?; + let sender = wallet_context.resolve_address(self.tx_options.sender)?; + match self.l1_chain { + RoochMultiChainID::Bitcoin => { + Self::binding_bitcoin_adddress( + self.btc_rpc_url, + self.btc_rpc_username, + self.btc_rpc_password, + sender.into(), + multichain_address.try_into()?, + ) + .await?; + Ok(()) + } + RoochMultiChainID::Rooch => Err(RoochError::CommandArgumentError( + "Can not binding Rooch address".to_owned(), + )), + _ => Err(RoochError::CommandArgumentError( + "Does not support this chain".to_owned(), + )), + } + } + + async fn binding_bitcoin_adddress( + btc_rpc_url: String, + btc_rpc_user_name: String, + btc_rpc_password: String, + _sender: RoochAddress, + bitcoin_address: BitcoinAddress, + ) -> anyhow::Result { + let rpc = Client::new( + btc_rpc_url.as_str(), + Auth::UserPass(btc_rpc_user_name, btc_rpc_password), + )?; + let chain_info = rpc.get_blockchain_info()?; + let bitcoin_chain_network = + rooch_types::bitcoin::network::Network::try_from(chain_info.chain)?; + let bitcoin_address_str = bitcoin_address.format(bitcoin_chain_network.to_num())?; + let message = "rooch"; + let result = rpc + .call::( + "signmessage", + &[ + serde_json::to_value(bitcoin_address_str)?, + serde_json::to_value(message)?, + ], + ) + .map_err(|e| RoochError::UnexpectedError(e.to_string()))?; + Ok(result) + } +} diff --git a/crates/rooch/src/commands/account/commands/mod.rs b/crates/rooch/src/commands/account/commands/mod.rs index 5e4d31bfc6..7bcfeb4641 100644 --- a/crates/rooch/src/commands/account/commands/mod.rs +++ b/crates/rooch/src/commands/account/commands/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod balance; +pub mod binding; pub mod create; pub mod list; pub mod nullify; diff --git a/crates/rooch/src/commands/account/mod.rs b/crates/rooch/src/commands/account/mod.rs index 879d28de0b..7441b5cc62 100644 --- a/crates/rooch/src/commands/account/mod.rs +++ b/crates/rooch/src/commands/account/mod.rs @@ -5,7 +5,8 @@ use crate::cli_types::CommandAction; use crate::commands::account::commands::balance::BalanceCommand; use async_trait::async_trait; use commands::{ - create::CreateCommand, list::ListCommand, nullify::NullifyCommand, switch::SwitchCommand, + binding::BindingCommand, create::CreateCommand, list::ListCommand, nullify::NullifyCommand, + switch::SwitchCommand, }; use rooch_types::error::{RoochError, RoochResult}; use std::path::PathBuf; @@ -33,6 +34,7 @@ impl CommandAction for Account { AccountCommand::Switch(switch) => switch.execute().await.map(|_| "".to_owned()), AccountCommand::Nullify(nullify) => nullify.execute().await.map(|_| "".to_owned()), AccountCommand::Balance(balance) => balance.execute().await.map(|_| "".to_owned()), + AccountCommand::Binding(binding) => binding.execute().await.map(|_| "".to_owned()), } .map_err(RoochError::from) } @@ -46,4 +48,5 @@ pub enum AccountCommand { Switch(SwitchCommand), Nullify(NullifyCommand), Balance(BalanceCommand), + Binding(BindingCommand), } From aefcdff5f3d1dddfdbce82b46d35a2cc068531f2 Mon Sep 17 00:00:00 2001 From: Feliciss <10203-feliciss@users.noreply.0xacab.org> Date: Mon, 15 Jan 2024 15:45:45 +0900 Subject: [PATCH 2/2] [gh-1282] fix referential link. --- crates/rooch/src/commands/account/commands/binding.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rooch/src/commands/account/commands/binding.rs b/crates/rooch/src/commands/account/commands/binding.rs index c384c19234..1ba62b83ed 100644 --- a/crates/rooch/src/commands/account/commands/binding.rs +++ b/crates/rooch/src/commands/account/commands/binding.rs @@ -46,7 +46,7 @@ impl BindingCommand { pub async fn execute(self) -> RoochResult<()> { let multichain_address = MultiChainAddress::try_from_str_with_multichain_id( self.l1_chain, - &self.l1_address.as_str(), + self.l1_address.as_str(), )?; let wallet_context = self.context_options.build()?; let sender = wallet_context.resolve_address(self.tx_options.sender)?;