npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rolznz-test4

v3.0.0

Published

Web components to connect to a lightning wallet and power a website with WebLN

Downloads

3

Readme

image

Bitcoin Connect

This project includes web components for connecting to Lightning wallets and enabling WebLN. Websites only need to implement a single interface to connect with multiple wallets (WebLN), and users can connect from both desktop and mobile devices. These components work with pure HTML and all Javascript libraries or frameworks, such as React, Angular, Vue, Solid.js, etc.

🆕 Bitcoin Connect also supports a nice invoice payment UI that gives a multitude of options to a user to pay an invoice. Accept payments with a single line of code.

🛝 Try it out

Demo

🧳 Migration Guide

There are multiple breaking changes in v3. See our migration guide here. Click here for v2.

🚀 Quick Start

🚧WARNING🚧: this package is currently in Alpha. It's got awesome features, but is using new features of protocols such as WebLN and NWC which have not been finalized, and there may be breaking changes or bugs.

React Package

npm install @getalby/bitcoin-connect-react or yarn add @getalby/bitcoin-connect-react

Web Components Package

npm install @getalby/bitcoin-connect or yarn add @getalby/bitcoin-connect

HTML (CDN)

You can use Bitcoin Connect without any build tools:

<script type="module">
  import {launchModal} from 'https://esm.sh/@getalby/[email protected]'; // jsdelivr.net, skypack.dev also work

  // use Bitcoin connect API normally...
  launchModal();

  // or if you just want access to the web components:
  import 'https://esm.sh/@getalby/[email protected]';
</script>

<!-- Bitcoin Connect components are now available -->
<bc-button></bc-button>

🤙 Usage

Pure JS

import {
  init,
  launchModal,
  requestProvider,
} from '@getalby/bitcoin-connect-react';

// Initialize Bitcoin Connect
init({
  appName: 'My Lightning App', // your app name
});

// launch a payment flow
await launchModal({invoice: 'lnbc...'});

// or request a WebLN provider to use the full WebLN API
const weblnProvider = await requestProvider();
const {preimage} = await weblnProvider.sendPayment('lnbc...');

Continue further down for the full Bitcoin Connect API.

React

import {Button, init, launchModal, closeModal, requestProvider} from '@getalby/bitcoin-connect-react';

// Initialize Bitcoin Connect
init({
  appName: "My Lightning App", // your app name
})

// request a provider
<button onClick={() => {
  // if no WebLN provider exists, it will launch the modal
  const weblnProvider = await requestProvider();
  const { preimage } = await weblnProvider.sendPayment("lnbc...")
}}>
  Request WebLN provider
</button>

// render the Bitcoin Connect button
<Button onConnect={(provider) => {
  provider.sendPayment("lnbc...")
}} />

// render a payment component on its own
<SendPayment invoice="lnbc..."/>

// open modal programmatically to pay an invoice
<button onClick={() => launchModal({invoice: "lnbc..."})}>
  Programmatically launch modal
</button>

// close modal programmatically
closeModal();

React SSR / NextJS

Make sure to only render the components client side. This can be done either by creating a wrapper component with 'use client' directive (NextJS app directory), using next/dynamic, or a dynamic import e.g.

useEffect(() => {
  // init bitcoin connect to provide webln
  import('@getalby/bitcoin-connect-react');
}, []);

Other Frameworks

💡 The core Bitcoin Connect package works on all frameworks because it is powered by web components. However, a wrapper can simplify usage of Bitcoin Connect.

Use another popular framework? please let us know or feel free to create a PR for a wrapper. See the React package for an example implementation.

Pure HTML

Components

Bitcoin Connect exposes the following web components for allowing users to connect their desired Lightning wallet:

  • <bc-button/> - launches the Bitcoin Connect Modal on click
  • <bc-send-payment/> - render a payment request UI
    • Arguments:
      • invoice - BOLT11 invoice
  • more components coming soon

