fiber_json_types/payment.rs
1//! Payment types for the Fiber Network JSON-RPC API.
2
3use crate::schema_helpers::*;
4use crate::serde_utils::{EntityHex, Hash256, Pubkey, SliceHex, U128Hex, U32Hex, U64Hex};
5use ckb_jsonrpc_types::Script;
6use ckb_types::packed::OutPoint;
7use schemars::{json_schema, JsonSchema, Schema, SchemaGenerator};
8use serde::{Deserialize, Serialize};
9use serde_with::serde_as;
10use std::collections::HashMap;
11
12/// The status of a payment, will update as the payment progresses.
13/// The transfer path for payment status is `Created -> Inflight -> Success | Failed`.
14///
15/// **MPP Behavior**: A single session may involve multiple attempts (HTLCs) to fulfill the total amount.
16#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
17pub enum PaymentStatus {
18 /// Initial status. A payment session is created, but no HTLC has been dispatched.
19 Created,
20 /// The first hop AddTlc is sent successfully and waiting for the response.
21 Inflight,
22 /// The payment is finished. All related HTLCs are successfully settled.
23 Success,
24 /// The payment session has terminated.
25 Failed,
26}
27
28/// Parameters for getting a payment.
29#[serde_as]
30#[derive(Serialize, Deserialize, Debug, JsonSchema)]
31pub struct GetPaymentCommandParams {
32 /// The payment hash of the payment to retrieve
33 pub payment_hash: Hash256,
34}
35
36/// The node and channel information in a payment route hop.
37#[serde_as]
38#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
39pub struct SessionRouteNode {
40 /// The public key of the node
41 pub pubkey: Pubkey,
42 /// The amount for this hop
43 #[serde_as(as = "U128Hex")]
44 #[schemars(schema_with = "schema_as_uint_hex")]
45 pub amount: u128,
46 /// The channel outpoint for this hop
47 #[serde_as(as = "EntityHex")]
48 #[schemars(schema_with = "schema_as_hex_bytes")]
49 pub channel_outpoint: OutPoint,
50}
51
52/// The router is a list of nodes that the payment will go through.
53#[derive(Clone, Debug, Serialize, Deserialize, Default, JsonSchema)]
54pub struct SessionRoute {
55 /// The nodes in the route
56 pub nodes: Vec<SessionRouteNode>,
57}
58
59/// The result of a get_payment command, which includes the payment hash, status, timestamps,
60/// error message if failed, fee paid, and custom records.
61#[serde_as]
62#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
63pub struct GetPaymentCommandResult {
64 /// The payment hash of the payment
65 pub payment_hash: Hash256,
66 /// The preimage learned from a successful payment attempt.
67 pub payment_preimage: Option<Hash256>,
68 /// The status of the payment
69 pub status: PaymentStatus,
70 #[serde_as(as = "U64Hex")]
71 #[schemars(schema_with = "schema_as_uint_hex")]
72 /// The time the payment was created at, in milliseconds from UNIX epoch
73 pub created_at: u64,
74 #[serde_as(as = "U64Hex")]
75 #[schemars(schema_with = "schema_as_uint_hex")]
76 /// The time the payment was last updated at, in milliseconds from UNIX epoch
77 pub last_updated_at: u64,
78 /// The error message if the payment failed
79 pub failed_error: Option<String>,
80 /// fee paid for the payment
81 #[serde_as(as = "U128Hex")]
82 #[schemars(schema_with = "schema_as_uint_hex")]
83 pub fee: u128,
84
85 /// The custom records to be included in the payment.
86 pub custom_records: Option<PaymentCustomRecords>,
87
88 #[cfg(debug_assertions)]
89 /// The router is a list of nodes that the payment will go through.
90 /// We store in the payment session and then will use it to track the payment history.
91 /// If the payment adapted MPP (multi-part payment), the routers will be a list of nodes.
92 /// For example:
93 /// `A(amount, channel) -> B -> C -> D`
94 /// means A will send `amount` with `channel` to B.
95 pub routers: Vec<SessionRoute>,
96}
97
98/// Parameters for listing payments.
99#[serde_as]
100#[derive(Serialize, Deserialize, Debug, Default, JsonSchema)]
101pub struct ListPaymentsParams {
102 /// Filter payments by status. If not set, all payments are returned.
103 pub status: Option<PaymentStatus>,
104 /// The maximum number of payments to return. Default is 15.
105 #[serde_as(as = "Option<U64Hex>")]
106 #[schemars(schema_with = "schema_as_uint_hex_optional")]
107 pub limit: Option<u64>,
108 /// The payment hash to start returning payments after (exclusive cursor for pagination).
109 pub after: Option<Hash256>,
110}
111
112/// Result of listing payments.
113#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
114pub struct ListPaymentsResult {
115 /// The list of payments.
116 pub payments: Vec<GetPaymentCommandResult>,
117 /// The last cursor for pagination. Use this as `after` in the next request to get more results.
118 pub last_cursor: Option<Hash256>,
119}
120
121/// The custom records to be included in the payment.
122/// The key is hex encoded of `u32`, it's range limited in 0 ~ 65535, and the value is hex encoded of `Vec<u8>` with `0x` as prefix.
123/// For example:
124/// ```json
125/// "custom_records": {
126/// "0x1": "0x01020304",
127/// "0x2": "0x05060708",
128/// "0x3": "0x090a0b0c",
129/// "0x4": "0x0d0e0f10010d090a0b0c"
130/// }
131/// ```
132#[serde_as]
133#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default)]
134pub struct PaymentCustomRecords {
135 /// The custom records to be included in the payment.
136 #[serde(flatten)]
137 #[serde_as(as = "HashMap<U32Hex, SliceHex>")]
138 pub data: HashMap<u32, Vec<u8>>,
139}
140
141impl JsonSchema for PaymentCustomRecords {
142 fn schema_name() -> std::borrow::Cow<'static, str> {
143 "PaymentCustomRecords".into()
144 }
145
146 fn json_schema(_generator: &mut SchemaGenerator) -> Schema {
147 json_schema!({
148 "type": "object",
149 "description": "Custom records map. Keys are hex-encoded u32 (0~65535), \
150 values are hex-encoded bytes. Both prefixed with 0x.",
151 "propertyNames": {
152 "type": "string",
153 "pattern": "^0x(0|[1-9a-fA-F][0-9a-fA-F]{0,3})$"
154 },
155 "additionalProperties": {
156 "type": "string",
157 "pattern": "^0x([0-9a-fA-F]{2})*$"
158 }
159 })
160 }
161}
162
163/// Parameters for sending a payment.
164#[serde_as]
165#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
166pub struct SendPaymentCommandParams {
167 /// The public key (`Pubkey`) of the payment target node, serialized as a hex string.
168 /// You can obtain a node's pubkey via the `node_info` or `graph_nodes` RPC.
169 pub target_pubkey: Option<Pubkey>,
170
171 /// the amount of the payment, the unit is Shannons for non UDT payment
172 /// If not set and there is a invoice, the amount will be set to the invoice amount
173 #[serde_as(as = "Option<U128Hex>")]
174 #[schemars(schema_with = "schema_as_uint_hex_optional")]
175 pub amount: Option<u128>,
176
177 /// the hash to use within the payment's HTLC.
178 /// If not set and `keysend` is set to true, a random hash will be generated.
179 /// If not set and there is a `payment_hash` in the invoice, it will be used.
180 /// Otherwise, `payment_hash` need to be set.
181 pub payment_hash: Option<Hash256>,
182
183 /// the TLC expiry delta should be used to set the timelock for the final hop, in milliseconds
184 #[serde_as(as = "Option<U64Hex>")]
185 #[schemars(schema_with = "schema_as_uint_hex_optional")]
186 pub final_tlc_expiry_delta: Option<u64>,
187
188 /// the TLC expiry limit for the whole payment, in milliseconds, each hop is with a default tlc delta of 1 day
189 /// suppose the payment router is with N hops, the total tlc expiry limit is at least (N-1) days
190 /// this is also the default value for the payment if this parameter is not provided
191 #[serde_as(as = "Option<U64Hex>")]
192 #[schemars(schema_with = "schema_as_uint_hex_optional")]
193 pub tlc_expiry_limit: Option<u64>,
194
195 /// the encoded invoice to send to the recipient
196 pub invoice: Option<String>,
197
198 /// the payment timeout in seconds, if the payment is not completed within this time, it will be cancelled
199 #[serde_as(as = "Option<U64Hex>")]
200 #[schemars(schema_with = "schema_as_uint_hex_optional")]
201 pub timeout: Option<u64>,
202
203 /// the maximum fee amounts in shannons that the sender is willing to pay.
204 /// Note: In trampoline routing mode, the sender will use the max_fee_amount as the total fee as much as possible.
205 #[serde_as(as = "Option<U128Hex>")]
206 #[schemars(schema_with = "schema_as_uint_hex_optional")]
207 pub max_fee_amount: Option<u128>,
208
209 /// the maximum fee rate per thousand, default is 5 (0.5%)
210 #[serde_as(as = "Option<U64Hex>")]
211 #[schemars(schema_with = "schema_as_uint_hex_optional")]
212 pub max_fee_rate: Option<u64>,
213
214 /// max parts for the payment, only used for multi-part payments
215 #[serde_as(as = "Option<U64Hex>")]
216 #[schemars(schema_with = "schema_as_uint_hex_optional")]
217 pub max_parts: Option<u64>,
218
219 /// Optional explicit trampoline hops.
220 ///
221 /// When set to a non-empty list `[t1, t2, ...]`, routing will only find a path from the
222 /// payer to `t1`, and the inner trampoline onion will encode `t1 -> t2 -> ... -> final`.
223 pub trampoline_hops: Option<Vec<Pubkey>>,
224
225 /// keysend payment
226 pub keysend: Option<bool>,
227
228 /// udt type script for the payment
229 pub udt_type_script: Option<Script>,
230
231 /// Allow paying yourself through a circular route, default is false.
232 /// This is useful for **channel rebalancing**: the payment flows out of one channel and
233 /// back through another, shifting liquidity between your channels without changing your
234 /// total balance (only routing fees are deducted).
235 /// Set `target_pubkey` to your own node pubkey and `keysend` to `true` to perform a rebalance.
236 /// Note: `allow_self_payment` is not compatible with trampoline routing.
237 pub allow_self_payment: Option<bool>,
238
239 /// Some custom records for the payment which contains a map of u32 to Vec<u8>
240 /// The key is the record type, and the value is the serialized data
241 /// For example:
242 /// ```json
243 /// "custom_records": {
244 /// "0x1": "0x01020304",
245 /// "0x2": "0x05060708",
246 /// "0x3": "0x090a0b0c",
247 /// "0x4": "0x0d0e0f10010d090a0b0c"
248 /// }
249 /// ```
250 pub custom_records: Option<PaymentCustomRecords>,
251
252 /// Optional route hints to reach the destination through private channels.
253 /// Note:
254 /// 1. this is only used for the private channels with the last hop.
255 /// 2. `hop_hints` is only a `hint` for routing algorithm,
256 /// it is not a guarantee that the payment will be routed through the specified channels,
257 /// it is up to the routing algorithm to decide whether to use the hints or not.
258 ///
259 /// For example `(pubkey, channel_outpoint, fee_rate, tlc_expiry_delta)` suggest path router
260 /// to use the channel of `channel_outpoint` at hop with `pubkey` to forward the payment
261 /// and the fee rate is `fee_rate` and tlc_expiry_delta is `tlc_expiry_delta`.
262 pub hop_hints: Option<Vec<HopHint>>,
263
264 /// dry_run for payment, used for check whether we can build valid router and the fee for this payment,
265 /// it's useful for the sender to double check the payment before sending it to the network,
266 /// default is false
267 pub dry_run: Option<bool>,
268}
269
270/// A hop hint is a hint for a node to use a specific channel.
271#[serde_as]
272#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
273pub struct HopHint {
274 /// The public key of the node
275 pub pubkey: Pubkey,
276 /// The outpoint of the channel
277 #[serde_as(as = "EntityHex")]
278 #[schemars(schema_with = "schema_as_hex_bytes")]
279 pub channel_outpoint: OutPoint,
280
281 /// The fee rate to use this hop to forward the payment.
282 #[serde_as(as = "U64Hex")]
283 #[schemars(schema_with = "schema_as_uint_hex")]
284 pub fee_rate: u64,
285 /// The TLC expiry delta to use this hop to forward the payment.
286 #[serde_as(as = "U64Hex")]
287 #[schemars(schema_with = "schema_as_uint_hex")]
288 pub tlc_expiry_delta: u64,
289}
290
291/// Parameters for building a payment router.
292#[serde_as]
293#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
294pub struct BuildRouterParams {
295 /// the amount of the payment, the unit is Shannons for non UDT payment
296 /// If not set, the minimum routable amount `1` is used
297 #[serde_as(as = "Option<U128Hex>")]
298 #[schemars(schema_with = "schema_as_uint_hex_optional")]
299 pub amount: Option<u128>,
300
301 /// udt type script for the payment router
302 pub udt_type_script: Option<Script>,
303
304 /// A list of hops that defines the route. This does not include the source hop pubkey.
305 /// A hop info is a tuple of pubkey and the channel(specified by channel funding tx) will be used.
306 /// This is a strong restriction given on payment router, which means these specified hops and channels
307 /// must be adapted in the router. This is different from hop hints, which maybe ignored by find path.
308 /// If channel is not specified, find path algorithm will pick a channel within these two peers.
309 ///
310 /// An error will be returned if there is no router could be build from given hops and channels
311 pub hops_info: Vec<HopRequire>,
312
313 /// the TLC expiry delta should be used to set the timelock for the final hop, in milliseconds
314 #[serde_as(as = "Option<U64Hex>")]
315 #[schemars(schema_with = "schema_as_uint_hex_optional")]
316 pub final_tlc_expiry_delta: Option<u64>,
317}
318
319/// A hop requirement to meet when building a router. Does not include the source node;
320/// the last hop is the target node.
321#[serde_as]
322#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
323pub struct HopRequire {
324 /// The public key of the node
325 pub pubkey: Pubkey,
326 /// The outpoint for the channel, which means use channel with `channel_outpoint` to reach this node
327 #[serde_as(as = "Option<EntityHex>")]
328 #[schemars(schema_with = "schema_as_hex_bytes_optional")]
329 pub channel_outpoint: Option<OutPoint>,
330}
331
332/// A router hop information for a payment, a paymenter router is an array of RouterHop,
333/// a router hop generally implies hop `target` will receive `amount_received` with `channel_outpoint` of channel.
334#[serde_as]
335#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
336pub struct RouterHop {
337 /// The node that is sending the TLC to the next node.
338 pub target: Pubkey,
339 /// The channel of this hop used to receive TLC
340 #[serde_as(as = "EntityHex")]
341 #[schemars(schema_with = "schema_as_hex_bytes")]
342 pub channel_outpoint: OutPoint,
343 /// The amount that the source node will transfer to the target node.
344 #[serde_as(as = "U128Hex")]
345 #[schemars(schema_with = "schema_as_uint_hex")]
346 pub amount_received: u128,
347 /// The expiry for the TLC that the source node sends to the target node.
348 #[serde_as(as = "U64Hex")]
349 #[schemars(schema_with = "schema_as_uint_hex")]
350 pub incoming_tlc_expiry: u64,
351}
352
353/// The router returned by build_router.
354#[serde_as]
355#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
356pub struct BuildPaymentRouterResult {
357 /// The hops information for router
358 pub router_hops: Vec<RouterHop>,
359}
360
361/// Parameters for sending a payment with a specified router.
362#[serde_as]
363#[derive(Serialize, Deserialize, Debug, JsonSchema)]
364pub struct SendPaymentWithRouterParams {
365 /// the hash to use within the payment's HTLC.
366 /// If not set and `keysend` is set to true, a random hash will be generated.
367 /// If not set and there is a `payment_hash` in the invoice, it will be used.
368 /// Otherwise, `payment_hash` need to be set.
369 pub payment_hash: Option<Hash256>,
370
371 /// The router to use for the payment
372 pub router: Vec<RouterHop>,
373
374 /// the encoded invoice to send to the recipient
375 pub invoice: Option<String>,
376
377 /// Some custom records for the payment which contains a map of u32 to Vec<u8>
378 /// The key is the record type, and the value is the serialized data.
379 /// Limits: the sum size of values can not exceed 2048 bytes.
380 ///
381 /// For example:
382 /// ```json
383 /// "custom_records": {
384 /// "0x1": "0x01020304",
385 /// "0x2": "0x05060708",
386 /// "0x3": "0x090a0b0c",
387 /// "0x4": "0x0d0e0f10010d090a0b0c"
388 /// }
389 /// ```
390 pub custom_records: Option<PaymentCustomRecords>,
391
392 /// keysend payment
393 pub keysend: Option<bool>,
394
395 /// udt type script for the payment
396 pub udt_type_script: Option<Script>,
397
398 /// dry_run for payment, used for check whether we can build valid router and the fee for this payment,
399 /// it's useful for the sender to double check the payment before sending it to the network,
400 /// default is false
401 pub dry_run: Option<bool>,
402}