zap method
Future<ZapResponse>
zap({
- required NwcConnection nwcConnection,
- required String lnurl,
- required int amountSats,
- bool fetchZapReceipt = false,
- EventSigner? signer,
- Iterable<
String> ? relays, - String? pubKey,
- String? comment,
- String? eventId,
zap or pay some lnurl, for zap to be created it is necessary:
- that the lnurl has the allowsNostr: true
- non empty relays
- non empty pubKey
- non empty _signer
Implementation
Future<ZapResponse> zap({
required NwcConnection nwcConnection,
required String lnurl,
required int amountSats,
bool fetchZapReceipt = false,
EventSigner? signer,
Iterable<String>? relays,
String? pubKey,
String? comment,
String? eventId,
}) async {
String? lud16Link = Lnurl.getLud16LinkFromLud16(lnurl);
ZapRequest? zapRequest;
if (pubKey != null &&
signer != null &&
relays != null &&
relays.isNotEmpty) {
zapRequest = await createZapRequest(
amountSats: amountSats,
signer: signer,
pubKey: pubKey,
comment: comment,
relays: relays,
eventId: eventId);
}
final invoice = await fecthInvoice(
lud16Link: lud16Link!,
comment: comment,
amountSats: amountSats,
zapRequest: zapRequest,
);
if (invoice == null) {
return ZapResponse(error: "couldn't get invoice from $lnurl");
}
try {
final payResponse = await _nwc.payInvoice(nwcConnection,
invoice: invoice.invoice, timeout: Duration(seconds: 10));
if (payResponse.preimage.isNotEmpty && payResponse.errorCode == null) {
final zapResponse = ZapResponse(payInvoiceResponse: payResponse);
if (zapRequest != null &&
fetchZapReceipt &&
invoice.nostrPubkey != null &&
invoice.nostrPubkey!.isNotEmpty) {
// if it's a zap, try to find the zap receipt
zapResponse.receiptResponse = _requests.subscription(filters: [
eventId != null
? Filter(
kinds: [ZapReceipt.kKind],
eTags: [eventId],
pTags: [pubKey!])
: Filter(kinds: [ZapReceipt.kKind], pTags: [pubKey!])
]);
// TODO make timeout waiting for receipt parameterizable somehow
StreamSubscription<Nip01Event>? streamSubscription;
final timeout = Timer(Duration(seconds: 30), () {
_requests
.closeSubscription(zapResponse.zapReceiptResponse!.requestId);
if (streamSubscription != null) {
streamSubscription.cancel();
}
Logger.log
.w("timed out waiting for zap receipt for invoice $invoice");
});
streamSubscription =
zapResponse.zapReceiptResponse!.stream.listen((event) {
String? bolt11 = event.getFirstTag("bolt11");
String? preimage = event.getFirstTag("preimage");
if (bolt11 != null && bolt11 == invoice.invoice ||
preimage != null && preimage == payResponse.preimage) {
ZapReceipt receipt = ZapReceipt.fromEvent(event);
Logger.log.d("Zap Receipt: $receipt");
if (receipt.isValid(
nostrPubKey: invoice.nostrPubkey!, recipientLnurl: lnurl)) {
zapResponse.emitReceipt(receipt);
} else {
Logger.log.w("Zap Receipt invalid: $receipt");
}
timeout.cancel();
_requests
.closeSubscription(zapResponse.zapReceiptResponse!.requestId);
if (streamSubscription != null) {
streamSubscription.cancel();
}
}
});
} else {
zapResponse.emitReceipt(null);
}
return zapResponse;
}
return ZapResponse(error: payResponse.errorMessage);
} catch (e) {
return ZapResponse(error: e.toString());
}
}