Skip to content

Commit 794dae2

Browse files
authored
lnd (#5)
* lnd * udl * . * pay_invoice * rabbit
1 parent 6fa252d commit 794dae2

File tree

23 files changed

+1661
-46
lines changed

23 files changed

+1661
-46
lines changed

bindings/lni_nodejs/index.d.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ export interface Bolt11Resp {
1616
paymentHash: string
1717
serialized: string
1818
}
19+
export interface PhoenixPayInvoiceResp {
20+
amountSat: number
21+
routingFeeSat: number
22+
paymentId: string
23+
paymentHash: string
24+
preimage: string
25+
}
1926
export interface ClnConfig {
2027
url: string
2128
rune: string
@@ -24,6 +31,14 @@ export interface ClnNode {
2431
url: string
2532
rune: string
2633
}
34+
export interface LndConfig {
35+
url: string
36+
macaroon: string
37+
}
38+
export interface LndNode {
39+
url: string
40+
macaroon: string
41+
}
2742
export const enum InvoiceType {
2843
Bolt11 = 'Bolt11',
2944
Bolt12 = 'Bolt12'
@@ -142,7 +157,7 @@ export interface LightningBalanceResponse {
142157
export interface PayInvoiceResponse {
143158
paymentHash: string
144159
preimage: string
145-
fee: number
160+
feeMsats: number
146161
}
147162
export interface PayKeysendResponse {
148163
fee: number
@@ -167,6 +182,11 @@ export interface CreateInvoiceParams {
167182
description?: string
168183
descriptionHash?: string
169184
expiry?: number
185+
rPreimage?: string
186+
isBlinded?: boolean
187+
isKeysend?: boolean
188+
isAmp?: boolean
189+
isPrivate?: boolean
170190
}
171191
export interface PayCode {
172192
offerId: string
@@ -176,6 +196,18 @@ export interface PayCode {
176196
singleUse?: boolean
177197
used?: boolean
178198
}
199+
export interface PayInvoiceParams {
200+
invoice: string
201+
feeLimitMsat?: number
202+
feeLimitPercentage?: number
203+
timeoutSeconds?: number
204+
amountMsats?: number
205+
maxParts?: number
206+
firstHopPubkey?: string
207+
lastHopPubkey?: string
208+
allowSelfPayment?: boolean
209+
isAmp?: boolean
210+
}
179211
export interface Payment {
180212
paymentId: string
181213
circId: string
@@ -191,6 +223,7 @@ export declare class PhoenixdNode {
191223
getConfig(): PhoenixdConfig
192224
getInfo(): Promise<NodeInfo>
193225
createInvoice(params: CreateInvoiceParams): Promise<Transaction>
226+
payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResponse>
194227
getOffer(): Promise<PayCode>
195228
lookupInvoice(paymentHash: string): Promise<Transaction>
196229
payOffer(offer: string, amountMsats: number, payerNote?: string | undefined | null): Promise<PayInvoiceResponse>
@@ -203,6 +236,22 @@ export declare class ClnNode {
203236
getConfig(): ClnConfig
204237
getInfo(): Promise<NodeInfo>
205238
createInvoice(params: CreateInvoiceParams): Promise<Transaction>
239+
payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResponse>
240+
getOffer(search?: string | undefined | null): Promise<PayCode>
241+
listOffers(search?: string | undefined | null): Promise<Array<PayCode>>
242+
payOffer(offer: string, amountMsats: number, payerNote?: string | undefined | null): Promise<PayInvoiceResponse>
243+
lookupInvoice(paymentHash: string): Promise<Transaction>
244+
listTransactions(params: ListTransactionsParams): Promise<Array<Transaction>>
245+
decode(str: string): Promise<string>
246+
}
247+
export declare class LndNode {
248+
constructor(config: LndConfig)
249+
getUrl(): string
250+
getMacaroon(): string
251+
getConfig(): LndConfig
252+
getInfo(): Promise<NodeInfo>
253+
createInvoice(params: CreateInvoiceParams): Promise<Transaction>
254+
payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResponse>
206255
getOffer(search?: string | undefined | null): Promise<PayCode>
207256
listOffers(search?: string | undefined | null): Promise<Array<PayCode>>
208257
payOffer(offer: string, amountMsats: number, payerNote?: string | undefined | null): Promise<PayInvoiceResponse>

bindings/lni_nodejs/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ if (!nativeBinding) {
310310
throw new Error(`Failed to load native binding`)
311311
}
312312

313-
const { InvoiceType, PhoenixdNode, ClnNode } = nativeBinding
313+
const { InvoiceType, PhoenixdNode, ClnNode, LndNode } = nativeBinding
314314

315315
module.exports.InvoiceType = InvoiceType
316316
module.exports.PhoenixdNode = PhoenixdNode
317317
module.exports.ClnNode = ClnNode
318+
module.exports.LndNode = LndNode

bindings/lni_nodejs/main.mjs

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PhoenixdNode, ClnNode, InvoiceType } from "./index.js";
1+
import { PhoenixdNode, ClnNode, LndNode, InvoiceType } from "./index.js";
22
import dotenv from "dotenv";
33
dotenv.config();
44

@@ -42,6 +42,11 @@ async function phoenixd() {
4242

4343
const offer = await node.getOffer();
4444
console.log("Get Offer:", offer);
45+
46+
// const pay_invoice_resp = await node.payInvoice({
47+
// invoice: ""
48+
// })
49+
// console.log("pay_invoice_resp:", pay_invoice_resp);
4550
}
4651

4752
async function cln() {
@@ -53,9 +58,6 @@ async function cln() {
5358
const info = await node.getInfo();
5459
console.log("Node info:", info);
5560

56-
// const configRes = await node.getConfig();
57-
// console.log("Config:", configRes.url);
58-
5961
const invoice = await node.createInvoice({
6062
amountMsats: 1000,
6163
description: "test invoice",
@@ -93,9 +95,56 @@ async function cln() {
9395
console.log("Transactions:", txns);
9496
}
9597

98+
async function lnd() {
99+
const config = {
100+
url: process.env.LND_URL,
101+
macaroon: process.env.LND_MACAROON,
102+
};
103+
const node = new LndNode(config);
104+
const info = await node.getInfo();
105+
console.log("Node info:", info);
106+
107+
const invoice = await node.createInvoice({
108+
amountMsats: 1000,
109+
description: "test invoice",
110+
invoiceType: InvoiceType.Bolt11,
111+
});
112+
console.log("LND Invoice:", invoice);
113+
114+
const bolt11Invoice = await node.createInvoice({
115+
amountMsats: 3000,
116+
description: "test invoice",
117+
invoiceType: InvoiceType.Bolt11,
118+
});
119+
console.log("LND bolt11 Invoice:", bolt11Invoice);
120+
121+
122+
const lookupInvoice = await node.lookupInvoice(
123+
process.env.LND_TEST_PAYMENT_HASH
124+
);
125+
console.log("lookupInvoice:", lookupInvoice);
126+
127+
const txns = await node.listTransactions({
128+
from: 0,
129+
limit: 10,
130+
});
131+
console.log("LND Transactions:", txns);
132+
}
133+
134+
async function test() {
135+
const config = {
136+
url: process.env.PHOENIXD_URL,
137+
password: process.env.PHOENIXD_PASSWORD,
138+
test_hash: process.env.PHOENIXD_TEST_PAYMENT_HASH,
139+
};
140+
const node = new PhoenixdNode(config);
141+
}
142+
96143
async function main() {
97-
phoenixd();
98-
cln();
144+
// phoenixd();
145+
// cln();
146+
// lnd();
147+
test();
99148
}
100149

101150
main();

bindings/lni_nodejs/src/cln.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use lni::{cln::lib::ClnConfig, CreateInvoiceParams};
1+
use lni::{cln::lib::ClnConfig, CreateInvoiceParams, PayInvoiceParams};
22
use napi::bindgen_prelude::*;
33
use napi_derive::napi;
44
#[napi]
@@ -58,6 +58,18 @@ impl ClnNode {
5858
Ok(txn)
5959
}
6060

61+
#[napi]
62+
pub async fn pay_invoice(
63+
&self,
64+
params: PayInvoiceParams,
65+
) -> Result<lni::types::PayInvoiceResponse> {
66+
let invoice =
67+
lni::cln::api::pay_invoice(self.inner.url.clone(), self.inner.rune.clone(), params)
68+
.await
69+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
70+
Ok(invoice)
71+
}
72+
6173
#[napi]
6274
pub async fn get_offer(&self, search: Option<String>) -> Result<lni::types::PayCode> {
6375
let offer = lni::cln::api::get_offer(self.inner.url.clone(), self.inner.rune.clone(), search)
@@ -104,12 +116,7 @@ impl ClnNode {
104116
None,
105117
)
106118
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
107-
Ok(
108-
txn
109-
.into_iter()
110-
.next()
111-
.ok_or_else(|| napi::Error::from_reason("No transaction found"))?,
112-
)
119+
Ok(txn)
113120
}
114121

115122
#[napi]

bindings/lni_nodejs/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ extern crate napi_derive;
44

55
pub use lni::ApiError;
66
pub use lni::types::*;
7+
pub use lni::utils::*;
78
pub use lni::types::{Transaction, InvoiceType, ListTransactionsParams, PayInvoiceResponse};
89

910
mod phoenixd;
1011
pub use phoenixd::PhoenixdNode;
1112

1213
mod cln;
1314
pub use cln::ClnNode;
15+
16+
mod lnd;
17+
pub use lnd::LndNode;

bindings/lni_nodejs/src/lnd.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use lni::{lnd::lib::LndConfig, CreateInvoiceParams, PayInvoiceParams};
2+
use napi::bindgen_prelude::*;
3+
use napi_derive::napi;
4+
#[napi]
5+
pub struct LndNode {
6+
inner: LndConfig,
7+
}
8+
9+
#[napi]
10+
impl LndNode {
11+
#[napi(constructor)]
12+
pub fn new(config: LndConfig) -> Self {
13+
Self { inner: config }
14+
}
15+
16+
#[napi]
17+
pub fn get_url(&self) -> String {
18+
self.inner.url.clone()
19+
}
20+
21+
#[napi]
22+
pub fn get_macaroon(&self) -> String {
23+
self.inner.macaroon.clone()
24+
}
25+
26+
#[napi]
27+
pub fn get_config(&self) -> LndConfig {
28+
LndConfig {
29+
url: self.inner.url.clone(),
30+
macaroon: self.inner.macaroon.clone(),
31+
}
32+
}
33+
34+
#[napi]
35+
pub async fn get_info(&self) -> napi::Result<lni::NodeInfo> {
36+
let info = lni::lnd::api::get_info(self.inner.url.clone(), self.inner.macaroon.clone())
37+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
38+
Ok(info)
39+
}
40+
41+
#[napi]
42+
pub async fn create_invoice(
43+
&self,
44+
params: CreateInvoiceParams,
45+
) -> napi::Result<lni::Transaction> {
46+
let txn =
47+
lni::lnd::api::create_invoice(self.inner.url.clone(), self.inner.macaroon.clone(), params)
48+
.await
49+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
50+
Ok(txn)
51+
}
52+
53+
#[napi]
54+
pub async fn pay_invoice(
55+
&self,
56+
params: PayInvoiceParams,
57+
) -> Result<lni::types::PayInvoiceResponse> {
58+
let invoice =
59+
lni::lnd::api::pay_invoice(self.inner.url.clone(), self.inner.macaroon.clone(), params)
60+
.await
61+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
62+
Ok(invoice)
63+
}
64+
65+
#[napi]
66+
pub async fn get_offer(&self, search: Option<String>) -> Result<lni::types::PayCode> {
67+
let offer =
68+
lni::lnd::api::get_offer(self.inner.url.clone(), self.inner.macaroon.clone(), search)
69+
.await
70+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
71+
Ok(offer)
72+
}
73+
74+
#[napi]
75+
pub async fn list_offers(&self, search: Option<String>) -> Result<Vec<lni::types::PayCode>> {
76+
let offers =
77+
lni::lnd::api::list_offers(self.inner.url.clone(), self.inner.macaroon.clone(), search)
78+
.await
79+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
80+
Ok(offers)
81+
}
82+
83+
#[napi]
84+
pub async fn pay_offer(
85+
&self,
86+
offer: String,
87+
amount_msats: i64,
88+
payer_note: Option<String>,
89+
) -> napi::Result<lni::PayInvoiceResponse> {
90+
let offer = lni::lnd::api::pay_offer(
91+
self.inner.url.clone(),
92+
self.inner.macaroon.clone(),
93+
offer,
94+
amount_msats,
95+
payer_note,
96+
)
97+
.await
98+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
99+
Ok(offer)
100+
}
101+
102+
#[napi]
103+
pub async fn lookup_invoice(&self, payment_hash: String) -> napi::Result<lni::Transaction> {
104+
let txn = lni::lnd::api::lookup_invoice(
105+
self.inner.url.clone(),
106+
self.inner.macaroon.clone(),
107+
Some(payment_hash),
108+
)
109+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
110+
Ok(txn)
111+
}
112+
113+
#[napi]
114+
pub async fn list_transactions(
115+
&self,
116+
params: lni::types::ListTransactionsParams,
117+
) -> napi::Result<Vec<lni::Transaction>> {
118+
let txns = lni::lnd::api::list_transactions(
119+
self.inner.url.clone(),
120+
self.inner.macaroon.clone(),
121+
params.from,
122+
params.limit,
123+
)
124+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
125+
Ok(txns)
126+
}
127+
128+
#[napi]
129+
pub async fn decode(&self, str: String) -> Result<String> {
130+
let decoded = lni::lnd::api::decode(self.inner.url.clone(), self.inner.macaroon.clone(), str)
131+
.await
132+
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
133+
Ok(decoded)
134+
}
135+
}

0 commit comments

Comments
 (0)