Bitcoin Connect API

Initializing Bitcoin Connect

import {init} from '@getalby/bitcoin-connect-react';

// Initialize Bitcoin Connect
init({
  appName: 'My Lightning App', // your app name
  // filters: ["nwc"],
  // showBalance: true,
});
  • appName - Name of the app requesting access to wallet. Currently used for NWC connections (Alby and Mutiny)
  • filters - Filter the type of connectors you want to show. Example: "nwc" (only show NWC connectors).
  • showBalance - If false, do not request the connected wallet's balance

Requesting a provider

With one line of code you can ensure you have a WebLN provider available and ready to use. If one is not available, the Bitcoin connect modal will be launched.

import {requestProvider} from '@getalby/bitcoin-connect';

const provider = await requestProvider();
await provider.sendPayment('lnbc...');

Programmatically launching the modal

The modal can then be launched with:

import {launchModal} from '@getalby/bitcoin-connect';

launchModal(); // A `<bc-modal/>` element will be injected into the DOM

launchModal can also take an optional options object:

import {launchModal} from '@getalby/bitcoin-connect';

launchModal({
  invoice: 'lnbc...', // bolt11 invoice
});

Programmatically closing the modal

import {closeModal} from '@getalby/bitcoin-connect';

closeModal();

Disconnect from wallet

import {disconnect} from '@getalby/bitcoin-connect';

disconnect();

Check connection status

window.bitcoinConnect.isConnected();

Events

onConnected

This event fires when a WebLN provider is made available.

  • When a user connects for the first time
  • On page reload when a user has previously connected
import {onConnected} from '@getalby/bitcoin-connect';

const unsub = onConnected(async (provider) => {
  const {preimage} = await provider.sendPayment('lnbc...');
});
unsub();
onConnecting

This event fires when a WebLN provider is initializing.

  • When a user connects for the first time
  • On page reload when a user has previously connected
import {onConnecting} from '@getalby/bitcoin-connect';

const unsub = onConnecting(async () => {
  // do something...
});
unsub();
onDisconnected

This event fires when the user manually disconnects from Bitcoin Connect.

import {onDisconnected} from '@getalby/bitcoin-connect';

const unsub = onDisconnected(async () => {
  // do something...
});
unsub();
onModalOpened

This event fires when the Bitcoin Connect modal opens.

import {onModalOpened} from '@getalby/bitcoin-connect';

const unsub = onModalOpened(async () => {
  // do something...
});
unsub();
onModalClosed

This event fires when the Bitcoin Connect modal closes.

import {onModalClosed} from '@getalby/bitcoin-connect';

const unsub = onModalClosed(async () => {
  // do something...
});
unsub();

WebLN global object

WARNING: webln is no longer injected into the window object by default. If you need this, execute the following code:

import {onConnected} from '@getalby/bitcoin-connect';

onConnected((provider) => {
  window.webln = provider;
});

WebLN events

Providers also should fire a webln:connected event. See webln.guide.

More methods coming soon. Is something missing that you'd need? let us know!

Styling

These variables must be set at the root or on a container element wrapping any bitcoin connect components.

html {
  --bc-color-brand: #196ce7; /* Only 6-digit hex and rgb formats are supported! */
}

Optional CSS variables for further customization:

html {
  --bc-color-brand-dark: #3994ff; /* use a different brand color in dark mode */
  --bc-brand-mix: 100%; /* how much to mix the brand color with default foreground color */
}

💡 using near-white or black brand colors? either set a lower bc-brand-mix or make sure to use an off-white for bc-color-brand and off-black for bc-color-brand-dark to avoid conflicts with the modal background color.

Dark mode

Automatic (Recommended)

Bitcoin Connect uses prefers-color-scheme to automatically detect light/dark mode.

Manual

In case your site uses a manual theme switcher, you can force a theme by following these steps:

