Skip to content

Commit

Permalink
allow to send keysend payments
Browse files Browse the repository at this point in the history
  • Loading branch information
joksas committed Aug 18, 2024
1 parent 90dfa36 commit 2ba802b
Showing 1 changed file with 170 additions and 5 deletions.
175 changes: 170 additions & 5 deletions src/alby/api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::alby::helpers::{make_request, RequestArgs, RequestError};
use crate::alby::helpers::{make_request, ErrorResponse, RequestArgs, RequestError};
use chrono::{DateTime, Utc};
use std::collections::HashMap;

/// Alby API functions related to the account.
///
Expand Down Expand Up @@ -60,6 +61,16 @@ pub mod invoices {
pub metadata: serde_json::Value,
}

/// Request body for [create_invoice].
#[derive(Debug, serde::Serialize)]
struct CreateInvoiceRequestBody {
/// The amount of sats.
#[serde(rename = "amount")]
pub num_sats: u64,
/// Arbitary metadata.
pub metadata: serde_json::Value,
}

/// Response for a successful invoice creation.
#[derive(Debug, serde::Deserialize)]
pub struct CreateInvoiceResponse {
Expand All @@ -75,10 +86,10 @@ pub mod invoices {
pub async fn create_invoice(
args: CreateInvoiceArgs<'_>,
) -> Result<CreateInvoiceResponse, RequestError> {
let request_body = serde_json::json!({
"amount": args.num_sats,
"metadata": args.metadata,
});
let request_body = CreateInvoiceRequestBody {
num_sats: args.num_sats,
metadata: args.metadata.clone(),
};

let body = serde_json::to_string(&request_body).map_err(RequestError::ResponseParse)?;

Expand All @@ -93,3 +104,157 @@ pub mod invoices {
make_request(request_args).await
}
}

/// Alby API functions related to payments.
///
/// Read more at
/// <https://guides.getalby.com/developer-guide/v/alby-wallet-api/reference/api-reference/payments>.
pub mod payments {
use super::*;

/// Arguments for [keysend].
pub struct KeysendArgs<'a> {
/// User agent string.
pub user_agent: &'a str,
/// Bearer token for authentication.
pub token: &'a str,
/// The amount of sats.
pub num_sats: u64,
/// Destination node pubkey.
pub dest_pubkey: &'a str,
/// Custom records.
pub custom_records: HashMap<String, String>,
}

/// Request body for [keysend].
#[derive(Debug, serde::Serialize)]
pub struct KeysendRequest {
/// The amount of sats.
#[serde(rename = "amount")]
pub num_sats: u64,
/// Destination node pubkey.
#[serde(rename = "destination")]
pub dest_pubkey: String,
/// Custom records.
pub custom_records: HashMap<String, String>,
}

/// Response for a successful keysend.
#[derive(Debug, serde::Deserialize)]
pub struct KeysendResponse {
/// The amount of sats.
#[serde(rename = "amount")]
pub num_sats: u64,
/// Description.
pub description: String,
/// Description hash.
pub description_hash: String,
/// Destination node pubkey.
#[serde(rename = "destination")]
pub dest_pubkey: String,
/// Fee in sats.
#[serde(rename = "fee")]
pub fee_in_sats: u64,
/// Custom records.
pub custom_records: HashMap<String, String>,
/// Payment hash.
pub payment_hash: String,
/// Payment preimage.
pub payment_preimage: String,
}

/// Send a keysend payment using the Alby API.
pub async fn keysend(args: KeysendArgs<'_>) -> Result<KeysendResponse, RequestError> {
let request_body = KeysendRequest {
num_sats: args.num_sats,
dest_pubkey: args.dest_pubkey.to_string(),
custom_records: args.custom_records.clone(),
};

let body = serde_json::to_string(&request_body).map_err(RequestError::ResponseParse)?;

let request_args = RequestArgs {
user_agent: args.user_agent,
method: reqwest::Method::POST,
url: "https://api.getalby.com/payments/keysend",
token: args.token,
body: Some(&body),
};

make_request(request_args).await
}

/// Request body for [multi_keysend].
#[derive(Debug, serde::Serialize)]
pub struct MultiKeysendRequest {
/// Array of keysend objects.
pub keysends: Vec<KeysendRequest>,
}

/// Keysend item response for [multi_keysend].
#[derive(Debug, serde::Deserialize)]
pub struct MultiKeysendItemResponse {
/// Error.
pub error: ErrorResponse,
/// Keysend response.
pub keysend: KeysendResponse,
}

/// Response for a successful [multi_keysend].
#[derive(Debug, serde::Deserialize)]
pub struct MultiKeysendResponse {
/// Array of keysend responses.
pub keysends: Vec<MultiKeysendItemResponse>,
}

/// [multi_keysend] keysend item.
pub struct MultiKeysendItemArgs<'a> {
/// The amount of sats.
pub num_sats: u64,
/// Destination node pubkey.
pub dest_pubkey: &'a str,
/// Custom records.
pub custom_records: HashMap<String, String>,
}

/// Arguments for [keysend].
pub struct MultiKeysendArgs<'a> {
/// User agent string.
pub user_agent: &'a str,
/// Bearer token for authentication.
pub token: &'a str,
/// Keysend items.
pub keysends: Vec<MultiKeysendItemArgs<'a>>,
}

/// Send multiple keysend payments using the Alby API.
pub async fn multi_keysend(
args: MultiKeysendArgs<'_>,
) -> Result<MultiKeysendResponse, RequestError> {
let mut keysends = Vec::new();

for item in args.keysends.iter() {
let request = KeysendRequest {
num_sats: item.num_sats,
dest_pubkey: item.dest_pubkey.to_string(),
custom_records: item.custom_records.clone(),
};

keysends.push(request);
}

let request_body = MultiKeysendRequest { keysends };

let body = serde_json::to_string(&request_body).map_err(RequestError::ResponseParse)?;

let request_args = RequestArgs {
user_agent: args.user_agent,
method: reqwest::Method::POST,
url: "https://api.getalby.com/payments/multi",
token: args.token,
body: Some(&body),
};

make_request(request_args).await
}
}

0 comments on commit 2ba802b

Please sign in to comment.