Wait for invoice to be paid #941

Closed
opened 2025-08-07 15:49:40 +00:00 by thesimplekid · 2 comments
thesimplekid commented 2025-08-07 15:49:40 +00:00 (Migrated from github.com)

Currently we don't have a nice fn on the wallet that will wait for an invoice to be paid. If you look at the examples we look checking for state. We should add a wallet fn that takes a mint quote and a time out and just waits until it is paid and mints once it is, erroring if it can't mint or times out

Currently we don't have a nice fn on the wallet that will wait for an invoice to be paid. If you look at the examples we look checking for state. We should add a wallet fn that takes a mint quote and a time out and just waits until it is paid and mints once it is, erroring if it can't mint or times out
crodas commented 2025-08-11 15:37:12 +00:00 (Migrated from github.com)

I think it would be best if a future is returned, and the caller decides how to wait on that event, either in that thread or in another thread. Do you think that would be better and more idiomatic?

let waiter = wallet.wait_for_payment(&quote.id, Duration::from_secs(10));

Alternatively we can add more enphasis in our subscription layer, perhaps adding a timeout factor, from this current code:

    // Subscribe to updates on the mint quote state
    let mut subscription = wallet
        .subscribe(WalletSubscription::Bolt11MintQuoteState(vec![quote
            .id
            .clone()]))
        .await;

    // Wait for the mint quote to be paid
    while let Some(msg) = subscription.recv().await {
        if let NotificationPayload::MintQuoteBolt11Response(response) = msg {
            if response.state == MintQuoteState::Paid {
                break;
            }
        }
    }

To this version

    // Subscribe to updates on the mint quote state
    let mut subscription = wallet
        .subscribe_with_timepit(WalletSubscription::Bolt11MintQuoteState(vec![quote
            .id
            .clone()]), Duration::from_secs(60) )
        .await;

    // Wait for the mint quote to be paid or an error will be thrown if the timeout is reached and *no* notification has been received
    while let Some(msg) = subscription.recv().await {
        if let NotificationPayload::MintQuoteBolt11Response(response) = msg {
            if response.state == MintQuoteState::Paid {
                break;
            }
        }
    }

The wallet notification will use websocket or http underneath.

I think it would be best if a future is returned, and the caller decides how to wait on that event, either in that thread or in another thread. Do you think that would be better and more idiomatic? ```rust let waiter = wallet.wait_for_payment(&quote.id, Duration::from_secs(10)); ``` Alternatively we can add more enphasis in our subscription layer, perhaps adding a timeout factor, from this current code: ```rust // Subscribe to updates on the mint quote state let mut subscription = wallet .subscribe(WalletSubscription::Bolt11MintQuoteState(vec![quote .id .clone()])) .await; // Wait for the mint quote to be paid while let Some(msg) = subscription.recv().await { if let NotificationPayload::MintQuoteBolt11Response(response) = msg { if response.state == MintQuoteState::Paid { break; } } } ``` To this version ```rust // Subscribe to updates on the mint quote state let mut subscription = wallet .subscribe_with_timepit(WalletSubscription::Bolt11MintQuoteState(vec![quote .id .clone()]), Duration::from_secs(60) ) .await; // Wait for the mint quote to be paid or an error will be thrown if the timeout is reached and *no* notification has been received while let Some(msg) = subscription.recv().await { if let NotificationPayload::MintQuoteBolt11Response(response) = msg { if response.state == MintQuoteState::Paid { break; } } } ``` The wallet notification will use websocket or http underneath.
thesimplekid commented 2025-08-11 18:15:03 +00:00 (Migrated from github.com)

I think the future is a good idea. This way the flow of minting is simplely

let quote = wallet.mint_quote(amount, None).await?;

let waiter = wallet.wait_for_payment(&quote.id, Duration::from_secs(10));
let proofs = waiter.await?;

Compared to the current where you have to implement the waiting yourself and then call mint.

github.com/cashubtc/cdk@d24a968bd4/crates/cdk/examples/wallet.rs (L29-L58)

I think the future is a good idea. This way the flow of minting is simplely ```rust let quote = wallet.mint_quote(amount, None).await?; let waiter = wallet.wait_for_payment(&quote.id, Duration::from_secs(10)); let proofs = waiter.await?; ``` Compared to the current where you have to implement the waiting yourself and then call mint. https://github.com/cashubtc/cdk/blob/d24a968bd45c50cdd661d8eef7b333604eabe1d8/crates/cdk/examples/wallet.rs#L29-L58
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cashubtc/cdk#941
No description provided.