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

refactor: better lightning payment responses #32

Merged
merged 1 commit into from
Apr 27, 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
15 changes: 4 additions & 11 deletions fedimint-clientd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,11 @@ async fn main() -> Result<()> {
/// Lightning network related commands:
/// - `/fedimint/v2/ln/invoice`: Create a lightning invoice to receive payment
/// via gateway.
/// - `/fedimint/v2/ln/invoice-external-pubkey`: Create a lightning invoice to
/// receive payment via gateway with external pubkey.
/// - `/fedimint/v2/ln/invoice-external-pubkey-tweaked`: Create a lightning
/// invoice to receive payment via gateway with external pubkey.
/// - `/fedimint/v2/ln/await-invoice`: Wait for incoming invoice to be paid.
/// - `/fedimint/v2/ln/claim-external-receive`: Claim an external receive.
/// - `/fedimint/v2/ln/claim-external-receive-tweaked`: Claim an external
/// receive.
/// - `/fedimint/v2/ln/pay`: Pay a lightning invoice or lnurl via a gateway.
/// - `/fedimint/v2/ln/await-pay`: Wait for a lightning payment to complete.
/// - `/fedimint/v2/ln/list-gateways`: List registered gateways.
Expand Down Expand Up @@ -228,10 +229,6 @@ fn fedimint_v2_rest() -> Router<AppState> {

let ln_router = Router::new()
.route("/invoice", post(fedimint::ln::invoice::handle_rest))
.route(
"/invoice-external-pubkey",
post(fedimint::ln::invoice_external_pubkey::handle_rest),
)
.route(
"/invoice-external-pubkey-tweaked",
post(fedimint::ln::invoice_external_pubkey_tweaked::handle_rest),
Expand All @@ -240,10 +237,6 @@ fn fedimint_v2_rest() -> Router<AppState> {
"/await-invoice",
post(fedimint::ln::await_invoice::handle_rest),
)
.route(
"/claim-external-receive",
post(fedimint::ln::claim_external_receive::handle_rest),
)
.route(
"/claim-external-receive-tweaked",
post(fedimint::ln::claim_external_receive_tweaked::handle_rest),
Expand Down
2 changes: 1 addition & 1 deletion fedimint-clientd/src/router/handlers/fedimint/admin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use fedimint_mint_client::MintClientModule;
use fedimint_wallet_client::WalletClientModule;
use info::InfoResponse;

pub async fn get_note_summary(client: &ClientHandleArc) -> anyhow::Result<InfoResponse> {
pub async fn _get_note_summary(client: &ClientHandleArc) -> anyhow::Result<InfoResponse> {
let mint_client = client.get_first_module::<MintClientModule>();
let wallet_client = client.get_first_module::<WalletClientModule>();
let summary = mint_client
Expand Down
43 changes: 23 additions & 20 deletions fedimint-clientd/src/router/handlers/fedimint/ln/await_invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ use fedimint_core::config::FederationId;
use fedimint_core::core::OperationId;
use fedimint_ln_client::{LightningClientModule, LnReceiveState};
use futures_util::StreamExt;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tracing::info;
use tracing::{debug, error, info};

use crate::error::AppError;
use crate::router::handlers::fedimint::admin::get_note_summary;
use crate::router::handlers::fedimint::admin::info::InfoResponse;
use crate::state::AppState;

#[derive(Debug, Deserialize)]
Expand All @@ -23,31 +21,37 @@ pub struct AwaitInvoiceRequest {
pub federation_id: FederationId,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AwaitInvoiceResponse {
pub status: LnReceiveState,
}

async fn _await_invoice(
client: ClientHandleArc,
req: AwaitInvoiceRequest,
) -> Result<InfoResponse, AppError> {
) -> Result<AwaitInvoiceResponse, AppError> {
let lightning_module = &client.get_first_module::<LightningClientModule>();
let mut updates = lightning_module
.subscribe_ln_receive(req.operation_id)
.await?
.into_stream();
info!(
"Created await invoice stream for operation id: {}",
req.operation_id
);
while let Some(update) = updates.next().await {
info!("Update: {update:?}");
match update {
debug!("Update: {update:?}");
match &update {
LnReceiveState::Claimed => {
return Ok(get_note_summary(&client).await?);
return Ok(AwaitInvoiceResponse { status: update });
}
LnReceiveState::Canceled { reason } => {
return Err(AppError::new(
StatusCode::INTERNAL_SERVER_ERROR,
anyhow!(reason),
))
error!("Invoice canceled: {}", reason);
return Ok(AwaitInvoiceResponse { status: update });
}
_ => {}
}

info!("Update: {update:?}");
}

Err(AppError::new(
Expand All @@ -60,17 +64,16 @@ pub async fn handle_ws(state: AppState, v: Value) -> Result<Value, AppError> {
let v = serde_json::from_value::<AwaitInvoiceRequest>(v)
.map_err(|e| AppError::new(StatusCode::BAD_REQUEST, anyhow!("Invalid request: {}", e)))?;
let client = state.get_client(v.federation_id).await?;
let invoice = _await_invoice(client, v).await?;
let invoice_json = json!(invoice);
Ok(invoice_json)
let invoice_response = _await_invoice(client, v).await?;
Ok(json!(invoice_response))
}

#[axum_macros::debug_handler]
pub async fn handle_rest(
State(state): State<AppState>,
Json(req): Json<AwaitInvoiceRequest>,
) -> Result<Json<InfoResponse>, AppError> {
) -> Result<Json<AwaitInvoiceResponse>, AppError> {
let client = state.get_client(req.federation_id).await?;
let invoice = _await_invoice(client, req).await?;
Ok(Json(invoice))
let invoice_response = _await_invoice(client, req).await?;
Ok(Json(invoice_response))
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ use fedimint_client::ClientHandleArc;
use fedimint_core::config::FederationId;
use fedimint_ln_client::{LightningClientModule, LnReceiveState};
use futures_util::StreamExt;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tracing::info;
use tracing::{debug, error, info};

use crate::error::AppError;
use crate::router::handlers::fedimint::admin::get_note_summary;
use crate::router::handlers::fedimint::admin::info::InfoResponse;
use crate::state::AppState;

#[derive(Debug, Deserialize)]
Expand All @@ -25,44 +23,51 @@ pub struct ClaimExternalReceiveTweakedRequest {
pub federation_id: FederationId,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClaimExternalReceiveTweakedResponse {
pub status: LnReceiveState,
}

async fn _await_claim_external_receive_tweaked(
client: ClientHandleArc,
req: ClaimExternalReceiveTweakedRequest,
) -> Result<InfoResponse, AppError> {
) -> Result<ClaimExternalReceiveTweakedResponse, AppError> {
let secp = Secp256k1::new();
let key_pair = KeyPair::from_secret_key(&secp, &req.private_key);
let lightning_module = &client.get_first_module::<LightningClientModule>();
let operation_id = lightning_module
.scan_receive_for_user_tweaked(key_pair, req.tweaks, ())
.await;

let mut final_response = get_note_summary(&client).await?;
for operation_id in operation_id {
let mut updates = lightning_module
.subscribe_ln_claim(operation_id)
.await?
.into_stream();

info!(
"Created claim external receive tweaked stream for operation id: {}",
operation_id
);
while let Some(update) = updates.next().await {
info!("Update: {update:?}");
match update {
debug!("Update: {update:?}");
match &update {
LnReceiveState::Claimed => {
final_response = get_note_summary(&client).await?;
return Ok(ClaimExternalReceiveTweakedResponse { status: update });
}
LnReceiveState::Canceled { reason } => {
return Err(AppError::new(
StatusCode::INTERNAL_SERVER_ERROR,
anyhow!(reason),
))
error!("Claim canceled: {}", reason);
return Ok(ClaimExternalReceiveTweakedResponse { status: update });
}
_ => {}
}

info!("Update: {update:?}");
}
}

Ok(final_response)
Err(AppError::new(
StatusCode::INTERNAL_SERVER_ERROR,
anyhow!("Unexpected end of stream"),
))
}

pub async fn handle_ws(state: AppState, v: Value) -> Result<Value, AppError> {
Expand All @@ -78,8 +83,8 @@ pub async fn handle_ws(state: AppState, v: Value) -> Result<Value, AppError> {
pub async fn handle_rest(
State(state): State<AppState>,
Json(req): Json<ClaimExternalReceiveTweakedRequest>,
) -> Result<Json<InfoResponse>, AppError> {
) -> Result<Json<ClaimExternalReceiveTweakedResponse>, AppError> {
let client = state.get_client(req.federation_id).await?;
let invoice = _await_claim_external_receive_tweaked(client, req).await?;
Ok(Json(invoice))
let invoice_response = _await_claim_external_receive_tweaked(client, req).await?;
Ok(Json(invoice_response))
}

This file was deleted.

Loading
Loading