Skip to content

Commit

Permalink
feat: onchain send (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandipndev authored Aug 1, 2023
1 parent e3df165 commit 171ce74
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

42 changes: 41 additions & 1 deletion src/app/operations/onchain.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
use anyhow::Context;
use anyhow::{Context, Result};
use rust_decimal::Decimal;

use crate::{
app::App,
client::types::{ReceiveVia, Wallet},
};

impl App {
pub async fn send_onchain(
&self,
onchain_address: String,
wallet: Wallet,
cents: Option<Decimal>,
sats: Option<Decimal>,
memo: Option<String>,
) -> Result<()> {
match (wallet, sats, cents) {
(Wallet::Btc, Some(sats), _) => {
let btc_wallet_id = self.get_user_btc_wallet_id().await?;
self.client
.onchain_payment_send(btc_wallet_id, onchain_address.clone(), sats, memo)
.await
.context("Error occurred while executing BTC onchain payment")?;

println!(
"Successfully sent {} sats to address: {}",
sats, onchain_address
);
}
(Wallet::Usd, _, Some(cents)) => {
let usd_wallet_id = self.get_user_usd_wallet_id().await?;
self.client
.onchain_payment_send(usd_wallet_id, onchain_address.clone(), cents, memo)
.await
.context("Error occurred while executing USD onchain payment")?;

println!(
"Successfully sent {} cents to address: {}",
cents, onchain_address
);
}
_ => {}
}

Ok(())
}

pub async fn receive(&self, wallet: Wallet, via: ReceiveVia) -> anyhow::Result<()> {
let receiving_wallet_id = match wallet {
Wallet::Btc => self.get_user_btc_wallet_id().await?,
Expand Down
4 changes: 3 additions & 1 deletion src/cli/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ pub enum Command {
/// Execute a Payment
Pay {
#[clap(short, long)]
username: String,
username: Option<String>,
#[clap(short, long, conflicts_with("username"))]
onchain_address: Option<String>,
#[clap(short, long, value_parser)]
wallet: Wallet,
#[clap(short, long, required_if_eq("wallet", "usd"))]
Expand Down
16 changes: 12 additions & 4 deletions src/cli/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,22 @@ pub async fn run() -> anyhow::Result<()> {
}
Command::Pay {
username,
onchain_address,
wallet,
cents,
sats,
memo,
} => {
app.intraledger_payment(username, wallet, cents, sats, memo)
.await?;
}
} => match (username, onchain_address) {
(Some(username), None) => {
app.intraledger_payment(username, wallet, cents, sats, memo)
.await?;
}
(None, Some(onchain_address)) => {
app.send_onchain(onchain_address, wallet, cents, sats, memo)
.await?;
}
_ => {}
},
Command::Receive { wallet, via } => {
app.receive(wallet, via).await?;
}
Expand Down
10 changes: 10 additions & 0 deletions src/client/gql/mutations/onchain_payment_send.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
mutation OnChainPaymentSend($input: OnChainPaymentSendInput!) {
onChainPaymentSend(input: $input) {
errors {
message
__typename
}
status
__typename
}
}
11 changes: 11 additions & 0 deletions src/client/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,14 @@ use super::errors::captcha_error::CaptchaError;
pub(super) struct OnChainAddressCurrent;
pub use self::on_chain_address_current::OnChainAddressCurrentInput;
pub use self::on_chain_address_current::OnChainAddressCurrentOnChainAddressCurrent;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "src/client/gql/schema.gql",
query_path = "src/client/gql/mutations/onchain_payment_send.gql",
response_derives = "Debug, Serialize"
)]
pub(super) struct OnChainPaymentSend;
pub use self::on_chain_payment_send::OnChainPaymentSendInput;
pub use self::on_chain_payment_send::OnChainPaymentSendOnChainPaymentSend;
pub use self::on_chain_payment_send::PayoutSpeed;
47 changes: 46 additions & 1 deletion src/client/requests/onchain.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use graphql_client::reqwest::post_graphql;
use on_chain_address_current::OnChainAddressCurrentOnChainAddressCurrent;
use rust_decimal::Decimal;

use crate::client::{
errors::{api_error::ApiError, ClientError},
queries::{on_chain_address_current, OnChainAddressCurrent},
queries::{
on_chain_address_current, on_chain_payment_send, OnChainAddressCurrent, OnChainPaymentSend,
OnChainPaymentSendInput, PayoutSpeed,
},
GaloyClient,
};

Expand All @@ -28,4 +32,45 @@ impl GaloyClient {

Ok(result)
}

pub async fn onchain_payment_send(
&self,
sender_wallet_id: String,
onchain_address: String,
amount: Decimal,
memo: Option<String>,
) -> Result<(), ClientError> {
let input = OnChainPaymentSendInput {
wallet_id: sender_wallet_id,
address: onchain_address,
speed: Some(PayoutSpeed::FAST),
amount,
memo,
};

let variables = on_chain_payment_send::Variables { input };

let response_body =
post_graphql::<OnChainPaymentSend, _>(&self.graphql_client, &self.api, variables)
.await
.map_err(|err| ApiError::IssueGettingResponse(anyhow::Error::new(err)))?;

let response_data = response_body.data.ok_or(ApiError::IssueParsingResponse)?;

if !response_data.on_chain_payment_send.errors.is_empty() {
let error_string: String = response_data
.on_chain_payment_send
.errors
.iter()
.map(|error| format!("{:?}", error))
.collect::<Vec<String>>()
.join(", ");

return Err(ClientError::ApiError(ApiError::RequestFailedWithError(
error_string,
)));
} else {
Ok(())
}
}
}

0 comments on commit 171ce74

Please sign in to comment.