Simplify Swift invoice handling with non-optional return types
- Mentions.swift: convert_invoice_description now returns non-optional InvoiceDescription, returning empty description for BOLT11 compliance (both description and description_hash are optional per spec) - Block.swift, NdbBlock.swift, NostrEvent.swift, NoteContent.swift: Updated call sites to use non-optional invoice conversion - InvoiceTests.swift: Added test for specific failing invoice Signed-off-by: alltheseas <alltheseas@noreply.github.com> Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Daniel D’Aquino
parent
845089bed1
commit
1505a8f2e4
@@ -294,16 +294,19 @@ func format_msats(_ msat: Int64, locale: Locale = Locale.current) -> String {
|
||||
return String(format: format, locale: locale, sats.decimalValue as NSDecimalNumber, formattedSats)
|
||||
}
|
||||
|
||||
func convert_invoice_description(b11: ndb_invoice) -> InvoiceDescription? {
|
||||
/// Extracts the description from a BOLT11 invoice.
|
||||
/// Returns empty description if invoice has neither description nor description_hash,
|
||||
/// as both fields are optional per BOLT11 spec.
|
||||
func convert_invoice_description(b11: ndb_invoice) -> InvoiceDescription {
|
||||
if let desc = b11.description {
|
||||
return .description(String(cString: desc))
|
||||
}
|
||||
|
||||
|
||||
if var deschash = maybe_pointee(b11.description_hash) {
|
||||
return .description_hash(Data(bytes: &deschash, count: 32))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return .description("")
|
||||
}
|
||||
|
||||
func find_tag_ref(type: String, id: String, tags: [[String]]) -> Int? {
|
||||
|
||||
@@ -839,9 +839,7 @@ func separate_invoices(ndb: Ndb, ev: NostrEvent, keypair: Keypair) -> [Invoice]?
|
||||
let invoiceBlocks: [Invoice] = (try? blockGroup.reduce(initialResult: [Invoice](), { index, invoices, block in
|
||||
switch block {
|
||||
case .invoice(let invoice):
|
||||
if let invoice = invoice.as_invoice() {
|
||||
return .loopReturn(invoices + [invoice])
|
||||
}
|
||||
return .loopReturn(invoices + [invoice.as_invoice()])
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -79,8 +79,7 @@ extension Block {
|
||||
guard let url = URL(string: block.as_str()) else { return nil }
|
||||
self = .url(url)
|
||||
case BLOCK_INVOICE:
|
||||
guard let b = Block(invoice: block.block.invoice) else { return nil }
|
||||
self = b
|
||||
self = Block(invoice: block.block.invoice)
|
||||
case BLOCK_MENTION_BECH32:
|
||||
guard let b = Block(bech32: block.block.mention_bech32) else { return nil }
|
||||
self = b
|
||||
@@ -113,26 +112,20 @@ fileprivate extension Block {
|
||||
}
|
||||
|
||||
fileprivate extension Block {
|
||||
/// Failable initializer for the C-backed type `invoice_block_t`.
|
||||
init?(invoice: ndb_invoice_block) {
|
||||
|
||||
guard let invoice = invoice_block_as_invoice(invoice) else { return nil }
|
||||
self = .invoice(invoice)
|
||||
/// Initializer for the C-backed type `invoice_block_t`.
|
||||
init(invoice: ndb_invoice_block) {
|
||||
self = .invoice(invoice_block_as_invoice(invoice))
|
||||
}
|
||||
}
|
||||
|
||||
func invoice_block_as_invoice(_ invoice: ndb_invoice_block) -> Invoice? {
|
||||
/// Converts a C-backed invoice block to a Swift Invoice.
|
||||
func invoice_block_as_invoice(_ invoice: ndb_invoice_block) -> Invoice {
|
||||
let invstr = invoice.invstr.as_str()
|
||||
let b11 = invoice.invoice
|
||||
|
||||
guard let description = convert_invoice_description(b11: b11) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let description = convert_invoice_description(b11: b11)
|
||||
let amount: Amount = b11.amount == 0 ? .any : .specific(Int64(b11.amount))
|
||||
|
||||
return Invoice(description: description, amount: amount, string: invstr, expiry: b11.expiry, created_at: b11.timestamp)
|
||||
|
||||
}
|
||||
|
||||
fileprivate extension Block {
|
||||
|
||||
Reference in New Issue
Block a user