Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add precision validation for Moonpay call #576

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ impl PaymentError {
}
}

pub(crate) fn invalid_network(err: &str) -> Self {
Self::InvalidNetwork {
err: err.to_string(),
}
}

pub(crate) fn receive_error(err: &str) -> Self {
Self::ReceiveError {
err: err.to_string(),
Expand Down
21 changes: 16 additions & 5 deletions lib/core/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,19 @@ impl LiquidSdk {
Ok(())
}

fn validate_buy_bitcoin(&self, amount_sat: u64) -> Result<(), PaymentError> {
ensure_sdk!(
self.config.network == LiquidNetwork::Mainnet,
PaymentError::invalid_network("Can only buy bitcoin on Mainnet")
);
// The Moonpay API defines BTC amounts as having precision = 5, so only 5 decimals are considered
ensure_sdk!(
amount_sat % 1_000 == 0,
PaymentError::generic("Can only buy sat amounts that are multiples of 1000")
);
Ok(())
}

/// Prepares to buy Bitcoin via a chain swap.
///
/// # Arguments
Expand All @@ -2108,11 +2121,7 @@ impl LiquidSdk {
&self,
req: &PrepareBuyBitcoinRequest,
) -> Result<PrepareBuyBitcoinResponse, PaymentError> {
if self.config.network != LiquidNetwork::Mainnet {
return Err(PaymentError::InvalidNetwork {
err: "Can only buy bitcoin on Mainnet".to_string(),
});
}
self.validate_buy_bitcoin(req.amount_sat)?;

let res = self
.prepare_receive_payment(&PrepareReceiveRequest {
Expand Down Expand Up @@ -2145,6 +2154,8 @@ impl LiquidSdk {
/// * `prepare_response` - the [PrepareBuyBitcoinResponse] from calling [LiquidSdk::prepare_buy_bitcoin]
/// * `redirect_url` - the optional redirect URL the provider should redirect to after purchase
pub async fn buy_bitcoin(&self, req: &BuyBitcoinRequest) -> Result<String, PaymentError> {
self.validate_buy_bitcoin(req.prepare_response.amount_sat)?;

let swap = self
.create_receive_chain_swap(
req.prepare_response.amount_sat,
Expand Down
Loading