nwc: fix bug where private nwc zaps weren't getting tracked properly
It was using the wrapper zap request id instead of the inner id. Fix this type error by creating a ZapRequestId wrapper that makes sure it uses the proper request id.
This commit is contained in:
@@ -174,7 +174,7 @@ struct ZapButton: View {
|
|||||||
|
|
||||||
struct ZapButton_Previews: PreviewProvider {
|
struct ZapButton_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let pending_zap = PendingZap(amount_msat: 1000, target: ZapTarget.note(id: "noteid", author: "author"), request: test_zap_request, type: .pub, state: .external(.init(state: .fetching_invoice)))
|
let pending_zap = PendingZap(amount_msat: 1000, target: ZapTarget.note(id: "noteid", author: "author"), request: .normal(test_zap_request), type: .pub, state: .external(.init(state: .fetching_invoice)))
|
||||||
let zaps = ZapsDataModel([.pending(pending_zap)])
|
let zaps = ZapsDataModel([.pending(pending_zap)])
|
||||||
|
|
||||||
ZapButton(damus_state: test_damus_state(), event: test_event, lnurl: "lnurl", zaps: zaps)
|
ZapButton(damus_state: test_damus_state(), event: test_event, lnurl: "lnurl", zaps: zaps)
|
||||||
@@ -203,7 +203,7 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
|||||||
let target = ZapTarget.note(id: event.id, author: event.pubkey)
|
let target = ZapTarget.note(id: event.id, author: event.pubkey)
|
||||||
let content = comment ?? ""
|
let content = comment ?? ""
|
||||||
|
|
||||||
guard let zapreq = make_zap_request_event(keypair: keypair, content: content, relays: relays, target: target, zap_type: zap_type) else {
|
guard let mzapreq = make_zap_request_event(keypair: keypair, content: content, relays: relays, target: target, zap_type: zap_type) else {
|
||||||
// this should never happen
|
// this should never happen
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,9 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
|||||||
let zap_amount = amount_sats ?? damus_state.settings.default_zap_amount
|
let zap_amount = amount_sats ?? damus_state.settings.default_zap_amount
|
||||||
let amount_msat = Int64(zap_amount) * 1000
|
let amount_msat = Int64(zap_amount) * 1000
|
||||||
let pending_zap_state = initial_pending_zap_state(settings: damus_state.settings)
|
let pending_zap_state = initial_pending_zap_state(settings: damus_state.settings)
|
||||||
let pending_zap = PendingZap(amount_msat: amount_msat, target: target, request: ZapRequest(ev: zapreq), type: zap_type, state: pending_zap_state)
|
let pending_zap = PendingZap(amount_msat: amount_msat, target: target, request: mzapreq, type: zap_type, state: pending_zap_state)
|
||||||
|
let zapreq = mzapreq.potentially_anon_outer_request.ev
|
||||||
|
let reqid = ZapRequestId(from_makezap: mzapreq)
|
||||||
|
|
||||||
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
|
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
|
||||||
damus_state.add_zap(zap: .pending(pending_zap))
|
damus_state.add_zap(zap: .pending(pending_zap))
|
||||||
@@ -225,7 +227,7 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
|||||||
guard let payreq = mpayreq else {
|
guard let payreq = mpayreq else {
|
||||||
// TODO: show error
|
// TODO: show error
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
remove_zap(reqid: zapreq.id, zapcache: damus_state.zaps, evcache: damus_state.events)
|
remove_zap(reqid: reqid, zapcache: damus_state.zaps, evcache: damus_state.events)
|
||||||
let typ = ZappingEventType.failed(.bad_lnurl)
|
let typ = ZappingEventType.failed(.bad_lnurl)
|
||||||
let ev = ZappingEvent(is_custom: is_custom, type: typ, event: event)
|
let ev = ZappingEvent(is_custom: is_custom, type: typ, event: event)
|
||||||
notify(.zapping, ev)
|
notify(.zapping, ev)
|
||||||
@@ -239,7 +241,7 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
|||||||
|
|
||||||
guard let inv = await fetch_zap_invoice(payreq, zapreq: zapreq, sats: zap_amount, zap_type: zap_type, comment: comment) else {
|
guard let inv = await fetch_zap_invoice(payreq, zapreq: zapreq, sats: zap_amount, zap_type: zap_type, comment: comment) else {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
remove_zap(reqid: zapreq.id, zapcache: damus_state.zaps, evcache: damus_state.events)
|
remove_zap(reqid: reqid, zapcache: damus_state.zaps, evcache: damus_state.events)
|
||||||
let typ = ZappingEventType.failed(.fetching_invoice)
|
let typ = ZappingEventType.failed(.fetching_invoice)
|
||||||
let ev = ZappingEvent(is_custom: is_custom, type: typ, event: event)
|
let ev = ZappingEvent(is_custom: is_custom, type: typ, event: event)
|
||||||
notify(.zapping, ev)
|
notify(.zapping, ev)
|
||||||
@@ -253,7 +255,7 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
|||||||
case .nwc(let nwc_state):
|
case .nwc(let nwc_state):
|
||||||
// don't both continuing, user has canceled
|
// don't both continuing, user has canceled
|
||||||
if case .cancel_fetching_invoice = nwc_state.state {
|
if case .cancel_fetching_invoice = nwc_state.state {
|
||||||
remove_zap(reqid: zapreq.id, zapcache: damus_state.zaps, evcache: damus_state.events)
|
remove_zap(reqid: reqid, zapcache: damus_state.zaps, evcache: damus_state.events)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,10 +310,12 @@ func cancel_zap(zap: PendingZap, box: PostBox, zapcache: Zaps, evcache: EventCac
|
|||||||
if let err = box.cancel_send(evid: nwc_req.id) {
|
if let err = box.cancel_send(evid: nwc_req.id) {
|
||||||
return .send_err(err)
|
return .send_err(err)
|
||||||
}
|
}
|
||||||
remove_zap(reqid: zap.request.ev.id, zapcache: zapcache, evcache: evcache)
|
let reqid = ZapRequestId(from_pending: zap)
|
||||||
|
remove_zap(reqid: reqid, zapcache: zapcache, evcache: evcache)
|
||||||
|
|
||||||
case .failed:
|
case .failed:
|
||||||
remove_zap(reqid: zap.request.ev.id, zapcache: zapcache, evcache: evcache)
|
let reqid = ZapRequestId(from_pending: zap)
|
||||||
|
remove_zap(reqid: reqid, zapcache: zapcache, evcache: evcache)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -512,7 +512,12 @@ func zap_target_to_tags(_ target: ZapTarget) -> [[String]] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> String? {
|
struct PrivateZapRequest {
|
||||||
|
let req: ZapRequest
|
||||||
|
let enc: String
|
||||||
|
}
|
||||||
|
|
||||||
|
func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> PrivateZapRequest? {
|
||||||
// target tags must be the same as zap request target tags
|
// target tags must be the same as zap request target tags
|
||||||
let tags = zap_target_to_tags(target)
|
let tags = zap_target_to_tags(target)
|
||||||
|
|
||||||
@@ -520,10 +525,13 @@ func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair,
|
|||||||
note.id = calculate_event_id(ev: note)
|
note.id = calculate_event_id(ev: note)
|
||||||
note.sig = sign_event(privkey: identity.privkey, ev: note)
|
note.sig = sign_event(privkey: identity.privkey, ev: note)
|
||||||
|
|
||||||
guard let note_json = encode_json(note) else {
|
guard let note_json = encode_json(note),
|
||||||
|
let enc = encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32)
|
||||||
|
else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32)
|
|
||||||
|
return PrivateZapRequest(req: ZapRequest(ev: note), enc: enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decrypt_private_zap(our_privkey: String, zapreq: NostrEvent, target: ZapTarget) -> NostrEvent? {
|
func decrypt_private_zap(our_privkey: String, zapreq: NostrEvent, target: ZapTarget) -> NostrEvent? {
|
||||||
@@ -587,7 +595,30 @@ func generate_private_keypair(our_privkey: String, id: String, created_at: Int64
|
|||||||
return FullKeypair(pubkey: pubkey, privkey: privkey)
|
return FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> NostrEvent? {
|
enum MakeZapRequest {
|
||||||
|
case priv(ZapRequest, PrivateZapRequest)
|
||||||
|
case normal(ZapRequest)
|
||||||
|
|
||||||
|
var private_inner_request: ZapRequest {
|
||||||
|
switch self {
|
||||||
|
case .priv(let _, let pzr):
|
||||||
|
return pzr.req
|
||||||
|
case .normal(let zr):
|
||||||
|
return zr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var potentially_anon_outer_request: ZapRequest {
|
||||||
|
switch self {
|
||||||
|
case .priv(let zr, _):
|
||||||
|
return zr
|
||||||
|
case .normal(let zr):
|
||||||
|
return zr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? {
|
||||||
var tags = zap_target_to_tags(target)
|
var tags = zap_target_to_tags(target)
|
||||||
var relay_tag = ["relays"]
|
var relay_tag = ["relays"]
|
||||||
relay_tag.append(contentsOf: relays.map { $0.url.id })
|
relay_tag.append(contentsOf: relays.map { $0.url.id })
|
||||||
@@ -597,6 +628,8 @@ func make_zap_request_event(keypair: FullKeypair, content: String, relays: [Rela
|
|||||||
|
|
||||||
let now = Int64(Date().timeIntervalSince1970)
|
let now = Int64(Date().timeIntervalSince1970)
|
||||||
|
|
||||||
|
var privzap_req: PrivateZapRequest?
|
||||||
|
|
||||||
var message = content
|
var message = content
|
||||||
switch zap_type {
|
switch zap_type {
|
||||||
case .pub:
|
case .pub:
|
||||||
@@ -614,14 +647,20 @@ func make_zap_request_event(keypair: FullKeypair, content: String, relays: [Rela
|
|||||||
guard let privreq = make_private_zap_request_event(identity: keypair, enc_key: kp, target: target, message: message) else {
|
guard let privreq = make_private_zap_request_event(identity: keypair, enc_key: kp, target: target, message: message) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
tags.append(["anon", privreq])
|
tags.append(["anon", privreq.enc])
|
||||||
message = ""
|
message = ""
|
||||||
|
privzap_req = privreq
|
||||||
}
|
}
|
||||||
|
|
||||||
let ev = NostrEvent(content: message, pubkey: kp.pubkey, kind: 9734, tags: tags, createdAt: now)
|
let ev = NostrEvent(content: message, pubkey: kp.pubkey, kind: 9734, tags: tags, createdAt: now)
|
||||||
ev.id = calculate_event_id(ev: ev)
|
ev.id = calculate_event_id(ev: ev)
|
||||||
ev.sig = sign_event(privkey: kp.privkey, ev: ev)
|
ev.sig = sign_event(privkey: kp.privkey, ev: ev)
|
||||||
return ev
|
let zapreq = ZapRequest(ev: ev)
|
||||||
|
if let privzap_req {
|
||||||
|
return .priv(zapreq, privzap_req)
|
||||||
|
} else {
|
||||||
|
return .normal(zapreq)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func uniq<T: Hashable>(_ xs: [T]) -> [T] {
|
func uniq<T: Hashable>(_ xs: [T]) -> [T] {
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ func nwc_error(zapcache: Zaps, evcache: EventCache, resp: FullWalletResponse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove the pending zap if there was an error
|
// remove the pending zap if there was an error
|
||||||
remove_zap(reqid: pzap.request.ev.id, zapcache: zapcache, evcache: evcache)
|
let reqid = ZapRequestId(from_pending: pzap)
|
||||||
|
remove_zap(reqid: reqid, zapcache: zapcache, evcache: evcache)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ class PendingZap {
|
|||||||
let type: ZapType
|
let type: ZapType
|
||||||
private(set) var state: PendingZapState
|
private(set) var state: PendingZapState
|
||||||
|
|
||||||
init(amount_msat: Int64, target: ZapTarget, request: ZapRequest, type: ZapType, state: PendingZapState) {
|
init(amount_msat: Int64, target: ZapTarget, request: MakeZapRequest, type: ZapType, state: PendingZapState) {
|
||||||
self.amount_msat = amount_msat
|
self.amount_msat = amount_msat
|
||||||
self.target = target
|
self.target = target
|
||||||
self.request = request
|
self.request = request.private_inner_request
|
||||||
self.type = type
|
self.type = type
|
||||||
self.state = state
|
self.state = state
|
||||||
}
|
}
|
||||||
@@ -125,6 +125,21 @@ class PendingZap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ZapRequestId: Equatable {
|
||||||
|
let reqid: String
|
||||||
|
|
||||||
|
init(from_zap: Zapping) {
|
||||||
|
self.reqid = from_zap.request.id
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from_makezap: MakeZapRequest) {
|
||||||
|
self.reqid = from_makezap.private_inner_request.ev.id
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from_pending: PendingZap) {
|
||||||
|
self.reqid = from_pending.request.ev.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum Zapping {
|
enum Zapping {
|
||||||
case zap(Zap)
|
case zap(Zap)
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ class Zaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove_zap(reqid: String, zapcache: Zaps, evcache: EventCache) {
|
func remove_zap(reqid: ZapRequestId, zapcache: Zaps, evcache: EventCache) {
|
||||||
guard let zap = zapcache.remove_zap(reqid: reqid) else {
|
guard let zap = zapcache.remove_zap(reqid: reqid.reqid) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
evcache.get_cache_data(zap.target.id).zaps_model.remove(reqid: reqid)
|
evcache.get_cache_data(zap.target.id).zaps_model.remove(reqid: reqid.reqid)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ let test_zap = Zap(event: test_event, invoice: test_zap_invoice, zapper: "zapper
|
|||||||
|
|
||||||
let test_private_zap = Zap(event: test_event, invoice: test_zap_invoice, zapper: "zapper", target: .profile("pk"), request: test_zap_request, is_anon: false, private_request: test_event)
|
let test_private_zap = Zap(event: test_event, invoice: test_zap_invoice, zapper: "zapper", target: .profile("pk"), request: test_zap_request, is_anon: false, private_request: test_event)
|
||||||
|
|
||||||
let test_pending_zap = PendingZap(amount_msat: 10000, target: .note(id: "id", author: "pk"), request: test_zap_request, type: .pub, state: .external(.init(state: .fetching_invoice)))
|
let test_pending_zap = PendingZap(amount_msat: 10000, target: .note(id: "id", author: "pk"), request: .normal(test_zap_request), type: .pub, state: .external(.init(state: .fetching_invoice)))
|
||||||
|
|
||||||
struct ZapEvent_Previews: PreviewProvider {
|
struct ZapEvent_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|||||||
Reference in New Issue
Block a user