Problem
Across the codebase, amounts are passed as raw integers (u64, i64, long) with no enforced unit. This leads to ambiguity and potential bugs when different parts of the stack use different conventions — e.g. pay_invoice returning fees in sats vs the protocol defaulting to msat.
Related: the pay_invoice trait was recently updated to return fees in sats (#149), which surfaced this inconsistency.
Proposal
Introduce an Amount type in portal (core crate) that makes the unit explicit:
pub enum Amount {
Millisats(u64),
Sats(u64),
}
impl Amount {
pub fn to_msat(&self) -> u64 { ... }
pub fn to_sat(&self) -> u64 { ... }
}
All protocol-level structs (payment requests, wallet trait, responses) should use Amount instead of bare integers, eliminating implicit unit assumptions.
Benefits
- No more silent msat/sat mismatches
- Easier to audit and refactor payment flows
- Cleaner FFI/bindings (the type carries its unit)
Scope
portal core crate: payment request/response types
portal-wallet trait (pay_invoice, get_wallet_info, etc.)
portal-rest wire format (serialization stays as msat for protocol compatibility)
- Bindings (UniFFI): expose
Amount as a proper enum
Problem
Across the codebase, amounts are passed as raw integers (
u64,i64,long) with no enforced unit. This leads to ambiguity and potential bugs when different parts of the stack use different conventions — e.g.pay_invoicereturning fees in sats vs the protocol defaulting to msat.Related: the
pay_invoicetrait was recently updated to return fees in sats (#149), which surfaced this inconsistency.Proposal
Introduce an
Amounttype inportal(core crate) that makes the unit explicit:All protocol-level structs (payment requests, wallet trait, responses) should use
Amountinstead of bare integers, eliminating implicit unit assumptions.Benefits
Scope
portalcore crate: payment request/response typesportal-wallettrait (pay_invoice,get_wallet_info, etc.)portal-restwire format (serialization stays as msat for protocol compatibility)Amountas a proper enum