Add description and metadata to pay_invoice command
Changelog-Added: Zap receiver information now included for outgoing zaps Closes: https://github.com/damus-io/damus/issues/2927 Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -240,7 +240,7 @@ func send_zap(damus_state: DamusState, target: ZapTarget, lnurl: String, is_cust
|
|||||||
// we don't have a delay on one-tap nozaps (since this will be from customize zap view)
|
// we don't have a delay on one-tap nozaps (since this will be from customize zap view)
|
||||||
let delay = damus_state.settings.nozaps ? nil : 5.0
|
let delay = damus_state.settings.nozaps ? nil : 5.0
|
||||||
|
|
||||||
let nwc_req = WalletConnect.pay(url: nwc_state.url, pool: damus_state.nostrNetwork.pool, post: damus_state.nostrNetwork.postbox, invoice: inv, delay: delay, on_flush: flusher)
|
let nwc_req = WalletConnect.pay(url: nwc_state.url, pool: damus_state.nostrNetwork.pool, post: damus_state.nostrNetwork.postbox, invoice: inv, zap_request: zapreq, delay: delay, on_flush: flusher)
|
||||||
|
|
||||||
guard let nwc_req, case .nwc(let pzap_state) = pending_zap_state else {
|
guard let nwc_req, case .nwc(let pzap_state) = pending_zap_state else {
|
||||||
print("nwc: failed to send nwc request for zapreq \(reqid.reqid)")
|
print("nwc: failed to send nwc request for zapreq \(reqid.reqid)")
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ class HomeModel: ContactsDelegate {
|
|||||||
guard let nwc_str = damus_state.settings.nostr_wallet_connect,
|
guard let nwc_str = damus_state.settings.nostr_wallet_connect,
|
||||||
let nwc = WalletConnectURL(str: nwc_str),
|
let nwc = WalletConnectURL(str: nwc_str),
|
||||||
let resp = await WalletConnect.FullWalletResponse(from: ev, nwc: nwc) else {
|
let resp = await WalletConnect.FullWalletResponse(from: ev, nwc: nwc) else {
|
||||||
|
Log.error("HomeModel: Received NWC response I do not understand", for: .nwc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ extension WalletConnect {
|
|||||||
/// Pay an invoice
|
/// Pay an invoice
|
||||||
case payInvoice(
|
case payInvoice(
|
||||||
/// bolt-11 invoice string
|
/// bolt-11 invoice string
|
||||||
invoice: String
|
invoice: String,
|
||||||
|
/// The full description of the invoice (If description does not fit in the BOLT-11 invoice, this is the pre-image of the description hash)
|
||||||
|
description: String?,
|
||||||
|
/// Optional metadata object containing more information
|
||||||
|
metadata: Metadata?
|
||||||
)
|
)
|
||||||
/// Get the current wallet balance
|
/// Get the current wallet balance
|
||||||
case getBalance
|
case getBalance
|
||||||
@@ -33,6 +37,38 @@ extension WalletConnect {
|
|||||||
type: String?
|
type: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
static func payZapRequest(invoice: String, zapRequest: NostrEvent?) -> Self {
|
||||||
|
guard let zapRequest, let zapRequestEncoded = encode_json(zapRequest) else {
|
||||||
|
return WalletConnect.Request.payInvoice(
|
||||||
|
invoice: invoice,
|
||||||
|
description: nil,
|
||||||
|
metadata: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return WalletConnect.Request.payInvoice(
|
||||||
|
invoice: invoice,
|
||||||
|
description: zapRequestEncoded,
|
||||||
|
metadata: .init(nostr: zapRequest)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Metadata: Codable, Equatable, Hashable {
|
||||||
|
/// NIP-57-compliant `kind:9734` zap request event
|
||||||
|
let nostr: NostrEvent?
|
||||||
|
|
||||||
|
init(nostr: NostrEvent?) {
|
||||||
|
self.nostr = nostr
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from decoder: any Decoder) throws {
|
||||||
|
let container: KeyedDecodingContainer<WalletConnect.Request.Metadata.CodingKeys> = try decoder.container(keyedBy: WalletConnect.Request.Metadata.CodingKeys.self)
|
||||||
|
guard let decodedZapRequest = try? container.decodeIfPresent(NostrEvent.self, forKey: WalletConnect.Request.Metadata.CodingKeys.nostr) else {
|
||||||
|
self.nostr = nil // Be lenient and fallback to nil if the NWC provider provided something invalid, since metadata is not strictly spec'd yet.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.nostr = decodedZapRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Interface
|
// MARK: - Interface
|
||||||
|
|
||||||
@@ -61,7 +97,7 @@ extension WalletConnect {
|
|||||||
|
|
||||||
/// Keys for the JSON inside the "params" object
|
/// Keys for the JSON inside the "params" object
|
||||||
private enum ParamKeys: String, CodingKey {
|
private enum ParamKeys: String, CodingKey {
|
||||||
case invoice
|
case invoice, description, metadata
|
||||||
case from, until, limit, offset, unpaid, type
|
case from, until, limit, offset, unpaid, type
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +118,9 @@ extension WalletConnect {
|
|||||||
case Method.payInvoice.rawValue:
|
case Method.payInvoice.rawValue:
|
||||||
let paramsContainer = try container.nestedContainer(keyedBy: ParamKeys.self, forKey: .params)
|
let paramsContainer = try container.nestedContainer(keyedBy: ParamKeys.self, forKey: .params)
|
||||||
let invoice = try paramsContainer.decode(String.self, forKey: .invoice)
|
let invoice = try paramsContainer.decode(String.self, forKey: .invoice)
|
||||||
self = .payInvoice(invoice: invoice)
|
let description: String? = try paramsContainer.decodeIfPresent(String.self, forKey: .description)
|
||||||
|
let metadata: Metadata? = try paramsContainer.decodeIfPresent(Metadata.self, forKey: .metadata)
|
||||||
|
self = .payInvoice(invoice: invoice, description: description, metadata: metadata)
|
||||||
|
|
||||||
case Method.getBalance.rawValue:
|
case Method.getBalance.rawValue:
|
||||||
// No params to decode
|
// No params to decode
|
||||||
@@ -112,10 +150,12 @@ extension WalletConnect {
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
switch self {
|
switch self {
|
||||||
case .payInvoice(let invoice):
|
case .payInvoice(let invoice, let description, let metadata):
|
||||||
try container.encode(Method.payInvoice.rawValue, forKey: .method)
|
try container.encode(Method.payInvoice.rawValue, forKey: .method)
|
||||||
var paramsContainer = container.nestedContainer(keyedBy: ParamKeys.self, forKey: .params)
|
var paramsContainer = container.nestedContainer(keyedBy: ParamKeys.self, forKey: .params)
|
||||||
try paramsContainer.encode(invoice, forKey: .invoice)
|
try paramsContainer.encode(invoice, forKey: .invoice)
|
||||||
|
try paramsContainer.encodeIfPresent(description, forKey: .description)
|
||||||
|
try paramsContainer.encodeIfPresent(metadata, forKey: .metadata)
|
||||||
|
|
||||||
case .getBalance:
|
case .getBalance:
|
||||||
try container.encode(Method.getBalance.rawValue, forKey: .method)
|
try container.encode(Method.getBalance.rawValue, forKey: .method)
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ extension WalletConnect {
|
|||||||
/// - on_flush: A callback to call after the event has been flushed to the network
|
/// - on_flush: A callback to call after the event has been flushed to the network
|
||||||
/// - Returns: The Nostr Event that was sent to the network, representing the request that was made
|
/// - Returns: The Nostr Event that was sent to the network, representing the request that was made
|
||||||
@discardableResult
|
@discardableResult
|
||||||
static func pay(url: WalletConnectURL, pool: RelayPool, post: PostBox, invoice: String, delay: TimeInterval? = 5.0, on_flush: OnFlush? = nil) -> NostrEvent? {
|
static func pay(url: WalletConnectURL, pool: RelayPool, post: PostBox, invoice: String, zap_request: NostrEvent?, delay: TimeInterval? = 5.0, on_flush: OnFlush? = nil) -> NostrEvent? {
|
||||||
let req = WalletConnect.Request.payInvoice(invoice: invoice)
|
|
||||||
|
let req = WalletConnect.Request.payZapRequest(invoice: invoice, zapRequest: zap_request)
|
||||||
guard let ev = req.to_nostr_event(to_pk: url.pubkey, keypair: url.keypair) else {
|
guard let ev = req.to_nostr_event(to_pk: url.pubkey, keypair: url.keypair) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -142,7 +143,7 @@ extension WalletConnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print("damus-donation donating...")
|
print("damus-donation donating...")
|
||||||
WalletConnect.pay(url: nwc, pool: pool, post: postbox, invoice: invoice, delay: nil)
|
WalletConnect.pay(url: nwc, pool: pool, post: postbox, invoice: invoice, zap_request: nil, delay: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles a received Nostr Wallet Connect error
|
/// Handles a received Nostr Wallet Connect error
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ extension WalletConnect {
|
|||||||
let created_at: UInt64 // unixtimestamp, // invoice/payment creation time
|
let created_at: UInt64 // unixtimestamp, // invoice/payment creation time
|
||||||
let expires_at: UInt64? // unixtimestamp, // invoice expiration time, optional if not applicable
|
let expires_at: UInt64? // unixtimestamp, // invoice expiration time, optional if not applicable
|
||||||
let settled_at: UInt64? // unixtimestamp, // invoice/payment settlement time, optional if unpaid
|
let settled_at: UInt64? // unixtimestamp, // invoice/payment settlement time, optional if unpaid
|
||||||
//"metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
|
let metadata: WalletConnect.Request.Metadata? // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ struct TransactionView: View {
|
|||||||
let created_at = Date.init(timeIntervalSince1970: TimeInterval(transaction.created_at))
|
let created_at = Date.init(timeIntervalSince1970: TimeInterval(transaction.created_at))
|
||||||
let formatter = RelativeDateTimeFormatter()
|
let formatter = RelativeDateTimeFormatter()
|
||||||
let relativeDate = formatter.localizedString(for: created_at, relativeTo: Date.now)
|
let relativeDate = formatter.localizedString(for: created_at, relativeTo: Date.now)
|
||||||
let event = decode_nostr_event_json(transaction.description ?? "")
|
let event = decode_nostr_event_json(transaction.description ?? "") ?? transaction.metadata?.nostr
|
||||||
let pubkey = (event?.pubkey ?? ANON_PUBKEY)
|
let pubkey = self.pubkeyToDisplay(for: event, isIncomingTransaction: isIncomingTransaction) ?? ANON_PUBKEY
|
||||||
|
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
@@ -74,6 +74,16 @@ struct TransactionView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pubkeyToDisplay(for zapRequest: NostrEvent?, isIncomingTransaction: Bool) -> Pubkey? {
|
||||||
|
guard let zapRequest else { return nil }
|
||||||
|
if isIncomingTransaction {
|
||||||
|
return zapRequest.pubkey // We want to know who sent it to us
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return zapRequest.referenced_pubkeys.first // We want to know who we sent it to
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func userDisplayName(pubkey: Pubkey) -> String {
|
func userDisplayName(pubkey: Pubkey) -> String {
|
||||||
let profile_txn = damus_state.profiles.lookup(id: pubkey, txn_name: "txview-profile")
|
let profile_txn = damus_state.profiles.lookup(id: pubkey, txn_name: "txview-profile")
|
||||||
let profile = profile_txn?.unsafeUnownedValue
|
let profile = profile_txn?.unsafeUnownedValue
|
||||||
@@ -139,10 +149,10 @@ struct TransactionsView: View {
|
|||||||
|
|
||||||
struct TransactionsView_Previews: PreviewProvider {
|
struct TransactionsView_Previews: PreviewProvider {
|
||||||
static let tds = test_damus_state
|
static let tds = test_damus_state
|
||||||
static let transaction1: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "{\"id\":\"7c0999a5870ca3ba0186a29a8650152b555cee29b53b5b8747d8a3798042d01c\",\"pubkey\":\"b8851a06dfd79d48fc325234a15e9a46a32a0982a823b54cdf82514b9b120ba1\",\"created_at\":1736383715,\"kind\":9734,\"tags\":[[\"p\",\"520830c334a3f79f88cac934580d26f91a7832c6b21fb9625690ea2ed81b5626\"],[\"amount\",\"21000\"],[\"e\",\"a25e152a4cd1b3bbc3d22e8e9315d8ea1f35c227b2f212c7cff18abff36fa208\"],[\"relays\",\"wss://nos.lol\",\"wss://nostr.wine\",\"wss://premium.primal.net\",\"wss://relay.damus.io\",\"wss://relay.nostr.band\",\"wss://relay.nostrarabia.com\"]],\"content\":\"🫡 Onward!\",\"sig\":\"e77d16822fa21b9c2e6b580b51c470588052c14aeb222f08f0e735027e366157c8742a6d5cb850780c2bf44ac63d89b048e5cc56dd47a1bfc740a3173e578f4e\"}", description_hash: "", preimage: "", payment_hash: "1234567890", amount: 21000, fees_paid: 0, created_at: 1737736866, expires_at: 0, settled_at: 0)
|
static let transaction1: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "{\"id\":\"7c0999a5870ca3ba0186a29a8650152b555cee29b53b5b8747d8a3798042d01c\",\"pubkey\":\"b8851a06dfd79d48fc325234a15e9a46a32a0982a823b54cdf82514b9b120ba1\",\"created_at\":1736383715,\"kind\":9734,\"tags\":[[\"p\",\"520830c334a3f79f88cac934580d26f91a7832c6b21fb9625690ea2ed81b5626\"],[\"amount\",\"21000\"],[\"e\",\"a25e152a4cd1b3bbc3d22e8e9315d8ea1f35c227b2f212c7cff18abff36fa208\"],[\"relays\",\"wss://nos.lol\",\"wss://nostr.wine\",\"wss://premium.primal.net\",\"wss://relay.damus.io\",\"wss://relay.nostr.band\",\"wss://relay.nostrarabia.com\"]],\"content\":\"🫡 Onward!\",\"sig\":\"e77d16822fa21b9c2e6b580b51c470588052c14aeb222f08f0e735027e366157c8742a6d5cb850780c2bf44ac63d89b048e5cc56dd47a1bfc740a3173e578f4e\"}", description_hash: "", preimage: "", payment_hash: "1234567890", amount: 21000, fees_paid: 0, created_at: 1737736866, expires_at: 0, settled_at: 0, metadata: nil)
|
||||||
static let transaction2: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "123456789033", amount: 100000000, fees_paid: 0, created_at: 1737690090, expires_at: 0, settled_at: 0)
|
static let transaction2: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "123456789033", amount: 100000000, fees_paid: 0, created_at: 1737690090, expires_at: 0, settled_at: 0, metadata: nil)
|
||||||
static let transaction3: WalletConnect.Transaction = WalletConnect.Transaction(type: "outgoing", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "123456789042", amount: 303000, fees_paid: 0, created_at: 1737590101, expires_at: 0, settled_at: 0)
|
static let transaction3: WalletConnect.Transaction = WalletConnect.Transaction(type: "outgoing", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "123456789042", amount: 303000, fees_paid: 0, created_at: 1737590101, expires_at: 0, settled_at: 0, metadata: nil)
|
||||||
static let transaction4: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "1234567890662", amount: 720000, fees_paid: 0, created_at: 1737090300, expires_at: 0, settled_at: 0)
|
static let transaction4: WalletConnect.Transaction = WalletConnect.Transaction(type: "incoming", invoice: "", description: "", description_hash: "", preimage: "", payment_hash: "1234567890662", amount: 720000, fees_paid: 0, created_at: 1737090300, expires_at: 0, settled_at: 0, metadata: nil)
|
||||||
static var test_transactions: [WalletConnect.Transaction] = [transaction1, transaction2, transaction3, transaction4]
|
static var test_transactions: [WalletConnect.Transaction] = [transaction1, transaction2, transaction3, transaction4]
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ final class WalletConnectTests: XCTestCase {
|
|||||||
let pool = RelayPool(ndb: .empty)
|
let pool = RelayPool(ndb: .empty)
|
||||||
let box = PostBox(pool: pool)
|
let box = PostBox(pool: pool)
|
||||||
|
|
||||||
WalletConnect.pay(url: nwc, pool: pool, post: box, invoice: "invoice")
|
WalletConnect.pay(url: nwc, pool: pool, post: box, invoice: "invoice", zap_request: nil)
|
||||||
|
|
||||||
XCTAssertEqual(pool.our_descriptors.count, 0)
|
XCTAssertEqual(pool.our_descriptors.count, 0)
|
||||||
XCTAssertEqual(pool.all_descriptors.count, 1)
|
XCTAssertEqual(pool.all_descriptors.count, 1)
|
||||||
@@ -99,4 +99,109 @@ final class WalletConnectTests: XCTestCase {
|
|||||||
XCTAssertEqual(ev.remaining.count, 1)
|
XCTAssertEqual(ev.remaining.count, 1)
|
||||||
XCTAssertEqual(ev.remaining[0].relay.url.absoluteString, "ws://127.0.0.1")
|
XCTAssertEqual(ev.remaining[0].relay.url.absoluteString, "ws://127.0.0.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let testBolt11 = "lnbc15u1p3xnhl2pp5jptserfk3zk4qy42tlucycrfwxhydvlemu9pqr93tuzlv9cc7g3sdqsvfhkcap3xyhx7un8cqzpgxqzjcsp5f8c52y2stc300gl6s4xswtjpc37hrnnr3c9wvtgjfuvqmpm35evq9qyyssqy4lgd8tj637qcjp05rdpxxykjenthxftej7a2zzmwrmrl70fyj9hvj0rewhzj7jfyuwkwcg9g2jpwtk3wkjtwnkdks84hsnu8xps5vsq4gj5hs"
|
||||||
|
let testStringEncodedZapRequest = """
|
||||||
|
{"content":"","created_at":1746235486,"id":"faf5192c6805dea002e50cd52c7e553e3ee66ac42f30f41f1fe62b924f68fb22","kind":9734,"pubkey":"056b5b5966f500defb3b790a14633e5ec4a0e8883ca29bc23d0030553edb084a","sig":"21076018677656a220977c77e34bfa7427e1056a49b633afd3653d1d7466846cf6b35cf3fbf5908c712ebd647119cfadb1fa47e83121a238d77b1996f0fa26ee","tags":[["p","e8361082333142fc7f483b7dbd9bb36d671f2fbcf0a28015b2304fed79365fe8"],["relays","wss://nos.lol","wss://notify.damus.io","wss://relay.damus.io"]]}
|
||||||
|
"""
|
||||||
|
let testDoubleStringEncodedZapRequest = """
|
||||||
|
"{\\\"content\\\":\\\"\\\",\\\"created_at\\\":1746235486,\\\"id\\\":\\\"faf5192c6805dea002e50cd52c7e553e3ee66ac42f30f41f1fe62b924f68fb22\\\",\\\"kind\\\":9734,\\\"pubkey\\\":\\\"056b5b5966f500defb3b790a14633e5ec4a0e8883ca29bc23d0030553edb084a\\\",\\\"sig\\\":\\\"21076018677656a220977c77e34bfa7427e1056a49b633afd3653d1d7466846cf6b35cf3fbf5908c712ebd647119cfadb1fa47e83121a238d77b1996f0fa26ee\\\",\\\"tags\\\":[[\\\"p\\\",\\\"e8361082333142fc7f483b7dbd9bb36d671f2fbcf0a28015b2304fed79365fe8\\\"],[\\\"relays\\\",\\\"wss://nos.lol\\\",\\\"wss://notify.damus.io\\\",\\\"wss://relay.damus.io\\\"]]}"
|
||||||
|
"""
|
||||||
|
|
||||||
|
func testEncodingPayInvoiceRequest() throws {
|
||||||
|
let testZapRequest = decode_nostr_event_json(json: testStringEncodedZapRequest)!
|
||||||
|
let metadata = WalletConnect.Request.Metadata(nostr: testZapRequest)
|
||||||
|
let request = WalletConnect.Request.payInvoice(invoice: "lntest", description: testStringEncodedZapRequest, metadata: metadata)
|
||||||
|
|
||||||
|
let encodedData = try JSONEncoder().encode(request)
|
||||||
|
let encodedString = String(data: encodedData, encoding: .utf8)!
|
||||||
|
|
||||||
|
XCTAssertTrue(encodedString.contains("\"method\":\"pay_invoice\""))
|
||||||
|
XCTAssertTrue(encodedString.contains("\"invoice\":\"lntest\""))
|
||||||
|
XCTAssertTrue(encodedString.contains("\"description\":\"{"))
|
||||||
|
XCTAssertTrue(encodedString.contains("\"nostr\":{"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodingPayInvoiceRequest() throws {
|
||||||
|
let testZapRequest = decode_nostr_event_json(json: testStringEncodedZapRequest)!
|
||||||
|
|
||||||
|
let jsonText = """
|
||||||
|
{
|
||||||
|
"method": "pay_invoice",
|
||||||
|
"params": {
|
||||||
|
"invoice": "\(testBolt11)",
|
||||||
|
"description": \(testDoubleStringEncodedZapRequest),
|
||||||
|
"metadata": {
|
||||||
|
"nostr": \(testStringEncodedZapRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let jsonData = jsonText.data(using: .utf8)!
|
||||||
|
|
||||||
|
let decodedRequest = try JSONDecoder().decode(WalletConnect.Request.self, from: jsonData)
|
||||||
|
|
||||||
|
switch decodedRequest {
|
||||||
|
case .payInvoice(let invoice, let description, let metadata):
|
||||||
|
XCTAssertEqual(invoice, testBolt11)
|
||||||
|
XCTAssertEqual(description, testStringEncodedZapRequest)
|
||||||
|
XCTAssertNotNil(metadata)
|
||||||
|
XCTAssertEqual(metadata!.nostr, testZapRequest)
|
||||||
|
default:
|
||||||
|
XCTFail("Decoded to the wrong case")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodingPayInvoiceRequestWithoutMetadata() throws {
|
||||||
|
let jsonData = """
|
||||||
|
{
|
||||||
|
"method": "pay_invoice",
|
||||||
|
"params": {
|
||||||
|
"invoice": "\(testBolt11)",
|
||||||
|
"description": \(testDoubleStringEncodedZapRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".data(using: .utf8)!
|
||||||
|
|
||||||
|
let decodedRequest = try JSONDecoder().decode(WalletConnect.Request.self, from: jsonData)
|
||||||
|
|
||||||
|
switch decodedRequest {
|
||||||
|
case .payInvoice(let invoice, let description, let metadata):
|
||||||
|
XCTAssertEqual(invoice, testBolt11)
|
||||||
|
XCTAssertEqual(description, testStringEncodedZapRequest)
|
||||||
|
XCTAssertNil(metadata)
|
||||||
|
default:
|
||||||
|
XCTFail("Decoded to the wrong case")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodingPayInvoiceRequestWithCrazyMetadata() throws {
|
||||||
|
let jsonText = """
|
||||||
|
{
|
||||||
|
"method": "pay_invoice",
|
||||||
|
"params": {
|
||||||
|
"invoice": "\(testBolt11)",
|
||||||
|
"description": \(testDoubleStringEncodedZapRequest),
|
||||||
|
"metadata": {
|
||||||
|
"nostr": "totally not a zap request because this metadata is crazy",
|
||||||
|
"lorem": "ipsum"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let jsonData = jsonText.data(using: .utf8)!
|
||||||
|
|
||||||
|
let decodedRequest = try JSONDecoder().decode(WalletConnect.Request.self, from: jsonData)
|
||||||
|
|
||||||
|
switch decodedRequest {
|
||||||
|
case .payInvoice(let invoice, let description, let metadata):
|
||||||
|
XCTAssertEqual(invoice, testBolt11)
|
||||||
|
XCTAssertEqual(description, testStringEncodedZapRequest)
|
||||||
|
XCTAssertEqual(metadata?.nostr, nil)
|
||||||
|
default:
|
||||||
|
XCTFail("Decoded to the wrong case")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user