Skip to content

Commit

Permalink
feat(ucli): move transfer to ucli
Browse files Browse the repository at this point in the history
Signed-off-by: aeryz <abdullaheryz@protonmail.com>
  • Loading branch information
aeryz committed Oct 31, 2023
1 parent 8c50e3e commit 52410c9
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 22 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions evm/contracts/apps/ucs/01-relay/Relay.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ library RelayLib {
return address(iaddr);
}

function bytesToAddress(bytes memory b) private pure returns (address) {
function bytesToAddress(bytes memory b) internal pure returns (address) {
if (b.length != 20) {
revert("Invalid address.");
}
Expand Down Expand Up @@ -276,7 +276,7 @@ contract UCS01Relay is IBCAppBase {
RelayPacket memory packet
) internal {
// We're going to refund, the receiver will be the sender.
address receiver = bytesToAddress(packet.sender);
address receiver = RelayLib.bytesToAddress(packet.sender);
for (uint256 i = 0; i < packet.tokens.length; i++) {
Token memory token = packet.tokens[i];
// Either we tried to send back a remote native token
Expand Down Expand Up @@ -321,7 +321,7 @@ contract UCS01Relay is IBCAppBase {
strings.slice memory trimedDenom = denomSlice.beyond(
prefix.toSlice()
);
address receiver = bytesToAddress(packet.receiver);
address receiver = RelayLib.bytesToAddress(packet.receiver);
address denomAddress;
string memory denom;
if (!denomSlice.equals(token.denom.toSlice())) {
Expand Down
8 changes: 5 additions & 3 deletions ucli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ethers = { workspace = true, features = ["rustls", "ws"] }
clap = { version = "4.3.0", features = ["derive", "env", "error-context"] }
serde_json = "1.0.96"
serde = { version = "1.0.173", features = ["derive"] }
ethers = { workspace = true, features = ["rustls", "ws"] }
hex = { version = "0.4.3", features = [ "serde" ] }
serde = { version = "1.0.173", features = ["derive"] }
serde_json = "1.0.96"
tokio = { version = "1.27.0", features = ["macros"] }

unionlabs = { workspace = true, features = ["ethabi"] }
contracts.workspace = true
chain-utils.workspace = true
tendermint-rpc = { workspace = true, features = ["http-client", "websocket-client"] }
beacon-api = { workspace = true, default-features = false }
52 changes: 38 additions & 14 deletions ucli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
use std::{collections::BTreeMap, ffi::OsString, str::FromStr};

use chain_utils::private_key::PrivateKey;
use beacon_api::client::BeaconApiClient;
use chain_utils::{private_key::PrivateKey, union::Union};
use clap::{
error::{ContextKind, ContextValue},
Args, Parser, Subcommand,
};
use ethers::{
prelude::k256::ecdsa,
providers::{Middleware, Provider, Ws},
signers::LocalWallet,
types::{Address, H256},
utils::secret_key_to_address,
};
use serde::{Deserialize, Serialize};
use tendermint_rpc::WebSocketClientUrl;
use unionlabs::{
ethereum::{Address, H256, U256},
ethereum_consts_traits::{ChainSpec, Minimal},
};

#[derive(Debug, Parser)]
#[command(arg_required_else_help = true)]
Expand Down Expand Up @@ -43,8 +49,6 @@ pub enum TxCmd {
#[derive(Debug, Subcommand)]
pub enum EvmTx {
Transfer {
#[arg(long)]
on: String,
#[arg(long)]
relay_address: Address,
// #[arg(long)]
Expand All @@ -67,15 +71,8 @@ pub enum EvmTx {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "", deserialize = ""))]
pub struct Config {
/// Map of chain name to it's respective config.
pub chain: BTreeMap<String, ChainConfig>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "chain_type")]
pub enum ChainConfig {
Evm(EvmChainConfig),
Union(UnionChainConfig),
pub evm: EvmChainConfig,
pub union: UnionChainConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -84,7 +81,7 @@ pub struct EvmChainConfig {
pub ibc_handler_address: Address,

/// The signer that will be used to submit transactions by voyager.
pub signers: Vec<PrivateKey<ecdsa::SigningKey>>,
pub signer: PrivateKey<ecdsa::SigningKey>,

// TODO(benluelo): Use `Url` or something similar
/// The RPC endpoint for the execution chain.
Expand All @@ -101,3 +98,30 @@ pub struct UnionChainConfig {
pub prover_endpoint: String,
pub grpc_url: String,
}

#[derive(Debug, Clone)]
pub struct Evm<C: ChainSpec> {
pub chain_id: U256,
pub wallet: LocalWallet,
pub provider: Provider<Ws>,
pub beacon_api_client: BeaconApiClient<C>,
}

impl<C: ChainSpec> Evm<C> {
pub async fn new(config: EvmChainConfig) -> Result<Self, ()> {
let provider = Provider::new(Ws::connect(config.eth_rpc_api).await.unwrap());

let chain_id = provider.get_chainid().await.unwrap();

let signer = config.signer.value();
let address = secret_key_to_address(&signer);
let wallet = LocalWallet::new_with_signer(signer, address, chain_id.as_u64());

Ok(Self {
chain_id: U256(chain_id),
provider,
beacon_api_client: BeaconApiClient::new(config.eth_beacon_rpc_api).await,
wallet,
})
}
}
114 changes: 112 additions & 2 deletions ucli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,115 @@
use std::{fs::read_to_string, sync::Arc};

use clap::Parser;
use cli::Evm;
use contracts::{
erc20,
ucs01_relay::{LocalToken, UCS01Relay},
};
use ethers::{
middleware::SignerMiddleware,
signers::Signer,
types::{Address, U256},
};
use unionlabs::ethereum_consts_traits::{Mainnet, Minimal};

use crate::cli::{AppArgs, Config};

mod cli;

fn main() {
println!("Hello, world!");
#[cfg(not(feature = "eth-minimal"))]
pub type EvmConfig = Minimal;
#[cfg(feature = "eth-minimal")]
pub type EvmConfig = Mainnet;

#[tokio::main]
async fn main() {
let args = AppArgs::parse();
let config = read_to_string(&args.config_file_path).unwrap();
let config = serde_json::from_str::<Config>(&config).unwrap();

match args.command {
cli::Command::Tx(tx) => match tx {
cli::TxCmd::Evm(evm_tx) => {
let evm: Evm<EvmConfig> = Evm::new(config.evm).await.unwrap();
match evm_tx {
cli::EvmTx::Transfer {
relay_address,
port_id,
channel_id,
receiver,
amount,
denom,
} => {
handle_transfer(
evm,
relay_address.into(),
port_id,
channel_id,
receiver,
amount,
denom,
)
.await
}
};
}
},
}
}

async fn handle_transfer(
evm: Evm<EvmConfig>,
relay_address: Address,
port_id: String,
channel_id: String,
receiver: String,
amount: u64,
denom: String,
) {
let signer_middleware = Arc::new(SignerMiddleware::new(
evm.provider.clone(),
evm.wallet.clone(),
));
let relay = UCS01Relay::new(relay_address, signer_middleware.clone());

let denom = relay.denom_to_address(denom).await.unwrap();
println!("Address is: {}", denom);

let erc_contract = erc20::ERC20::new(denom, signer_middleware.clone());

let balance = erc_contract.balance_of(evm.wallet.address()).await.unwrap();
println!("Balance is: {}", balance);

erc_contract
.approve(relay_address, U256::max_value() / 2)
.send()
.await
.unwrap()
.await
.unwrap()
.unwrap();
println!("{:?}", evm.wallet.address());

let tx_rcp = relay
.send(
port_id,
channel_id,
hex::decode(receiver).unwrap().into(),
[LocalToken {
denom,
amount: amount.into(),
}]
.into(),
u64::MAX,
u64::MAX,
)
.send()
.await
.unwrap()
.await
.unwrap()
.unwrap();

dbg!(tx_rcp);
}

0 comments on commit 52410c9

Please sign in to comment.