Skip to content

fix: return fees_paid_msat from NWC pay_invoice uniffi binding#154

Merged
afilini merged 2 commits intomasterfrom
fix/nwc-pay-invoice-return-fees
Feb 22, 2026
Merged

fix: return fees_paid_msat from NWC pay_invoice uniffi binding#154
afilini merged 2 commits intomasterfrom
fix/nwc-pay-invoice-return-fees

Conversation

@portal-wheatley
Copy link
Contributor

Problem

The portal-app uniffi binding for NWC.pay_invoice was returning only the preimage string, silently discarding the fees_paid field from the NIP-47 response:

// before
pub async fn pay_invoice(&self, invoice: String) -> Result<String, AppError> {
    let response = self.inner.pay_invoice(...).await?;
    Ok(response.preimage) // fees_paid thrown away
}

This meant NwcService.sendPayment in portal-app had no way to surface NWC payment fees — it always returned { preimage } with no feeSats, so the activity detail screen always showed "N/A" for fees on NWC payments.

Root Cause

The internal portal-wallet NwcWallet trait was already updated in #149 to return (preimage, fees_paid_msat) — but that change lives in the portal-rest websocket server path. The portal-app uniffi binding (crates/portal-app/src/nwc.rs) is a separate code path used by the React Native client directly, and was not updated.

Fix

Introduce a PayInvoiceResult record (uniffi does not support tuple return types) containing both preimage and fees_paid_msat, and return it from the uniffi-exported pay_invoice:

#[derive(uniffi::Record)]
pub struct PayInvoiceResult {
    pub preimage: String,
    /// Fees in millisatoshis. Zero if the NWC wallet did not report fees (NIP-47 fees_paid is optional).
    pub fees_paid_msat: u64,
}

fees_paid is Option<u64> in the NIP-47 response, so we default to 0 when absent.

Portal-app side

After this lib version is published, NwcService.sendPayment in portal-app can be updated to:

const result = await this.client.payInvoice(paymentRequest);
return {
  preimage: result.preimage,
  feeSats: Math.floor(result.fees_paid_msat / 1000),
};

The portal-app uniffi binding for NwcWallet.pay_invoice was returning
only the preimage string, discarding the fees_paid field from the NIP-47
response.

This meant that portal-app could not surface NWC payment fees to the
UI — the TypeScript NwcService.sendPayment always returned
{ preimage } with no feeSats, causing 'N/A' to be shown in the
activity detail screen.

The fix introduces a PayInvoiceResult record (uniffi does not support
tuple return types) containing both the preimage and fees_paid_msat.
fees_paid is optional in NIP-47, so we default to 0 when absent.

Note: the internal portal-wallet NwcWallet trait was already updated in
the pay-invoice-return-fees-paid PR — this change closes the gap at the
uniffi binding layer so portal-app can consume the fees.
@afilini afilini merged commit 6985477 into master Feb 22, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants