Skip to content

Commit e041c50

Browse files
Lagrang3rustyrussell
authored andcommitted
xpay: add sendamount command
Changelog-Added: sendamount command, to make a payment specifying the desired amount to send instead of the amount to be received. Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
1 parent cec41bd commit e041c50

9 files changed

Lines changed: 607 additions & 28 deletions

File tree

‎cln-grpc/src/server.rs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4818,6 +4818,38 @@ impl Node for Server
48184818

48194819
}
48204820

4821+
async fn send_amount(
4822+
&self,
4823+
request: tonic::Request<pb::SendamountRequest>,
4824+
) -> Result<tonic::Response<pb::SendamountResponse>, tonic::Status> {
4825+
let req = request.into_inner();
4826+
let req: requests::SendamountRequest = req.into();
4827+
debug!("Client asked for send_amount");
4828+
trace!("send_amount request: {:?}", req);
4829+
let mut rpc = ClnRpc::new(&self.rpc_path)
4830+
.await
4831+
.map_err(|e| Status::new(Code::Internal, e.to_string()))?;
4832+
let result = rpc.call(Request::SendAmount(req))
4833+
.await
4834+
.map_err(|e| Status::new(
4835+
Code::Unknown,
4836+
format!("Error calling method SendAmount: {:?}", e)))?;
4837+
match result {
4838+
Response::SendAmount(r) => {
4839+
trace!("send_amount response: {:?}", r);
4840+
Ok(tonic::Response::new(r.into()))
4841+
},
4842+
r => Err(Status::new(
4843+
Code::Internal,
4844+
format!(
4845+
"Unexpected result {:?} to method call SendAmount",
4846+
r
4847+
)
4848+
)),
4849+
}
4850+
4851+
}
4852+
48214853

48224854

48234855
type SubscribeBalanceSnapshotStream = NotificationStream<pb::BalanceSnapshotNotification>;

‎contrib/msggen/msggen/schema.json‎

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32436,6 +32436,143 @@
3243632436
}
3243732437
]
3243832438
},
32439+
"sendamount.json": {
32440+
"$schema": "../rpc-schema-draft.json",
32441+
"type": "object",
32442+
"added": "v26.06",
32443+
"additionalProperties": false,
32444+
"rpc": "sendamount",
32445+
"title": "Command to send a fixed amount",
32446+
"description": [
32447+
"The **sendamount** RPC command attempts to send a fixed amount to the given destination. This means fees are deducted from that amount, hence the received value at the destination may vary depending on the chosen route."
32448+
],
32449+
"request": {
32450+
"required": [
32451+
"invstring",
32452+
"amount_msat"
32453+
],
32454+
"properties": {
32455+
"invstring": {
32456+
"type": "string",
32457+
"description": [
32458+
"A bolt12 (non-recursive) offer with no specific amount or a BIP353 name. It can also pay to a Bolt11 invoice as long as the amount is un-specified."
32459+
]
32460+
},
32461+
"amount_msat": {
32462+
"type": "msat",
32463+
"description": [
32464+
"The desired amount to be spent with this payment, ie. we will send this value while the destination will receive this minus fees. *amount_msat* is in millisatoshi precision; it can be a whole number, or a whole number with suffix *msat* or *sat*, or a three decimal point number with suffix *sat*, or an 1 to 11 decimal point number suffixed by *btc*."
32465+
]
32466+
},
32467+
"maxfee": {
32468+
"type": "msat",
32469+
"description": [
32470+
"*maxfee* creates an absolute limit on what fee will be paid."
32471+
],
32472+
"default": "For *amount_msat* smaller than 10sat it is 50%, for *amount_msat* between 10sat and 500sat *maxfee* is 5sat, while for *amount_msat* greater than 500sat it is 1%."
32473+
},
32474+
"layers": {
32475+
"type": "array",
32476+
"description": [
32477+
"These are askrene layers to apply in addition to 'xpay' layer: these can alter the topology or provide additional information on the lightning network. See askrene-create-layer."
32478+
],
32479+
"items": {
32480+
"type": "string",
32481+
"description": [
32482+
"name of an existing layer"
32483+
]
32484+
}
32485+
},
32486+
"retry_for": {
32487+
"type": "u32",
32488+
"description": [
32489+
"Until *retry_for* seconds passes, the command will keep finding routes and retrying the payment."
32490+
],
32491+
"default": "60 seconds"
32492+
},
32493+
"maxdelay": {
32494+
"type": "u32",
32495+
"description": [
32496+
"A payment may be delayed for up to `maxdelay` blocks by another node; clients should be prepared for this worst case."
32497+
],
32498+
"default": "2016"
32499+
},
32500+
"payer_note": {
32501+
"type": "string",
32502+
"description": [
32503+
"A message that a payer is willing to send to a payee within an invoice request."
32504+
]
32505+
},
32506+
"label": {
32507+
"type": "string",
32508+
"description": [
32509+
"Attach a label to payments for which is returned in `listpays` and `listsendpays`. This is for your own use: it is not visible to the recipient."
32510+
]
32511+
}
32512+
}
32513+
},
32514+
"response": {
32515+
"required": [
32516+
"payment_preimage",
32517+
"failed_parts",
32518+
"successful_parts",
32519+
"amount_msat",
32520+
"amount_sent_msat"
32521+
],
32522+
"properties": {
32523+
"payment_preimage": {
32524+
"type": "secret",
32525+
"description": [
32526+
"The proof of payment: SHA256 of this **payment_hash**."
32527+
]
32528+
},
32529+
"failed_parts": {
32530+
"type": "u64",
32531+
"description": [
32532+
"How many separate payment parts failed."
32533+
]
32534+
},
32535+
"successful_parts": {
32536+
"type": "u64",
32537+
"description": [
32538+
"How many separate payment parts succeeded (or are anticipated to succeed). This will be at least one."
32539+
]
32540+
},
32541+
"amount_msat": {
32542+
"type": "msat",
32543+
"description": [
32544+
"Amount the recipient received."
32545+
]
32546+
},
32547+
"amount_sent_msat": {
32548+
"type": "msat",
32549+
"description": [
32550+
"Total amount we sent (including fees)."
32551+
]
32552+
}
32553+
}
32554+
},
32555+
"errors": [
32556+
"The following error codes may occur:",
32557+
"",
32558+
"- -1: Catchall nonspecific error.",
32559+
"- 203: Permanent failure from destination (e.g. it said it didn't recognize invoice)",
32560+
"- 205: Couldn't find, or find a way to, the destination.",
32561+
"- 207: Invoice has expired.",
32562+
"- 219: Invoice has already been paid.",
32563+
"- 209: Other payment error."
32564+
],
32565+
"author": [
32566+
"Lagrang3 [lagrang3@protonmail.com](mailto:lagrang3@protonmail.com) is mainly responsible."
32567+
],
32568+
"see_also": [
32569+
"lightning-xpay(7)"
32570+
],
32571+
"resources": [
32572+
"Main web site: [https://github.com/ElementsProject/lightning](https://github.com/ElementsProject/lightning)"
32573+
],
32574+
"examples": []
32575+
},
3243932576
"sendcustommsg.json": {
3244032577
"$schema": "../rpc-schema-draft.json",
3244132578
"type": "object",

‎contrib/msggen/msggen/utils/utils.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
"ListCurrencyRates",
159159
"CurrencyConvert",
160160
"CurrencyRate",
161+
"SendAmount",
161162
]
162163

163164
grpc_notification_names = [

‎contrib/pyln-client/pyln/client/lightning.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,27 @@ def keysend(self, destination, amount_msat, label=None, maxfeepercent=None,
17041704
}
17051705
return self.call("keysend", payload)
17061706

1707+
def sendamount(
1708+
self,
1709+
invstring,
1710+
amount_msat,
1711+
maxfee=None,
1712+
layers=None,
1713+
retry_for=None,
1714+
maxdelay=None,
1715+
payer_note=None,
1716+
):
1717+
payload = {
1718+
"invstring": invstring,
1719+
"amount_msat": amount_msat,
1720+
"maxfee": maxfee,
1721+
"layers": layers,
1722+
"retry_for": retry_for,
1723+
"maxdelay": maxdelay,
1724+
"payer_note": payer_note,
1725+
}
1726+
return self.call("sendamount", payload)
1727+
17071728
def xkeysend(self, destination, amount_msat, maxfee=None,
17081729
layers=None, retry_for=None, maxdelay=None,
17091730
extratlvs=None):

‎doc/Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ MARKDOWNPAGES := doc/addgossip.7 \
128128
doc/renepay.7 \
129129
doc/renepaystatus.7 \
130130
doc/reserveinputs.7 \
131+
doc/sendamount.7 \
131132
doc/sendcustommsg.7 \
132133
doc/sendinvoice.7 \
133134
doc/sendonion.7 \

‎doc/index.rst‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ Core Lightning Documentation
183183
renepay <renepay.7.md>
184184
renepaystatus <renepaystatus.7.md>
185185
reserveinputs <reserveinputs.7.md>
186+
sendamount <sendamount.7.md>
186187
sendcustommsg <sendcustommsg.7.md>
187188
sendinvoice <sendinvoice.7.md>
188189
sendonion <sendonion.7.md>

‎doc/schemas/sendamount.json‎

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
{
2+
"$schema": "../rpc-schema-draft.json",
3+
"type": "object",
4+
"added": "v26.06",
5+
"additionalProperties": false,
6+
"rpc": "sendamount",
7+
"title": "Command to send a fixed amount",
8+
"description": [
9+
"The **sendamount** RPC command attempts to send a fixed amount to the given destination. This means fees are deducted from that amount, hence the received value at the destination may vary depending on the chosen route."
10+
],
11+
"request": {
12+
"required": [
13+
"invstring",
14+
"amount_msat"
15+
],
16+
"properties": {
17+
"invstring": {
18+
"type": "string",
19+
"description": [
20+
"A bolt12 (non-recursive) offer with no specific amount or a BIP353 name. It can also pay to a Bolt11 invoice as long as the amount is un-specified."
21+
]
22+
},
23+
"amount_msat": {
24+
"type": "msat",
25+
"description": [
26+
"The desired amount to be spent with this payment, ie. we will send this value while the destination will receive this minus fees. *amount_msat* is in millisatoshi precision; it can be a whole number, or a whole number with suffix *msat* or *sat*, or a three decimal point number with suffix *sat*, or an 1 to 11 decimal point number suffixed by *btc*."
27+
]
28+
},
29+
"maxfee": {
30+
"type": "msat",
31+
"description": [
32+
"*maxfee* creates an absolute limit on what fee will be paid."
33+
],
34+
"default": "For *amount_msat* smaller than 10sat it is 50%, for *amount_msat* between 10sat and 500sat *maxfee* is 5sat, while for *amount_msat* greater than 500sat it is 1%."
35+
},
36+
"layers": {
37+
"type": "array",
38+
"description": [
39+
"These are askrene layers to apply in addition to 'xpay' layer: these can alter the topology or provide additional information on the lightning network. See askrene-create-layer."
40+
],
41+
"items": {
42+
"type": "string",
43+
"description": [
44+
"name of an existing layer"
45+
]
46+
}
47+
},
48+
"retry_for": {
49+
"type": "u32",
50+
"description": [
51+
"Until *retry_for* seconds passes, the command will keep finding routes and retrying the payment."
52+
],
53+
"default": "60 seconds"
54+
},
55+
"maxdelay": {
56+
"type": "u32",
57+
"description": [
58+
"A payment may be delayed for up to `maxdelay` blocks by another node; clients should be prepared for this worst case."
59+
],
60+
"default": "2016"
61+
},
62+
"payer_note": {
63+
"type": "string",
64+
"description": [
65+
"A message that a payer is willing to send to a payee within an invoice request."
66+
]
67+
},
68+
"label": {
69+
"type": "string",
70+
"description": [
71+
"Attach a label to payments for which is returned in `listpays` and `listsendpays`. This is for your own use: it is not visible to the recipient."
72+
]
73+
}
74+
}
75+
},
76+
"response": {
77+
"required": [
78+
"payment_preimage",
79+
"failed_parts",
80+
"successful_parts",
81+
"amount_msat",
82+
"amount_sent_msat"
83+
],
84+
"properties": {
85+
"payment_preimage": {
86+
"type": "secret",
87+
"description": [
88+
"The proof of payment: SHA256 of this **payment_hash**."
89+
]
90+
},
91+
"failed_parts": {
92+
"type": "u64",
93+
"description": [
94+
"How many separate payment parts failed."
95+
]
96+
},
97+
"successful_parts": {
98+
"type": "u64",
99+
"description": [
100+
"How many separate payment parts succeeded (or are anticipated to succeed). This will be at least one."
101+
]
102+
},
103+
"amount_msat": {
104+
"type": "msat",
105+
"description": [
106+
"Amount the recipient received."
107+
]
108+
},
109+
"amount_sent_msat": {
110+
"type": "msat",
111+
"description": [
112+
"Total amount we sent (including fees)."
113+
]
114+
}
115+
}
116+
},
117+
"errors": [
118+
"The following error codes may occur:",
119+
"",
120+
"- -1: Catchall nonspecific error.",
121+
"- 203: Permanent failure from destination (e.g. it said it didn't recognize invoice)",
122+
"- 205: Couldn't find, or find a way to, the destination.",
123+
"- 207: Invoice has expired.",
124+
"- 219: Invoice has already been paid.",
125+
"- 209: Other payment error."
126+
],
127+
"author": [
128+
"Lagrang3 [lagrang3@protonmail.com](mailto:lagrang3@protonmail.com) is mainly responsible."
129+
],
130+
"see_also": [
131+
"lightning-xpay(7)"
132+
],
133+
"resources": [
134+
"Main web site: [https://github.com/ElementsProject/lightning](https://github.com/ElementsProject/lightning)"
135+
],
136+
"examples": []
137+
}

0 commit comments

Comments
 (0)