Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@synonymdev/blocktank-lsp-ln2-client
Advanced tools
Client to interact with the blocktank-lsp-ln2 service.
Hodl invoices are invoices that can be canceled or settled by the merchant. This is useful for example if you want to issue a refund in case the service couldn't be fulfilled.
Create HOLD invoice
import { LspLnClient, IBolt11Invoice } from '@synonymdev/blocktank-lsp-ln2-client';
const amountSat = 1000
const client = new LspLnClient()
const invoice: IBolt11Invoice = await client.createHodlInvoice(amountSat, "This is the description of the invoice")
console.log('New created invoice', invoice)
Listen for HOLDING event
import {LspLnEventListener, IBolt11InvoiceChangedEvent, LspLnClient, Bolt11InvoiceState} from "@synonymdev/blocktank-lsp-ln2-client";
const client = new LspLnClient()
const listener = new LspLnEventListener()
await listener.init()
listener.listenToInvoicesChanged(async message => {
const event: IBolt11InvoiceChangedEvent = message.content
const eventMatchesOurInvoice = event.invoiceId === invoice.id
if (!eventMatchesOurInvoice) {
// This is a general event stream, not just for our invoice.
return
}
// Pull the latest state of the invoice. You need to do this because events are not guaranteed to be in order.
const currentInvoice = await client.getInvoice(invoice.id)
const isHolding = currentInvoice.state === Bolt11InvoiceState.HOLDING && event.state.new === Bolt11InvoiceState.HOLDING // Doublecheck that the event is in the HOLDING state to not double process the event.
if (isHolding) {
// Payment arrived but is not settled yet.
const success = doWhateverYouWant()
if (success) {
// Settle the invoice.
await LnWorkerApi.settleHodlInvoice(invoice.id)
} else {
// Reject the invoice.
await LnWorkerApi.cancelHodlInvoice(invoice.id)
}
} else if (currentInvoice.state === Bolt11InvoiceState.PAID) {
// Invoice is settled.
markAsSettled()
} else if (currentInvoice.state === Bolt11InvoiceState.CANCELED) {
// Invoice is canceled.
markAsCanceled()
}
})
This is a regular Lightning invoice.
Create invoice
import { LspLnClient, IBolt11Invoice } from '@synonymdev/blocktank-lsp-ln2-client';
const amountSat = 1000
const client = new LspLnClient()
const invoice: IBolt11Invoice = await client.createInvoice(amountSat, "This is the description of the invoice")
console.log('New created invoice', invoice)
Listen for PAID or CANCELED event
import {LspLnEventListener, IBolt11InvoiceChangedEvent, Bolt11InvoiceState} from "@synonymdev/blocktank-lsp-ln2-client";
const listener = new LspLnEventListener()
await listener.init()
listener.listenToInvoicesChanged(async message => {
const event: IBolt11InvoiceChangedEvent = message.content
const eventMatchesOurInvoice = event.invoiceId === invoice.id
if (!eventMatchesOurInvoice) {
// This is a general event stream, not just for our invoice.
return
}
// Pull the latest state of the invoice. You need to do this because events are not guaranteed to be in order.
if (event.state.new === Bolt11InvoiceState.PAID) {
// Invoice is settled.
markAsSettled()
} else if (currentInvoice.state === Bolt11InvoiceState.CANCELED) {
// Invoice is canceled. This happens when the invoice is expired.
markAsCanceled()
}
})
Info Regular BOLT11 invoices do not emit a HOLDING event state.
Pay a bolt11 invoice.
Pay invoice
import { LspLnClient, IBolt11Payment, IBolt11PayCreationError } from '@synonymdev/blocktank-lsp-ln2-client';
const client = new LspLnClient()
const invoice = 'lntb1u1pwz5w78pp5e8w8cr5c30xzws9...'
try {
const payment: IBolt11Payment = await client.makePayment(invoice)
} catch (e) {
// The worker or the LND node rejected the pay request without even trying to pay.
const error: IBolt11PayCreationError = e;
console.log(`${error.type} will tell you what went wrong in a simple way. ${error.message} will give you a human error message.`)
console.log(`${error.datail?.raw} will give you the raw error. Don't rely on this though as this is can change in the future.`)
}
Listen for channel FAILED or PAID events
import {LspLnEventListener, LspLnClient, IBolt11PayChangedEvent, Bolt11PaymentState} from "@synonymdev/blocktank-lsp-ln2-client";
const listener = new LspLnEventListener()
await listener.init()
listener.listenToPaymentChanged(async message => {
const event: IBolt11PayChangedEvent = message.content
const eventMatches = event.paymentId === payment.id
if (!eventMatches) {
// This is a general event stream, not just for our payment.
return
}
setPaymentState(event.state.new);
})
Open a channel to a node and observe the state.
Create channel open
import { LspLnClient, IOpenChannelOrder, IOpenChannelError } from '@synonymdev/blocktank-lsp-ln2-client';
const connectionString = '02d1b...@192.168.1.1:9735'
const isPrivate = false
const localBalanceSat = 100000
try {
const open: IOpenChannelOrder = await client.orderChannel(connectionString, isPrivate, localBalanceSat)
} catch (e) {
// This is a sync channel open. If we could not connect to the peer or the open channel process failed, we will get an error here.
// error is of type IOpenChannelError.
const error: IOpenChannelError = e;
console.log(`${error.type} will tell you what went wrong in a simple way. ${error.message} will give you a human error message.`)
console.log(`${error.datail?.raw} will give you the raw error. Don't rely on this though as this is can change in the future.`)
}
Listen for channel OPEN or CLOSED events
import {LspLnEventListener, IChannelOpenEvent, LspLnClient, OpenChannelOrderState} from "@synonymdev/blocktank-lsp-ln2-client";
const client = new LspLnClient()
const listener = new LspLnEventListener()
await listener.init()
listener.listenToOpenChannelChanged(async message => {
const event: IChannelOpenEvent = message.content
const eventMatchesOurChannel = event.orderId === open.id
if (!eventMatchesOurChannel) {
// This is a general event stream, not just for our channel.
return
}
// Pull the latest state of the channel open. You need to do this because events are not guaranteed to be in order.
const currentChannel = await client.getOrderedChannel(open.id)
setChannelState(currentChannel.state);
})
Important Events can arrive in a different order than they were sent. If there is an error throw, the event will be retried. Make sure you don't process the same event twice or in the wrong order!
Info Always close your event listener with
await listener.close()
when you are done listening to events.
package.json
.CHANGELOG.md
.git tag v0.1.0
.git push origin v0.1.0
.npm run build
.npm publish
.FAQs
Blocktank LN2 client
We found that @synonymdev/blocktank-lsp-ln2-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.