see an example here

  1. set globalThis.bcDarkMode = "class" before any bitcoin connect components are rendered
  2. "dark" must be added as a classname to the document to enable dark mode (e.g. <html class="dark"> or document.documentElement.classList.add('dark')) otherwise light mode will be forced.

Access to underlying providers (NWC, LNC etc.)

import { WebLNProviders, requestProvider } from "@getalby/bitcoin-connect";

const provider = await requestProvider();

if (provider instanceof WebLNProviders.NostrWebLNProvider) {
  provider.nostrWalletConnectUrl;
}

if (provider instanceof WebLNProviders.LNCWebLNProvider) {
  provider.lnc.lnd.lightning.listInvoices(...);
}

if (provider instanceof WebLNProviders.LnbitsWebLNProvider) {
  provider.requestLnbits('GET', '/api/v1/wallet');
}

Demos

Pure HTML Demo

See Pure HTML

Example codepen

React Demo

See React

Example replit

More demos

Open demos

🛠️ Development

Install

Run yarn install && (cd dev/vite && yarn install)

Run Vite

Run yarn dev

Other dev options

Open dev

Production Build

yarn build

Testing

yarn test

Need help?

We are happy to help, please contact us or create an issue.

FAQ

How does it work?

Bitcoin Connect provides multiple options to the user to connect to a lightning wallet, each compatible with WebLN. Any already-existing providers of WebLN (such as an installed WebLN extension like Alby) are detected and offered, as well as options to create a new WebLN provider through protocols such as NWC. No matter which option you choose, a WebLN provider will become available for the website to use to interact with your lightning wallet. Similar to the Alby extension, new options (called Connectors) can be easily added as they all follow a common, simple interface. As long as there is a way to connect to a lightning wallet through Javascript, a connector can be created for it in Bitcoin Connect. We welcome any and all contributions for new connectors!

Does this work on mobile browsers and mobile PWAs, or desktop browsers without a WebLN extension?

Yes! that's the main benefit.

Does it work with a desktop extension enabled?

Yes. It will use the desktop extension as the default connector if it exists.

Can I connect it to my mobile wallet?

That depends. The connection to your lightning node / wallet needs to be asynchronous so that you can use Bitcoin Connect natively on mobile websites or PWAs.

Can a user connect any lightning wallet?

It will only work for the connectors that are shown in the modal. Some of these connectors (e.g. the Alby Browser Extension) allow to connect multiple wallets themselves. Feel free to contribute to add a new connector.

Does it "remember" the user if they leave the page or close the browser?

Yes. Your connection is saved to localStorage

Is this safe?

You should have a certain level of trust on the website you decide to connect your wallet with, and that they ensure there is no malicious third-party scripts which would intend to read the wallet connection configuration, either from memory or storage. Connectors with budget controls or confirmation dialogs (Alby extension or NWC) are recommend so you have full control over your connection.

What are the high level things I need to do to add this to my site?

  1. add the "Connect Wallet" button
  2. wait for a connection event (using window.addEventListener) and then request to pay the invoice with window.webln

What connectors are supported?

If a user pays with another wallet why does the modal stay open?

Bitcoin Connect cannot detect payments made externally. It's up to your app to detect the payment and then programmatically close the modal using the exposed closeModal function.

Why is window.webln not set after connecting?

The global window.webln object can be overridden if there are multiple providers, leading to unexpected behaviour. We recommend using the requestProvider function to obtain a WebLN provider instead of relying on the global window object.

Why does Bitcoin Connect not work on some pages?

Bitcoin Connect must be imported at the root component or on every component that requires webln to ensure webln is available. If you only import the button in your settings page, you'll still need to import the library where you want to make a lightning payment. We recommend using the requestProvider function.

Known Issues

  • NWC connectors do not work on iOS in non-secure contexts because window.crypto.subtle is unavailable. If testing on your phone, please run an https server or use an https tunnel.

🔥 Lit

This project is powered by Lit.

See Get started on the Lit site for more information.

License

MIT