Skip to content

Commit

Permalink
feat: expose command for broker fee withdrawal (#4581)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel <daniel@chainflip.io>
Co-authored-by: dandanlen <3168260+dandanlen@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 29, 2024
1 parent c3393b8 commit f05ac0f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 4 deletions.
22 changes: 21 additions & 1 deletion api/bin/chainflip-broker-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use chainflip_api::{
self, clean_foreign_chain_address,
primitives::{AccountRole, Asset, BasisPoints, BlockNumber, CcmChannelMetadata, ChannelId},
settings::StateChain,
BrokerApi, OperatorApi, StateChainApi,
BrokerApi, OperatorApi, StateChainApi, WithdrawFeesDetail,
};

use clap::Parser;
use futures::FutureExt;
use jsonrpsee::{
Expand Down Expand Up @@ -56,6 +57,13 @@ pub trait Rpc {
channel_metadata: Option<CcmChannelMetadata>,
boost_fee: Option<BasisPoints>,
) -> RpcResult<BrokerSwapDepositAddress>;

#[method(name = "withdraw_fees", aliases = ["broker_withdrawFees"])]
async fn withdraw_fees(
&self,
asset: Asset,
destination_address: String,
) -> RpcResult<WithdrawFeesDetail>;
}

pub struct RpcServerImpl {
Expand Down Expand Up @@ -108,6 +116,18 @@ impl RpcServer for RpcServerImpl {
.await
.map(BrokerSwapDepositAddress::from)?)
}

async fn withdraw_fees(
&self,
asset: Asset,
destination_address: String,
) -> RpcResult<WithdrawFeesDetail> {
Ok(self
.api
.broker_api()
.withdraw_fees(asset, clean_foreign_chain_address(asset.into(), &destination_address)?)
.await?)
}
}

#[derive(Parser, Debug, Clone, Default)]
Expand Down
13 changes: 13 additions & 0 deletions api/bin/chainflip-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ async fn run_cli() -> Result<()> {
.await?;
println!("Deposit Address: {address}");
},
Broker(BrokerSubcommands::WithdrawFees(params)) => {
let withdraw_details = api
.broker_api()
.withdraw_fees(
params.asset,
chainflip_api::clean_foreign_chain_address(
params.asset.into(),
&params.destination_address,
)?,
)
.await?;
println!("Withdrawal request successfull submitted: {}", withdraw_details);
},
LiquidityProvider(
LiquidityProviderSubcommands::RequestLiquidityDepositAddress {
asset,
Expand Down
9 changes: 8 additions & 1 deletion api/bin/chainflip-cli/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,18 @@ pub struct SwapRequestParams {
/// Commission to the booster in basis points
pub boost_fee: Option<u16>,
}

#[derive(Parser, Clone, Debug)]
pub struct WithdrawFeesParams {
/// Asset to withdraw ("ETH"|"DOT")
pub asset: Asset,
/// Egress asset address to receive withdrawn funds
pub destination_address: String,
}
#[derive(clap::Subcommand, Clone, Debug)]
pub enum BrokerSubcommands {
/// Request a swap deposit address.
RequestSwapDepositAddress(SwapRequestParams),
WithdrawFees(WithdrawFeesParams),
}

#[derive(clap::Subcommand, Clone, Debug)]
Expand Down
74 changes: 72 additions & 2 deletions api/lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{str::FromStr, sync::Arc};
use std::{fmt, str::FromStr, sync::Arc};

use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
Expand All @@ -10,7 +10,7 @@ use cf_primitives::{AccountRole, Asset, BasisPoints, ChannelId, SemVer};
use futures::FutureExt;
use pallet_cf_governance::ExecutionMode;
use pallet_cf_validator::MAX_LENGTH_FOR_VANITY_NAME;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_consensus_grandpa::AuthorityId as GrandpaId;
pub use sp_core::crypto::AccountId32;
Expand Down Expand Up @@ -305,6 +305,35 @@ pub struct SwapDepositAddress {
pub source_chain_expiry_block: <AnyChain as cf_chains::Chain>::ChainBlockNumber,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct WithdrawFeesDetail {
pub tx_hash: H256,
pub egress_id: (ForeignChain, u64),
pub egress_amount: u128,
pub egress_fee: u128,
pub destination_address: String,
}

impl fmt::Display for WithdrawFeesDetail {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"\
Tx hash: {:?}\n\
Egress id: {:?}\n\
Egress amount: {}\n\
Egress fee: {}\n\
Destination address: {}\n\
",
self.tx_hash,
self.egress_id,
self.egress_amount,
self.egress_fee,
self.destination_address,
)
}
}

#[async_trait]
pub trait BrokerApi: SignedExtrinsicApi {
async fn request_swap_deposit_address(
Expand Down Expand Up @@ -356,6 +385,47 @@ pub trait BrokerApi: SignedExtrinsicApi {
bail!("No SwapDepositAddressReady event was found");
}
}
async fn withdraw_fees(
&self,
asset: Asset,
destination_address: EncodedAddress,
) -> Result<WithdrawFeesDetail> {
let (tx_hash, events, ..) = self
.submit_signed_extrinsic(RuntimeCall::from(pallet_cf_swapping::Call::withdraw {
asset,
destination_address,
}))
.await
.until_in_block()
.await
.context("Request to withdraw broker fee for ${asset} failed.")?;

if let Some(state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::WithdrawalRequested {
egress_amount,
egress_fee,
destination_address,
egress_id,
},
)) = events.iter().find(|event| {
matches!(
event,
state_chain_runtime::RuntimeEvent::Swapping(
pallet_cf_swapping::Event::WithdrawalRequested { .. }
)
)
}) {
Ok(WithdrawFeesDetail {
tx_hash,
egress_id: *egress_id,
egress_amount: *egress_amount,
egress_fee: *egress_fee,
destination_address: destination_address.to_string(),
})
} else {
bail!("No WithdrawalRequested event was found");
}
}
}

/// Sanitize the given address (hex or base58) and turn it into a EncodedAddress of the given
Expand Down

0 comments on commit f05ac0f

Please sign in to comment.