Skip to content

Commit ca5e6b5

Browse files
committed
napi rs json db
1 parent 845496c commit ca5e6b5

File tree

7 files changed

+136
-27
lines changed

7 files changed

+136
-27
lines changed

bindings/lni_nodejs/index.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ export interface PaymentFailedEventProperties {
159159
transaction: Transaction
160160
reason: string
161161
}
162+
export interface Payment {
163+
paymentId: string
164+
circId: string
165+
round: number
166+
relayFingerprint: string
167+
updatedAt: number
168+
amountMsat: number
169+
}
162170
export declare class PhoenixdNode {
163171
constructor(config: PhoenixdConfig)
164172
getUrl(): string
@@ -169,3 +177,9 @@ export declare class PhoenixdNode {
169177
lookupInvoice(paymentHash: string): Promise<Transaction>
170178
listTransactions(params: ListTransactionsParams): Promise<Array<Transaction>>
171179
}
180+
export declare class Db {
181+
constructor(path: string)
182+
save(): void
183+
writePayment(payment: Payment): void
184+
lookupPayment(paymentId: string): Payment | null
185+
}

bindings/lni_nodejs/index.js

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

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

315315
module.exports.InvoiceType = InvoiceType
316316
module.exports.PhoenixdNode = PhoenixdNode
317+
module.exports.Db = Db

bindings/lni_nodejs/main.mjs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,45 @@
1-
import { PhoenixdNode, InvoiceType } from './index.js'
2-
import dotenv from 'dotenv';
1+
import { PhoenixdNode, InvoiceType, Db } from "./index.js";
2+
import dotenv from "dotenv";
33
dotenv.config();
44

5-
65
const config = {
7-
url: process.env.PHOENIXD_URL,
8-
password: process.env.PHOENIXD_PASSWORD,
9-
test_hash: process.env.PHOENIXD_TEST_PAYMENT_HASH,
10-
}
11-
const node = new PhoenixdNode(config)
12-
const info = await node.getInfo()
13-
console.log('Node info:', info)
6+
url: process.env.PHOENIXD_URL,
7+
password: process.env.PHOENIXD_PASSWORD,
8+
test_hash: process.env.PHOENIXD_TEST_PAYMENT_HASH,
9+
};
10+
const node = new PhoenixdNode(config);
11+
const info = await node.getInfo();
12+
console.log("Node info:", info);
1413

15-
const configRes = await node.getConfig()
16-
console.log('Config:', configRes.url)
14+
const configRes = await node.getConfig();
15+
console.log("Config:", configRes.url);
1716

18-
const invoice = await node.makeInvoice({ amount: 1000, description: 'test invoice', invoiceType: InvoiceType.Bolt11 })
19-
console.log('Invoice:', invoice)
17+
const invoice = await node.makeInvoice({
18+
amount: 1000,
19+
description: "test invoice",
20+
invoiceType: InvoiceType.Bolt11,
21+
});
22+
console.log("Invoice:", invoice);
2023

21-
const lookupInvoice = await node.lookupInvoice(config.test_hash)
22-
console.log('lookupInvoice:', lookupInvoice)
24+
const lookupInvoice = await node.lookupInvoice(config.test_hash);
25+
console.log("lookupInvoice:", lookupInvoice);
2326

2427
const txns = await node.listTransactions({
25-
from: 0,
26-
until: 0,
27-
limit: 10,
28-
offset: 0,
29-
unpaid: false,
30-
invoiceType: 'all',
31-
})
32-
console.log('Transactions:', txns)
28+
from: 0,
29+
until: 0,
30+
limit: 10,
31+
offset: 0,
32+
unpaid: false,
33+
invoiceType: "all",
34+
});
35+
console.log("Transactions:", txns);
36+
37+
const db = new Db("test.json");
38+
db.writePayment({
39+
paymentId: "1",
40+
circId: "1",
41+
round: 1,
42+
relayFingerprint: "1",
43+
updatedAt: 1,
44+
amountMsat: 1,
45+
});

