Files
breez-sdk-liquid/lib/bindings/langs/swift/Sources/BreezSDKLiquid/Task/LnurlPayVerify.swift
Ross Savage 42c7bfe285 Add LNURL-verify notification plugin tasks (#911)
* Add LNURL-verify notification plugin tasks

* Only settled when MRH payment is complete

* Ignore unknown JSON keys

* Log fail replyURL

* Prevent escaping slashes
2025-05-15 06:26:32 +02:00

74 lines
3.4 KiB
Swift

import UserNotifications
import Foundation
struct LnurlVerifyRequest: Codable {
let payment_hash: String
let reply_url: String
}
struct LnurlVerifyResponse: Decodable, Encodable {
let settled: Bool
let preimage: String?
let pr: String
init(settled: Bool, preimage: String?, pr: String) {
self.settled = settled
self.preimage = preimage
self.pr = pr
}
}
class LnurlPayVerifyTask : LnurlPayTask {
fileprivate let TAG = "LnurlPayVerifyTask"
init(payload: String, logger: ServiceLogger, contentHandler: ((UNNotificationContent) -> Void)? = nil, bestAttemptContent: UNMutableNotificationContent? = nil) {
let successNotificationTitle = ResourceHelper.shared.getString(key: Constants.LNURL_PAY_VERIFY_NOTIFICATION_TITLE, fallback: Constants.DEFAULT_LNURL_PAY_VERIFY_NOTIFICATION_TITLE)
let failNotificationTitle = ResourceHelper.shared.getString(key: Constants.LNURL_PAY_VERIFY_NOTIFICATION_FAILURE_TITLE, fallback: Constants.DEFAULT_LNURL_PAY_VERIFY_NOTIFICATION_FAILURE_TITLE)
super.init(payload: payload, logger: logger, contentHandler: contentHandler, bestAttemptContent: bestAttemptContent, successNotificationTitle: successNotificationTitle, failNotificationTitle: failNotificationTitle)
}
override func start(liquidSDK: BindingLiquidSdk) throws {
var request: LnurlVerifyRequest? = nil
do {
request = try JSONDecoder().decode(LnurlVerifyRequest.self, from: self.payload.data(using: .utf8)!)
} catch let e {
self.logger.log(tag: TAG, line: "failed to decode payload: \(e)", level: "ERROR")
self.displayPushNotification(title: self.failNotificationTitle, logger: self.logger, threadIdentifier: Constants.NOTIFICATION_THREAD_REPLACEABLE)
throw e
}
do {
// Get the payment by payment hash
let getPaymentReq = GetPaymentRequest.paymentHash(paymentHash: request!.payment_hash)
guard let payment = try liquidSDK.getPayment(req: getPaymentReq) else {
throw InvalidLnurlPayError.notFound
}
var response: LnurlVerifyResponse? = nil
switch payment.details {
case let .lightning(_, _, _, preimage, invoice, _, _, _, _, _, claimTxId, _, _):
// In the case of a Lightning payment, if it's paid via Lightning or MRH,
// we can release the preimage
let settled = switch payment.status {
case .pending:
// If the payment is pending, we need to check if it's paid via Lightning or MRH
claimTxId != nil
case .complete:
true
default:
false
}
response = LnurlVerifyResponse(settled: settled, preimage: settled ? preimage : nil, pr: invoice!)
default:
break
}
if response == nil {
throw InvalidLnurlPayError.notFound
}
replyServer(encodable: response, replyURL: request!.reply_url)
} catch let e {
self.logger.log(tag: TAG, line: "failed to process lnurl verify: \(e)", level: "ERROR")
fail(withError: e.localizedDescription, replyURL: request!.reply_url)
}
}
}