Lightning Web SDK
An npm package that provides useful and common tools and helpers to build lightning web applications.
🚀 Quick Start
npm install @getalby/lightning-tools
or
yarn add @getalby/lightning-tools
or for use without any build tools:
<script type="module">
import { LightningAddress } from "https://esm.sh/@getalby/lightning-tools@5.0.0";
(async () => {
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
console.log(ln.lnurlpData);
})();
</script>
This library relies on a global fetch()
function which will work in browsers and node v18 or newer. (In older versions you have to use a polyfill.)
🤙 Usage
Lightning Address
The LightningAddress
class provides helpers to work with lightning addresses
import { LightningAddress } from "@getalby/lightning-tools";
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
console.log(ln.lnurlpData);
console.log(ln.keysendData);
Get an invoice:
import { LightningAddress } from "@getalby/lightning-tools";
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
const invoice = await ln.requestInvoice({ satoshi: 1000 });
console.log(invoice.paymentRequest);
console.log(invoice.paymentHash);
Verify a payment
import { LightningAddress } from "@getalby/lightning-tools";
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
const invoice = await ln.requestInvoice({ satoshi: 1000 });
const paid = await invoice.verifyPayment();
if (paid) {
console.log(invoice.preimage);
}
await window.webln.enable();
const response = await window.webln.sendPayment(invoice.paymentRequest);
const paid = invoice.validatePreimage(response.preimage);
if (paid) {
console.log("paid");
}
await invoice.isPaid();
It is also possible to manually initialize the Invoice
const { Invoice } = require("alby-tools");
const invoice = new Invoice({ pr: pr, preimage: preimage });
await invoice.isPaid();
Boost a LN address:
You can also attach additional metadata information like app name, version, name of the podcast which is boosted etc. to the keysend payment.
import { LightningAddress } from "@getalby/lightning-tools";
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
const boost = {
action: "boost",
value_msat: 21000,
value_msat_total: 21000,
app_name: "Podcastr",
app_version: "v2.1",
feedId: "21",
podcast: "random podcast",
episode: "1",
ts: 2121,
name: "Satoshi",
sender_name: "Alby",
};
await ln.boost(boost);
Zapping a LN address on Nostr:
Nostr is a simple, open protocol that enables truly censorship-resistant and global value-for-value publishing on the web. Nostr integrates deeply with Lightning. more info
This librarys provides helpers to create zaps.
import { LightningAddress } from "@getalby/lightning-tools";
const ln = new LightningAddress("hello@getalby.com");
await ln.fetch();
const response = await ln.zap({
satoshi: 1000,
comment: "Awesome post",
relays: ["wss://relay.damus.io"],
e: "44e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
});
console.log(response.preimage);
For a full example see examples/zaps
Zapping a LN address on Nostr using Nostr Wallet Connect:
Native zaps without a browser extension are possible by using a Nostr Wallet Connect WebLN provider.
See examples/zaps-nwc
L402
L402 is a protocol standard based on the HTTP 402 Payment Required error code
designed to support the use case of charging for services and
authenticating users in distributed networks.
This library includes a fetchWithL402
function to consume L402 protected resources.
fetchWithL402(url: string, fetchArgs, options)
- url: the L402 protected URL
- fetchArgs: arguments are passed to the underlaying
fetch()
function used to do the HTTP request - options:
- webln: the webln object used to call
sendPayment()
defaults to globalThis.webln - store: a key/value store object to persiste the l402 for each URL. The store must implement a
getItem()
/setItem()
function as the browser's localStorage. By default a memory storage is used. - headerKey: defaults to L402 but if you need to consume an old LSAT API set this to LSAT
Examples
import { fetchWithL402 } from "@getalby/lightning-tools";
await fetchWithL402(
"https://lsat-weather-api.getalby.repl.co/kigali",
{},
{ store: window.localStorage }
)
.then((res) => res.json())
.then(console.log);
import { fetchWithL402 } from "@getalby/lightning-tools";
import { webln } from "alby-js-sdk";
const nwc = new webln.NostrWebLNProvider({
nostrWalletConnectUrl: loadNWCUrl(),
});
await fetchWithL402(
"https://lsat-weather-api.getalby.repl.co/kigali",
{},
{ webln: nwc }
)
.then((res) => res.json())
.then(console.log);
import { l402 } from "@getalby/lightning-tools";
await l402.fetchWithL402(
"https://lsat-weather-api.getalby.repl.co/kigali",
{},
{ store: new l402.storage.NoStorage() }
);
Basic invoice decoding
You can initialize an Invoice
to decode a payment request.
const { Invoice } = require("alby-tools");
const invoice = new Invoice({ pr });
const { paymentHash, satoshi, description, createdDate, expiryDate } = invoice;
If you need more details about the invoice, use a dedicated BOLT11 decoding library.
💵 Fiat conversions
Helpers to convert sats values to fiat and fiat values to sats.
getFiatValue(satoshi: number, currency: string): number
Returns the fiat value for a specified currrency of a satoshi amount
getSatoshiValue(amount: number, currency: string): number
Returns the satoshi value for a specified amount (in the smallest denomination) and currency
getFormattedFiatValue(satoshi: number, currency: string, locale: string): string
Like getFiatValue
but returns a formatted string for a given locale using JavaScript's toLocaleString
Examples
await getFiatValue(satoshi: 2100, currency: 'eur');
await getSatoshiValue(amount: 100, currency: 'eur');
await getFormattedFiatValue(satoshi: 2100, currency: 'usd', locale: 'en')
🤖 Lightning Address Proxy
This library uses a proxy to simplify requests to lightning providers.
- Many ln addresses don't support CORS, which means fetching the data directly in a browser environment will not always work.
- Two requests are required to retrieve lnurlp and keysend data for a lightning address. The proxy will do these for you with a single request.
You can disable the proxy by explicitly setting the proxy to false when initializing a lightning address:
const lightningAddress = new LightningAddress("hello@getalby.com", {
proxy: false,
});
crypto dependency
If you get an crypto is not defined
in NodeJS error you have to import it first:
import * as crypto from 'crypto';
globalThis.crypto = crypto as any;
fetch() dependency
This library relies on a global fetch object which will work in browsers and node v18.x or newer. In old version you can manually install a global fetch option or polyfill if needed.
For example:
import fetch from "cross-fetch";
globalThis.fetch = fetch;
import "cross-fetch/polyfill";
🛠 Development
yarn install
yarn run build
Need help?
We are happy to help, please contact us or create an issue.
License
MIT