diff --git a/protocol-units/bridge/cli/Cargo.toml b/protocol-units/bridge/cli/Cargo.toml index d32e55638..b2745f4b1 100644 --- a/protocol-units/bridge/cli/Cargo.toml +++ b/protocol-units/bridge/cli/Cargo.toml @@ -13,8 +13,7 @@ rust-version.workspace = true bridge-shared.workspace = true ethereum-bridge.workspace = true movement-bridge.workspace = true - -clap.workspace = true +clap = { workspace = true, features = ["derive"] } tokio.workspace = true anyhow.workspace = true tracing.workspace = true diff --git a/protocol-units/bridge/cli/src/clap.rs b/protocol-units/bridge/cli/src/clap.rs index 269092087..f29287d77 100644 --- a/protocol-units/bridge/cli/src/clap.rs +++ b/protocol-units/bridge/cli/src/clap.rs @@ -14,4 +14,5 @@ pub enum Commands { /// Ethereum to Movement Labs bridge commands #[command(subcommand)] BridgeETHtoMOVETH(eth_to_movement::Commands), + } diff --git a/protocol-units/bridge/cli/src/clap/eth_to_movement.rs b/protocol-units/bridge/cli/src/clap/eth_to_movement.rs index 44551a4a3..10c8f6ad6 100644 --- a/protocol-units/bridge/cli/src/clap/eth_to_movement.rs +++ b/protocol-units/bridge/cli/src/clap/eth_to_movement.rs @@ -31,16 +31,59 @@ pub struct EthSharedArgs { pub eth_gas_limit: u64, } +#[derive(Args, Clone, Debug)] +pub struct MoveSharedArgs { + /// Private key of the Ethereum signer + #[arg(long)] + pub move_signer_private_key: String, + + /// URL for the Ethereum RPC + #[arg(long, default_value = "http://localhost:8545")] + pub move_rpc_url: Url, + + /// URL for the Ethereum WebSocket + #[arg(long, default_value = "ws://localhost:8545")] + pub move_ws_url: Url, + + /// Ethereum contract address for the initiator + #[arg(long, default_value = "0x0000000000000000000000000000000000000000")] + pub move_initiator_contract: MovementAddress, + + /// Ethereum contract address for the counterparty + #[arg(long, default_value = "0x0000000000000000000000000000000000000000")] + pub move_counterparty_contract: MovementAddress, + + /// Gas limit for Ethereum transactions + #[arg(long, default_value_t = 10_000_000_000)] + pub move_gas_limit: u64, +} + +#[derive(Args, Clone, Debug)] +pub struct CombinedArgs { + #[command(flatten)] + pub eth_args: EthSharedArgs, + + #[command(flatten)] + pub move_args: MoveSharedArgs, +} + #[derive(Subcommand)] pub enum Commands { - /// Initiate a bridge transfer - Swap { + /// Initiate a bridge transfer from Ethereum + BridgeToMovement { #[command(flatten)] args: EthSharedArgs, - /// The recipient address on the movement labs chain recipient: MovementAddress, - + /// The amount of Ethereum to transfer in WEI + amount: u64, + }, + /// Initiate a bridge transfer from Movement + BridgeToEthereum { + #[command(flatten)] + args: MoveSharedArgs, + /// The recipient address on the Ethereum chain + recipient: EthAddress, /// The amount of Ethereum to transfer in WEI amount: u64, }, @@ -53,4 +96,8 @@ pub enum Commands { #[arg(long)] transfer_id: String, }, + IniatializeUser { + #[command(flatten)] + args: CombinedArgs, + }, } diff --git a/protocol-units/bridge/cli/src/eth_to_moveth.rs b/protocol-units/bridge/cli/src/eth_to_moveth.rs index d3a70d214..1eafbf505 100644 --- a/protocol-units/bridge/cli/src/eth_to_moveth.rs +++ b/protocol-units/bridge/cli/src/eth_to_moveth.rs @@ -1,19 +1,25 @@ -use crate::clap::eth_to_movement::{Commands, EthSharedArgs}; +use crate::clap::eth_to_movement::{Commands, EthSharedArgs, MoveSharedArgs}; use alloy::primitives::keccak256; use anyhow::Result; use bridge_shared::types::{Amount, HashLock, HashLockPreImage, RecipientAddress, TimeLock}; -use bridge_shared::{bridge_contracts::BridgeContractInitiator, types::InitiatorAddress}; +use bridge_shared::{types::InitiatorAddress}; use ethereum_bridge::{types::EthAddress, EthClient}; use movement_bridge::utils::MovementAddress; +use movement_bridge::MovementClient; +use bridge_shared::bridge_contracts::BridgeContractInitiator; + + pub async fn execute(command: &Commands) -> Result<()> { match command { - Commands::Swap { args, recipient, amount } => initiate_swap(args, recipient, *amount).await, + Commands::IniatializeUser { args } => Ok(()), + Commands::BridgeToEthereum { args, recipient, amount } => bridge_to_ethereum(args, recipient, *amount).await, + Commands::BridgeToMovement { args, recipient, amount } => bridge_to_movement(args, recipient, *amount).await, Commands::Resume { args, transfer_id } => resume_swap(args, transfer_id).await, } } -async fn initiate_swap( +async fn bridge_to_movement( args: &EthSharedArgs, recipient: &MovementAddress, amount: u64, @@ -34,7 +40,40 @@ async fn initiate_swap( let time_lock = TimeLock(current_block + 100); // Set an appropriate time lock let amount = Amount(amount); - // TODO: Store the swap details in the local database so they can be resumed in case of failure + // Call using rust based eth libs + client + .initiate_bridge_transfer( + InitiatorAddress(initiator_address), + recipient_address, + hash_lock, + time_lock, + amount, + ) + .await?; + Ok(()) +} + +async fn bridge_to_ethereum( + args: &MoveSharedArgs, + recipient: &EthAddress, + amount: u64, +) -> Result<()> { + println!("Initiating swap to {:?} with amount {}", recipient, amount); + + let mut client = MovementClient::new(args).await?; + + // Get the current block height + let current_block = client.get_block_number().await?; + println!("Current Ethereum block height: {}", current_block); + + // Convert signer's private key to EthAddress + let initiator_address = MovementAddress(client.get_signer_address()); + let recipient_address = RecipientAddress(From::from(recipient)); + let hash_lock_pre_image = HashLockPreImage::random(); + let hash_lock = HashLock(From::from(keccak256(hash_lock_pre_image))); + let time_lock = TimeLock(current_block + 100); // Set an appropriate time lock + let amount = Amount(amount); + client .initiate_bridge_transfer( diff --git a/protocol-units/bridge/cli/src/transaction_request.rs b/protocol-units/bridge/cli/src/transaction_request.rs new file mode 100644 index 000000000..17e51a4aa --- /dev/null +++ b/protocol-units/bridge/cli/src/transaction_request.rs @@ -0,0 +1,32 @@ +extern crate web3; + +use web3::futures::Future; +use web3::types::{TransactionRequest, U256}; + +fn main() { + let (_eloop, transport) = web3::transports::Http::new("http://localhost:8545").unwrap(); + + let web3 = web3::Web3::new(transport); + let accounts = web3.eth().accounts().wait().unwrap(); + + let balance_before = web3.eth().balance(accounts[1], None).wait().unwrap(); + + let tx = TransactionRequest { + from: accounts[0], + to: Some(accounts[1]), + gas: None, + gas_price: None, + value: Some(U256::from(10000)), + data: None, + nonce: None, + condition: None + }; + + let tx_hash = web3.eth().send_transaction(tx).wait().unwrap(); + + let balance_after = web3.eth().balance(accounts[1], None).wait().unwrap(); + + println!("TX Hash: {:?}", tx_hash); + println!("Balance before: {}", balance_before); + println!("Balance after: {}", balance_after); +} \ No newline at end of file diff --git a/protocol-units/bridge/cli/src/types.rs b/protocol-units/bridge/cli/src/types.rs index 59e929798..a4e02f734 100644 --- a/protocol-units/bridge/cli/src/types.rs +++ b/protocol-units/bridge/cli/src/types.rs @@ -1,5 +1,6 @@ -use crate::clap::eth_to_movement::EthSharedArgs; +use crate::clap::eth_to_movement::{EthSharedArgs, MoveSharedArgs}; use ethereum_bridge::Config; +use movement_bridge::Config as MovementConfig; impl From for Config { fn from(args: EthSharedArgs) -> Self { @@ -14,6 +15,25 @@ impl From for Config { } } +impl From<&MoveSharedArgs> for MovementConfig { + fn from(args: &MoveSharedArgs) -> Self { + From::from(args.clone()) + } +} + +impl From for MovementConfig { + fn from(args: MoveSharedArgs) -> Self { + Self { + rpc_url: args.move_rpc_url, + ws_url: Some(args.move_ws_url), + signer_private_key: Some(args.move_signer_private_key), + initiator_contract: Some(args.move_initiator_contract.0), + counterparty_contract: Some(args.move_counterparty_contract.0), + gas_limit: args.move_gas_limit, + } + } +} + impl From<&EthSharedArgs> for Config { fn from(args: &EthSharedArgs) -> Self { From::from(args.clone())