bindings/lni_nodejs/src/database.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use lni::DbError;
2+
use serde::{Deserialize, Serialize};
3+
use std::fs::{File, OpenOptions};
4+
use std::io::{Read, Write};
5+
use std::sync::{Arc, Mutex};
6+
use napi::bindgen_prelude::*;
7+
use napi_derive::{napi};
8+
9+
10+
#[napi]
11+
#[derive(Debug, Deserialize)]
12+
pub struct Db {
13+
path: String,
14+
#[serde(skip)]
15+
data: Arc<Mutex<Vec<lni::Payment>>>,
16+
}
17+
18+
#[napi]
19+
impl Db {
20+
#[napi(constructor)]
21+
pub fn new(path: String) -> Result<Self> {
22+
let data = if let Ok(mut file) = File::open(&path) {
23+
let mut contents = String::new();
24+
file.read_to_string(&mut contents)
25+
.map_err(|e| napi::Error::from_reason(format!("IoErr: {}", e.to_string())))?;
26+
serde_json::from_str(&contents).map_err(|e| DbError::DeserializationErr {
27+
reason: e.to_string(),
28+
}).unwrap()
29+
} else {
30+
Vec::new()
31+
};
32+
33+
Ok(Self {
34+
path,
35+
data: Arc::new(Mutex::new(data)),
36+
})
37+
}
38+
39+
#[napi]
40+
pub fn save(&self) -> Result<()> {
41+
let data = self.data.lock().unwrap();
42+
let json = serde_json::to_string_pretty(&*data).map_err(|e| DbError::SerializationErr {
43+
reason: e.to_string(),
44+
}).unwrap();
45+
let mut file = OpenOptions::new()
46+
.write(true)
47+
.create(true)
48+
.truncate(true)
49+
.open(&self.path)
50+
.map_err(|e| DbError::IoErr {
51+
reason: e.to_string(),
52+
}).unwrap();
53+
file.write_all(json.as_bytes())
54+
.map_err(|e| DbError::IoErr {
55+
reason: e.to_string(),
56+
}).unwrap();
57+
Ok(())
58+
}
59+
60+
#[napi]
61+
pub fn write_payment(&self, payment: lni::Payment) -> Result<()> {
62+
let mut data = self.data.lock().unwrap();
63+
data.push(payment);
64+
drop(data); // Explicitly drop the lock before saving
65+
self.save()
66+
}
67+
68+
#[napi]
69+
pub fn lookup_payment(&self, payment_id: String) -> Result<Option<lni::Payment>> {
70+
let data = self.data.lock().unwrap();
71+
Ok(data
72+
.iter()
73+
.find(|payment| payment.payment_id == payment_id)
74+
.cloned())
75+
}
76+
}

bindings/lni_nodejs/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ extern crate napi_derive;
44

55
mod phoenixd;
66

7-
pub use lni::{ApiError, Result};
7+
pub use lni::ApiError;
88
pub use phoenixd::PhoenixdNode;
99
pub use lni::types::*;
1010

11+
mod database;
12+
pub use database::Db;

crates/lni/database.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::fs::{File, OpenOptions};
33
use std::io::{Read, Write};
44
use std::sync::{Arc, Mutex};
55
use thiserror::Error;
6+
#[cfg(feature = "napi_rs")]
7+
use napi_derive::napi;
68

79
#[derive(Debug, Error)]
810
pub enum DbError {
@@ -14,6 +16,7 @@ pub enum DbError {
1416
DeserializationErr { reason: String },
1517
}
1618

19+
#[cfg_attr(feature = "napi_rs", napi(object))]
1720
#[derive(Debug, Serialize, Deserialize, Clone)]
1821
pub struct Payment {
1922
pub payment_id: String,

crates/lni/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ pub mod types;
3030
pub use types::*;
3131

3232
pub mod database;
33-
pub use database::{Db, DbError};
33+
pub use database::{Db, DbError, Payment};

0 commit comments

Comments
 (0)