1.1.0 • Published 17 days ago

@synonymdev/blocktank-lsp-ln2-client v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
17 days ago

blocktank-lsp-ln2-client

NPM version

Client to interact with the blocktank-lsp-ln2 service.

Usage

Hodl invoice

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()
    }
})

Bolt11 Invoice

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.

Make payment

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);
})

Channel Open

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.

Versioning

  1. Increase version in package.json.
  2. Add changes to CHANGELOG.md.
  3. Commit changes.
  4. Tag new version: git tag v0.1.0.
  5. Push tag git push origin v0.1.0.
  6. Build: npm run build.
  7. Publish to npm: npm publish.
1.1.0

17 days ago

1.0.0

2 months ago

1.1.0-alpha.0

2 months ago

0.10.0-alpha.17

2 months ago

0.10.0-alpha.16

2 months ago

0.10.0-alpha.15

2 months ago

0.10.0-alpha.14

2 months ago

0.10.0-alpha.13

2 months ago

0.10.0-alpha.7

2 months ago

0.10.0-alpha.9

2 months ago

0.10.0-alpha.8

2 months ago

0.10.0-alpha.10

2 months ago

0.10.0-alpha.12

2 months ago

0.10.0-alpha.11

2 months ago

0.10.0-alpha.6

3 months ago

0.10.0-alpha.5

3 months ago

0.10.0-alpha.3

3 months ago

0.10.0-alpha.2

3 months ago

0.10.0-alpha.4

3 months ago

0.10.0-alpha.1

3 months ago

0.10.0-alpha.0

3 months ago

0.9.0

4 months ago

0.9.0-beta.1

5 months ago

0.9.0-beta.0

5 months ago

0.8.0-rc0

6 months ago

0.8.0

6 months ago

0.2.10

10 months ago

0.7.0-rc.0

6 months ago

0.3.0

10 months ago

0.2.7

10 months ago

0.2.9

10 months ago

0.2.8

10 months ago

0.4.1

8 months ago

0.4.0

8 months ago

0.5.0-rc.0

7 months ago

0.6.0

7 months ago

0.2.6

11 months ago

0.2.3

11 months ago

0.2.5

11 months ago

0.2.4

11 months ago

0.2.2

11 months ago

0.2.2-beta.0

12 months ago

0.2.1

12 months ago

0.2.0

12 months ago

0.2.0-alpha.2

12 months ago

0.2.0-alpha.1

12 months ago