Skip to content

Commit 46586e4

Browse files
vincenzopalazzoswaptr
authored andcommitted
kraken: implement pay command proxy around core lightning pay command
Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent 5f64260 commit 46586e4

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ build/
1818
*.log
1919
*.info
2020
*.exe
21+
22+
kraken

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CC=dart
22
FMT=format
33
ARGS="--help"
44
PROBLEM=
5-
NAME=cln_plugin
5+
NAME=kraken
66

77
default: fmt build
88

lib/src/kraken.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,56 @@ class KrakenPlugin extends Plugin {
2525
.call(method: "listfunds", params: params.toListFundsRequest());
2626

2727
/// Make a call to listfunds like the prev one, and take only the channels
28-
return Future.value(
29-
{"listpays": listPays, "channels": listFunds["channels"]});
28+
/// The raw reason is the error message that core lightning return
29+
return Future.value({
30+
"listpays": listPays,
31+
"channels": listFunds["channels"],
32+
"raw_reason": request["raw_reason"] ?? "unknown"
33+
});
3034
} catch (ex, stacktrace) {
3135
plugin.log(level: "broken", message: "error received: ${ex.toString()}");
3236
stderr.write(stacktrace);
3337
rethrow;
3438
}
3539
}
3640

41+
Future<String> handleBolt12(Plugin plugin,
42+
{required FetchInvoiceRequest offer}) async {
43+
var fetchInvoice = await rpc!
44+
.call<FetchInvoiceRequest, FetchInvoiceResponse>(
45+
method: "fetchinvoice", params: offer);
46+
return fetchInvoice.invoice;
47+
}
48+
3749
/// This is the Kraken pay RPC method. This method allows for
3850
/// an alternate method to pay invoices in Core Lightning and
3951
/// return payment failure analysis reports.
52+
///
53+
/// For more info on what command we are wrapping, check the cln pay command
54+
// https://lightning.readthedocs.io/lightning-pay.7.html
4055
Future<Map<String, Object>> krakenPay(
4156
Plugin plugin, Map<String, Object> request) async {
4257
log(level: "info", message: "This is the kraken pay output.");
4358
try {
59+
String invoice = request["bolt11"]! as String;
60+
// The human-readable prefix for BOLT 12 offers is lno.
61+
if (invoice.startsWith("lno")) {
62+
// Modify request with the correct bolt 12!
63+
// FIXME: we should remove the msatoshi amount from the request? or the pay command
64+
// us smart enough to handle it?
65+
request["bolt11"] = await handleBolt12(plugin,
66+
offer: FetchInvoiceRequest(
67+
offer: invoice, msamsatoshi: request["msatoshi"] as String?));
68+
}
4469
// TODO: rpc should return an exception if any error occurs, and if we have the error returned run the doctor command
4570
HashMap<String, Object> result =
4671
await rpc!.call(method: "pay", params: PayRequest.fromJson(request));
4772
return Future.value(result);
4873
} catch (ex, stacktrace) {
4974
plugin.log(level: "broken", message: "error received: ${ex.toString()}");
5075
stderr.write(stacktrace);
76+
// TODO run the doctor command, and put the CLN exception message inside the doctor request
77+
// with identifier `raw_reason`
5178
rethrow;
5279
}
5380
}

lib/src/model/model.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,23 @@ class PayRequest extends Serializable {
5454
@override
5555
Map<String, dynamic> toJSON() => {};
5656
}
57+
58+
class FetchInvoiceRequest extends Serializable {
59+
String offer;
60+
String? msamsatoshi;
61+
62+
FetchInvoiceRequest({required this.offer, this.msamsatoshi});
63+
64+
@override
65+
Map<String, dynamic> toJSON() {
66+
return {
67+
"offer": offer,
68+
};
69+
}
70+
}
71+
72+
class FetchInvoiceResponse {
73+
String invoice;
74+
75+
FetchInvoiceResponse(this.invoice);
76+
}

0 commit comments

Comments
 (0)