# Welcome to NWC

Nostr Wallet Connect (NWC) — Connecting Bitcoin Wallets and Apps

<figure><img src="/files/I9DvVzwOHzfdVTmu2h0Q" alt="" width="555"><figcaption></figcaption></figure>

### One Open Protocol to Connect Bitcoin Wallets and Apps

These docs provide guidance and toolkits for developers of bitcoin apps and wallets to build engaging payment experiences. Enjoy!

## What are you building?

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h3>Bitcoin Wallet</h3></td><td><a href="/pages/aQmqDqaG5uqjAkGFInMP">/pages/aQmqDqaG5uqjAkGFInMP</a></td><td><a href="/files/ZdxYPwk0h0g9om19JIEK">/files/ZdxYPwk0h0g9om19JIEK</a></td></tr><tr><td><h3>Bitcoin App or Website  </h3></td><td><a href="/pages/6FtJidwF6LZ8tGvotp1s">/pages/6FtJidwF6LZ8tGvotp1s</a></td><td><a href="/files/gdU3Fz82eAn63LQ3mBcu">/files/gdU3Fz82eAn63LQ3mBcu</a></td></tr></tbody></table>

## Join the community

[Join the NWC Discord Channel](https://discord.gg/PRhQPZCmeF)


# Introduction to NWC

NWC describes a way for client apps to access a remote bitcoin lightning wallet through a standardized protocol. Wallets and apps want to implement this to allow users to seamlessly connect their own wallet accounts for native payments in apps.

### NWC - a free and open protocol

NWC is a free and open protocol. This is a crucial property, because it creates several benefits:

1. NWC can be used by anyone.
2. Implementing payments based on NWC avoids vendor lock-in.
3. NWC offers a higher degree of flexibility, with more integration options between existing and new apps.

Apps that adopt NWC enhance their accessibility and innovation. Most importantly you ensure interoperability with the ecosystem and capitalize on network effects of your ecosystem.&#x20;

### NWC builds on bitcoin's lightning network

Bitcoin is a decentralized digital currency that enables peer-to-peer transactions without the need for banks or intermediaries. The lightning network comes in as a second-layer protocol that enables instant, low-fee payments by routing transactions off-chain while maintaining bitcoin’s security guarantees. Together, bitcoin and the lightning network provide a powerful foundation for a global, open financial system that’s fast, borderless, and permissionless. It's a match made in heaven and therefore the payment protocol of choice for NWC.&#x20;

Please note, NWC only describes how payment intents are exchanged between apps and wallets. NWC can support any payment network. In fact, there are proposals for bitcoin on-chain transactions or multi-currency payments.

### Why is it called *Nostr* Wallet Connect?

As stated in the beginning NWC describes a way for apps to connect with wallets, hence the name of the protocol. Nostr is part of NWC as the underlying enabling technology. Nostr itself is a simple, open protocol that enables censorship-resistant, decentralized communication flows—built on public-key cryptography and message relays. It does not rely on central servers or gatekeepers. NWC uses Nostr's relay technology and public-key cryptography to securely exchange information between apps and wallets.

{% hint style="info" %}
As a end-user of an NWC-enabled wallet, you don't need to know anything about the underlying relay technology or own your own Nostr key. Same as your email provider today that abstracts away SMTP, your wallet and the connected app handles the information exchange.
{% endhint %}

### How a Payment Works (Big Picture)

The app and the wallet can interact with one another across the relay bridge once the session is initialized. Relays provide a reliable and efficient way to communicate with lightning nodes without the use of TOR or exposing nodes on clearnet.&#x20;

If the user wishes to perform an action (e.g. pay\_invoice) the transactions are prepared by the app frontend, serialized and encrypted, and then written to the relay. The wallet reads the message from the relay, decrypts it, unpacks the transaction, presents it to the wallet user for signing or auto-executes the action. In that way the relay only facilitates the communication but the request itself is encrypted and cannot be read by the relay.

### How a Payment Works (Step-by-Step)

<figure><img src="/files/PSKehMmaEStqIF3mjWmD" alt=""><figcaption><p>NWC overview</p></figcaption></figure>

1. The user scans the QR code generated by the **wallet service** with their **client** **application**, they follow a `nostr+walletconnect:` deeplink or configure the connection details manually. The step to setup a connection only happens once. &#x20;
2. The **client app** receives an invoice which can happen from various sources such NWC itstelf or LNURL.
3. The **client app** sends an event to the **wallet service** via a relay. The content is a `pay_invoice` request. The private key is the secret from the connection string above.
4. The relay forwards the  `pay_invoice` request to the **wallet service**.
5. The **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment.
6. The **wallet service** responds to the event by sending a specific event and content as a response either containing an error message or a preimage.


# What to Build

NWC gives you the freedom to do whatever you want—it’s fully agnostic and leaves the creativity to you. Its purpose is to provide simple, easy to integrate building blocks. What you do with them is entirely up to you.

### For App developers

<details>

<summary>Social P2P payments</summary>

* Seamlessly onboard users with their wallets and let them exchange value instead of “likes”
* That will add a completely new level of interaction to your app powered by instant p2p transactions

**Example**: Zaps on Nostr

</details>

<details>

<summary>Marketplace payments</summary>

* Transform your marketplace with instant payments directly between marketplace participants without expensive payment providers and any regulatory burden.
* You can earn your share for each facilitated transaction by deducting the amount from the user's connected wallet.

</details>

<details>

<summary>Subscription payments</summary>

* Give your customers the freedom to set up hassle-free subscriptions for your products.
* NWC lets you pull payments from connected wallets given your customers set respective permissions.
* You decide the payment frequency: Yearly, monthly, daily, hourly, etc.

**Example:** [ZapPlanner](https://zapplanner.albylabs.com/)

</details>

<details>

<summary>Rebuild complete wallet interface</summary>

* NWC gives you all the building blocks to rebuild a complete wallet interface into your own app: Send, receive, list transactions, etc.&#x20;
* Create the UX according to your own imagination without having to build a wallet backend yourself.

**Example:** [Boostz](https://boostz.xyz/)

</details>

<details>

<summary>Agentic payments</summary>

* NWC lets you attach wallets to any app such as AI agents.&#x20;
* Let the agent own their own wallet and set access permissions or  payment allowances according to your preferences.&#x20;

**Example:** [NWC MCP Server](https://github.com/getalby/nwc-mcp-server)

</details>

<details>

<summary>In-Game transactions</summary>

* Boost retention and engagement by rewarding users with real value payouts.
* Or let users wager and play against each other. You orchestrate the payments between them and earn your share.&#x20;

**Example:** [Zappy Bird](https://rolznz.github.io/zappy-bird/)

</details>

### For Wallet developers

<details>

<summary>NWC Wallet Service: Allow apps to connect seamlessly to your wallet</summary>

Instantly unlock access for all users in N+ existing NWC-enabled applications and increase payment activity.

**Example:** Alby Hub, Coinos, Primal, etc.

</details>

<details>

<summary>Access to multiple wallet interfaces</summary>

Provide new payment experiences by letting your users pay right where they need to pay such as in the browser. But this time they can use their wallet on iOS or Android.

**Example:** Alby Browser Extension

</details>

<details>

<summary>Advanced Connections and Metadata</summary>

Provide your users with tools to segregate and analyze their payments across apps.

</details>

<details>

<summary>Paid Services</summary>

Explore what is possible by building optional paid services that your users can connect to via NWC.

</details>


# FAQ

#### Which apps already support NWC?

You’ll find a growing list of NWC-enabled apps [here](https://github.com/getAlby/awesome-nwc?tab=readme-ov-file#apps) from a wide range of categories—including AI tools, education platforms, fintech services, messaging apps, social media, content platforms, tipping bots, and more. The ecosystem is expanding quickly, with new integrations happening all the time.

#### Which wallets already support NWC?

You can find a list of NWC-compatible wallets [here](https://guides.getalby.com/italian-guides/wallet-lightning-alby/come-ricaricare-il-saldo-del-tuo-wallet/da-un-exchange). It includes options across web, mobile, and desktop platforms. You can even connect your own lightning node at home to any app that supports NWC, giving you full control and flexibility.

#### Do end-users need a Nostr key to send or receive payments?

No, end-users don’t need a Nostr key or even be aware that Nostr is involved. Wallets and apps handle all the communication behind the scenes via NWC relays, making the experience seamless for users.

#### How much does it cost to transact via NWC?

NWC is a free and open protocol—there are no licensing fees or vendor lock-ins to implement or use it. You can integrate it freely into your apps without paying anyone. Transactions sent over the lightning network do incur the usual routing fees, just like any standard lightning payment.


# Benefits and Features

**Nostr Wallet Connect (NWC)** makes it easy for developers to integrate Bitcoin wallets into their applications. With a simple, standardized protocol, NWC enables apps to interact with users' wallets in real-time—without requiring manual steps like QR code scanning or switching apps.

Whether you're building a mobile app, desktop software, CLI tool, or backend service, NWC gives you the flexibility and power to handle bitcoin payments seamlessly.

## Benefits for app developers

* **Easy and Quick Implementation**\
  Integrate in minutes with a clean, well-documented API. Focus on building features, not infrastructure.
* **Free and Open**\
  NWC is open-source and free to use—no licensing fees, vendor lock-in, or hidden costs.
* **Zero Custody**\
  Eliminate the need to custody user funds. Let wallets handle the money, while your app simply orchestrates actions securely.&#x20;
* **Flexible**\
  Use NWC for a full wallet experience or just for specific features like sending or receiving payments. It's modular by design.
* **Interoperable**\
  Connect to any NWC-compatible bitcoin wallet. One protocol, multiple wallets—no custom integrations needed.
* **Platform-Independent**\
  Works across environments: mobile apps, web backends, CLI tools, desktop apps—NWC adapts to your stack.
* **Persistent Connection**\
  Once the connection is setup, as long as the user's wallet is online your app can communicate with it without requiring user input.

## Benefits for users

* **Convenient In-App Payments**\
  Initiate payments programmatically—no QR codes, no switching apps, no manual confirmation required from the user.
* **Faster Onboarding**\
  Users with NWC-enabled wallets can connect instantly—no signups, KYC, or setup steps. If their wallet is funded, they’re ready to go.
* **Single Wallet**\
  Users have a single wallet across multiple apps - no need to "top up" inside each individual application.

## Features

* **Send Payments**\
  Initiate single payments, batch transactions, or even automate recurring payments with minimal code.
* **Receive Payments**\
  Display payment requests and receive funds in real time. Great for tipping, in-app purchases, or donations.
* **Wallet Balance**\
  Query and display the current balance of a connected wallet within your app.
* **Payment History**\
  List incoming and outgoing payments for transparency and tracking.
* **Payment Verification**\
  Check the status of payments—pending, completed, or failed—programmatically.


# Getting Started

How to get started quickly with bitcoin payments based on NWC

{% stepper %}
{% step %}

### Plan your Bitcoin integration &#x20;

[Alby Developer Sandbox](https://sandbox.albylabs.com/): Explore different payment scenarios

[NWC Faucet](https://faucet.nwc.dev/): Create test wallets

[Best Practices](/bitcoin-apps-and-websites/best-practices)
{% endstep %}

{% step %}

### Build your Bitcoin integration

[Code examples](/bitcoin-apps-and-websites/code-examples)

[SDKs and Tools](/bitcoin-apps-and-websites/sdks-and-tools)
{% endstep %}

{% step %}

### Enable 1-Click Wallet Connections

[1-Click Wallet Connections](/bitcoin-apps-and-websites/connecting-to-the-wallet/1-click-wallet-connections)
{% endstep %}

{% step %}

### Ship your NWC integration 🚀

Get listed on [NWC.dev](https://nwc.dev/) and [Awesome-NWC](https://github.com/getAlby/awesome-nwc)
{% endstep %}
{% endstepper %}


# Code Examples

Fast-track your NWC integration with these examples

## TypeScript Project (NodeJS, Browser, React Native) <a href="#sample-typescript-project" id="sample-typescript-project"></a>

### Install the SDK

```
npm install @getalby/sdk
```

or

```javascript
yarn add @getalby/sdk
```

## Quick Start

You can use the JS SDK `LN` class to quickly send and receive payments.

```
import { LN } from "@getalby/sdk";
const credentials = "nostr+walletconnect://..."; // the NWC connection credentials
const ln = new LN(credentials);

// to send
await ln.pay("lnbc..."); // pay a lightning invoice

// generate an invoice and act upon it once it's paid
const request = await ln.receive({satoshi: 21});
request.onPaid(giveAccess);
```

## Web Project

### Bitcoin Connect

See also [Bitcoin Connect](https://github.com/getAlby/bitcoin-connect/) if you are developing a web application. Bitcoin Connect is a front end library that does the heavily lifting for you. The library includes web components letting users connect from both desktop and mobile devices or make one time payments from wallets that do not yet support NWC.

You can also filter by NWC wallets, allowing users to create a new NWC connection that can be used by your service (for example: [ZapPlanner](https://zapplanner.albylabs.com/)).&#x20;

### Alby JS SDK

The `NostrWebLNProvider` exposes the [WebLN](https://webln.guide/) interface to execute lightning wallet functionality through Nostr Wallet Connect, such as sending payments, making invoices and getting the node balance.

<details>

<summary>Example: <a href="https://github.com/getAlby/js-sdk/blob/master/examples/nwc/get-balance.js">get-balance.js</a> </summary>

```typescript
// import "websocket-polyfill"; // required in node.js

import * as readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

import { webln as providers } from "../../dist/index.module.js";

const rl = readline.createInterface({ input, output });

const nwcUrl =
  process.env.NWC_URL ||
  (await rl.question("Nostr Wallet Connect URL (nostr+walletconnect://...): "));
rl.close();

const webln = new providers.NostrWebLNProvider({
  nostrWalletConnectUrl: nwcUrl,
});
await webln.enable();
const response = await webln.getBalance();

console.info(response);

webln.close();
```

</details>

[list-transactions.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/list-transactions.js)

[make-invoice.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/make-invoice.js)

[send-payment.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/send-payment.js)

You can explore all the examples [here](https://github.com/getAlby/js-sdk/blob/master/examples/nwc).&#x20;

## Mobile Project <a href="#sample-typescript-project" id="sample-typescript-project"></a>

The `NWCClient` exposes the NWC interface directly, which is more powerful than the WebLN interface and is recommended if you plan to create an application outside of the web (e.g. native mobile/command line/server backend etc.). See [Alby SDK NWCClient documentation](https://github.com/getAlby/js-sdk/blob/master/docs/nwc.md).

<details>

<summary>Example: <a href="https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/get-balance.js">get-balance.js</a></summary>

```typescript
// import "websocket-polyfill"; // required in node.js

import * as readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

import { nwc } from "../../../dist/index.module.js";

const rl = readline.createInterface({ input, output });

const nwcUrl =
  process.env.NWC_URL ||
  (await rl.question("Nostr Wallet Connect URL (nostr+walletconnect://...): "));
rl.close();

const client = new nwc.NWCClient({
  nostrWalletConnectUrl: nwcUrl,
});
const response = await client.getBalance();

console.info(response);

client.close();
```

</details>

[list-transactions.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/list-transactions.js)

[make-invoice.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/make-invoice.js)

[pay-invoice.js](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/pay-invoice.js)

You find all examples [here](https://github.com/getAlby/js-sdk/tree/master/examples/nwc/client).


# Connecting To The Wallet

There are two different flows to connect an app to the wallet - the traditional flow, which is simple but less user friendly and secure, and the new seamless 1-click connection flow. Currently it's good to implement both, as not all wallets support the 1-click connection flow yet.


# Traditional Connection Flow

## Connection Secret

Apps and wallets initiated connections via "Connection Secrets". The **wallet service** generates a Connection Secret with protocol `nostr+walletconnect://` and base path it's hex-encoded `pubkey` with the following query string parameters:

* `relay` Required. URL of the relay where the **wallet service** is connected and will be listening for events. May be more than one.
* `secret` Required. 32-byte randomly generated hex encoded string. The **client app** MUST use this to sign events and encrypt payloads when communicating with the **wallet service**.
  * Authorization does not require passing keys back and forth.
  * The user can have different keys for different applications. Keys can be revoked and created at will and have arbitrary constraints (e.g. budgets).
  * The key is harder to leak since it is not shown to the user and backed up.
  * It improves privacy because the user's main key would not be linked to their payments.

#### Example Connection Secret:

```
nostr+walletconnect://b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.getalby.com/v1&secret=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c
```

The user then copies this connection secret and pastes it into the app or website they are using to initiate the connection.


# 1-Click Wallet Connections

## **Introduction**

**NWC is built with user experience and interoperability at its core.**\
It defines a simple, one-click flow for connecting wallets to apps—just like “Log in with Google,” but for bitcoin lightning wallets *“Connect your wallet.”*

What sets NWC apart is its cross-platform compatibility. Whether it’s linking a mobile wallet to a web app, a browser-based wallet to a native mobile app, or even a self-hosted Lightning node—NWC makes it seamless.\
Delivering a smooth, intuitive experience for users across all setups is a fundamental design goal.

### Demo 1: Connecting a web wallet to a web app

{% embed url="<https://www.youtube.com/watch?v=cm0FqpcGcXg>" %}
Connecting Alby Hub in one click to a web app
{% endembed %}

For publicly accessible lightning wallets, NWC specifies a flow based on HTTP to create an OAuth-like experience

### Demo 2: Connecting a self-custodial wallet hosted on a private device to a web app

{% embed url="<https://youtu.be/ZuddFINDW4U>" %}
Connecting Alby Hub hosted on a private device in one click via Alby Go to a web app
{% endembed %}

For mobile-based or self-hosted Lightning wallets, NWC defines a flow that leverages the Nostr protocol. The key benefit is seamless cross-device connectivity—mobile to web and vice versa.

## Connection Secret

Unlike the traditional connection flow, the secret is generated by the client application and never leaves the device. Only the public keys of the client and wallet are exchanged to initiate the connection, creating a safer and user-friendly connection flow. Rather than receiving the entire NWC connection string from the server, The client constructs its connection from individual parts (the wallet's public key and relay URL, and its own generated secret).

## Implementation

### As a (Progressive) Web App

[Bitcoin Connect](https://bitcoin-connect.com/) is a front end library that does the heavily lifting for you. The library includes web components letting users connect from both desktop and mobile devices, using their favorite browser. PWAs *just work*. Bitcoin Connect's components work with pure [HTML](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#html-cdn) and all Javascript libraries or frameworks, such as [React](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#react), Angular, Vue, Solid.js, etc.

### As a Mobile App

#### HTTP Flow

This flow covers wallets that are publicly accessible and can provide a static link for users to connect their wallet and be redirected back into the application.&#x20;

[Code example](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/auth.html)

#### Nostr Flow

This flow covers wallets that are not publicly accessible, which is often the case for mobile-based or self-hosted lightning wallets. The app creates a QR code for the user to scan and link the wallet. &#x20;

[Code example](https://github.com/getAlby/js-sdk/blob/master/examples/nwc/client/nwa.js)

Instructions on how to use it are mentioned [here](https://github.com/getAlby/js-sdk/blob/master/docs/nwc.md#nostr-wallet-auth).

Read the NIP-47 PR for one-click connections [here](https://github.com/nostr-protocol/nips/pull/1818).


# SDKs and Tools

Find SDKs and tools to implement NWC into your apps and websites

## SDKs

* [Javascript](https://github.com/getAlby/js-sdk?tab=readme-ov-file#nostr-wallet-connect-documentation)
* [React Native (Expo)](https://github.com/getAlby/nwc-react-native-expo) (Showcase)
* [Rust](https://github.com/rust-nostr/nostr)
* [Dart](https://pub.dev/packages/nwc)
* [Flutter](https://pub.dev/packages/ndk)
* [Python](https://github.com/supertestnet/python_nwc)

Are you missing a SDK? Join the community and help apps to adopt bitcoin payments with NWC.

## Libraries

### Bitcoin Connect

Bitcoin Connect is a simple library that enables users to connect their wallet to bitcoin lightning-powered websites on any browser through the power of WebLN, the open protocol for lightning on the Web.

{% embed url="<https://www.youtube.com/watch?v=T3XRiwdXKU4>" %}
Introducing Bitcoin Connect
{% endembed %}

Bitcoin Connect works on all web frameworks. Code examples are available for  [HTML](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#html-cdn), [JavaScript](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#pure-js), [React](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#react), [Next JS/SSR](https://github.com/getAlby/bitcoin-connect?tab=readme-ov-file#nextjs--ssr).

Visit: <https://bitcoin-connect.com/>

## Tools

### Alby Developer Sandbox

A playground for Builders to test Bitcoin payment flows in minutes:

* Prototype Bitcoin payments for your app
* Explore real payment scenarios
* Learn Lightning fundamentals

**-->** [**Get started**](https://sandbox.albylabs.com/)

#### **NWC Faucet**

Create test wallets for the NWC protocol.

**-->** [**Get started**](https://faucet.nwc.dev/)<br>


# Best Practices

Follow this page to learn about best practices as an app developer

### Permission requests

App developers should seek permissions responsibly, ensuring that they only request the necessary permissions automatically and for the specific duration required.

### Setting up a connection

App developers should pass the application name when setting up a connection

### Manually adding a connection

Users should always be given the option to paste a connection string from an NWC wallet application. Connection string input fields should be `password` type so they are not leaked in recorded videos or screenshots.

### **Don't assume a particular wallet service**

NWC allows anyone to connect their own wallet or node, so don't assume the user is using a particular one. Stay agnostic in your language about the user's wallet, e.g. instead of saying `Pay`*`with X`*, just say `Pay`.

### Check the supported methods from the connection

Apps should do a `get_info` request to check what the connection supports to ensure that the app does not execute commands that are not supported. A positive side effect of this is it will do a request to the wallet service, notifiying the wallet service that the connection is created (which allows the wallet service to tell the user the connection has been successfully created).


# Benefits and Features

**Nostr Wallet Connect (NWC)** enables seamless, secure communication between bitcoin wallets and a growing ecosystem of apps. By integrating NWC, your wallet becomes instantly compatible with any app that supports the protocol—unlocking new use cases, more transactions, and better user engagement.

NWC provides a clean, event-based interface that lets apps request actions such as sending or receiving payments from your wallet in real-time. It’s open, lightweight, extensible and widely used.

## Benefits for Wallet Developers

* **Access**\
  Instantly connect your wallet to the expanding universe of bitcoin-enabled apps—without building custom APIs or SDKs for each one.
* **Secure**\
  Rely on end-to-end encrypted communication and proven public key infrastructure.
* **Simplicity**\
  One standard interface to support all app types: mobile, web, desktop, and even backend services or bots.
* **Service**\
  Become your users' go-to wallet for interacting with the bitcoin economy. Power everything from tipping to in-app purchases to automation.

## Benefits for Wallet Users

* **Grow**\
  Enable your users to spend and receive bitcoin across more contexts—games, websites, marketplaces, tools—driving higher transaction volume.
* **Safety**\
  NWC can be combined with granular permission management and budget settings to protect users if needed.<br>

## Features

* **Receive Payments**\
  Let apps request invoices or payment addresses directly from the wallet.
* **Send Payments**\
  Support sending single or multiple payments—manual or automated—based on app requests.
* **Show Wallet Balance**\
  Return the current balance to apps for display or logic control.
* **List Payments**\
  Expose incoming/outgoing transaction history to connected apps.
* **Check Payments**\
  Enable apps to verify the status of specific payments (pending, confirmed, failed).


# Getting Started

How to get started quickly with NWC

{% stepper %}
{% step %}

### Plan your wallet service

[Best Practices](/bitcoin-lightning-wallets/best-practices)
{% endstep %}

{% step %}

### Build your wallet service&#x20;

[Code Examples](/bitcoin-lightning-wallets/code-examples)

[Reference Implementations](/bitcoin-lightning-wallets/references-and-sdks)
{% endstep %}

{% step %}

### Connect to a NWC Relay

[Connect to a NWC Relay](/bitcoin-lightning-wallets/nwc-relay)
{% endstep %}

{% step %}

### Ship your NWC wallet service 🚀

Get listed on [NWC.dev](https://nwc.dev/) and [Awesome-NWC](https://github.com/getAlby/awesome-nwc)
{% endstep %}
{% endstepper %}


# Code Examples

Fast-track your NWC integration with these examples

## Example Web TypeScript Project <a href="#sample-typescript-project" id="sample-typescript-project"></a>

### Install the SDK

```
npm install @getalby/sdk
```

or

```javascript
yarn add @getalby/sdk
```

## Examples

```typescript
import { nwc } from "@getalby/sdk";

// setup the wallet service for your preferred relay
const walletService = new nwc.NWCWalletService({
  relayUrl: "wss://relay.getalby.com/v1",
});

// for each client/app connection you can publish a NIP-47
// info event and subscribe to requests
await walletService.publishWalletServiceInfoEvent(
  walletServiceSecretKey,
  ["get_info"], // NIP-47 methods supported by your wallet service
  [],
);

// each client app connection will have a unique keypair
const keypair = new nwc.NWCWalletServiceKeyPair(
  walletServiceSecretKey,
  clientPubkey,
);

// subscribe to and handle requests for each client app
const unsub = await walletService.subscribe(keypair, {
  getInfo: () => {
    return Promise.resolve({
      result: {
        methods: ["get_info"], // NIP-47 methods supported by your wallet service
        //... add other fields here
      },
      error: undefined,
    });
  },
  // ... handle other NIP-47 methods here
});
```


# NWC Relay

## Running or connecting to a relay

Relay servers route messages between client apps and wallets. NWC requires `relay` as an URL of the relay where the **wallet service** is connected and will be listening for events. &#x20;

There are four event kinds:

* `NIP-47 info event`: 13194
* `NIP-47 request`: 23194
* `NIP-47 response`: 23195
* `NIP-47 notification`: 23197 (and 23196: legacy NIP-04 notifications)

The info event should be a replaceable event that is published by the **wallet service** on the relay to indicate which commands it supports. The content should be a plaintext string with the supported commands, space-separated, eg. `pay_invoice` `get_balance`.

Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **user** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to.

The content of requests and responses is encrypted with [NIP04](https://github.com/nostr-protocol/nips/blob/master/04.md), and is a JSON-RPCish object with a semi-fixed structure:

**Request:**

```json
{
    "method": "pay_invoice", // method, string
    "params": { // params, object
        "invoice": "lnbc50n1..." // command-related data
    }
}
```

**Response:**

```json5
{
    "result_type": "pay_invoice", //indicates the structure of the result field
    "error": { //object, non-null in case of error
        "code": "UNAUTHORIZED", //string error code, see below
        "message": "human readable error message"
    },
    "result": { // result, object. null in case of error.
        "preimage": "0123456789abcdef..." // command-related data
    }
}
```

The `result_type` field MUST contain the name of the method that this event is responding to. The `error` field MUST contain a `message` field with a human readable error message and a `code` field with the error code if the command was not successful. If the command was successful, the `error` field must be null.

### Using a dedicated relay

NWC does not specify any requirements on the type of a [Nostr](https://github.com/nostr-protocol/nostr)-compatible relay. However, it makes sense to use a dedicated relay to prevent metadata leaks and improve reliability.\
Wallets can set up their own relay or leverage existing infrastructure listed [here](/bitcoin-lightning-wallets/references-and-sdks#relays).


# References & SDKs

Find SDKs and tools to implement NWC into your bitcoin lightning wallet

## Reference Implementation

* Alby: <https://github.com/getAlby/hub>
* Coinos: <https://github.com/coinos/coinos-server>

## SDKs

* [Javascript](https://github.com/getAlby/js-sdk?tab=readme-ov-file#nostr-wallet-connect-documentation)
* [Rust](https://github.com/rust-nostr/nostr)
* [Dart](https://pub.dev/packages/nwc)
* [Flutter](https://pub.dev/packages/ndk)
* [Python](https://github.com/supertestnet/python_nwc)

## NWC Relays&#x20;

[Alby NWC Relay](https://guides.getalby.com/developer-guide/nostr-wallet-connect-api/building-nwc-wallet-services/alby-nwc-relay) with a simple HTTP API open to wallets and lightning nodes ([get in contact](mailto:hello@getalby.com))


# Best Practices

Follow this page to learn about best practices as a wallet service developer

Configure permissions

Wallets should support the ability to configure connections directly from the wallet service (e.g. Alby Hub allows you to define permissions such read account balance and make payments)

<figure><img src="/files/6WSzIhZL7LrPI183h26Q" alt=""><figcaption><p>Manage access permissions example from Alby Hub</p></figcaption></figure>

### Set budgets

Users are going to link their wallet account to apps to send and receive payments natively in apps. Enabling your users to set budgets creates an efficient safety measure to not overspend.&#x20;

<figure><img src="/files/aj6zngENOfnV77qVWMoB" alt=""><figcaption><p>Manage budgets example from Alby Hub</p></figcaption></figure>

### Unique Keys

Use unique wallet keys for each connection. This keeps your user's activity across different apps completely separate.

### Sub-wallets

Sub-wallets allow your users to completely isolate their activity, so that apps can only see and access data and funds for that specific app.


# Overview

Overview of NWC supported methods

{% content-ref url="/pages/bATXstAN3IVi4IU6wF9u" %}
[get\_info](/reference-api/overview/get_info)
{% endcontent-ref %}

{% content-ref url="/pages/saO5PSpfc30zlM0EOVFh" %}
[get\_balance](/reference-api/overview/get_balance)
{% endcontent-ref %}

{% content-ref url="/pages/BY5hYtrPxOM9RlDK8A0l" %}
[make\_invoice](/reference-api/overview/make_invoice)
{% endcontent-ref %}

{% content-ref url="/pages/T9CXkwYBLiT7353t3RtD" %}
[pay\_invoice](/reference-api/overview/pay_invoice)
{% endcontent-ref %}

{% content-ref url="/pages/HTaOSiRVVYxoAFyjcQdg" %}
[multi\_pay\_invoice](/reference-api/overview/multi_pay_invoice)
{% endcontent-ref %}

{% content-ref url="/pages/mqqVRepR2HFbrRIMR12j" %}
[pay\_keysend](/reference-api/overview/pay_keysend)
{% endcontent-ref %}

{% content-ref url="/pages/EsPfhT5iN5TQzxcw3Iyd" %}
[lookup\_invoice](/reference-api/overview/lookup_invoice)
{% endcontent-ref %}

{% content-ref url="/pages/qBr5pAQPeIbUI7ibHKrb" %}
[list\_transactions](/reference-api/overview/list_transactions)
{% endcontent-ref %}


# get\_info

Get specific information about the wallet account

### **Use case**

The app requests specific information about the account from the wallet.

### **Request**

```json
{
    "method": "get_info",
    "params": {
    }
}
```

### **Response**

```json
{
    "result_type": "get_info",
    "result": {
            "alias": "string",
            "color": "hex string",
            "pubkey": "hex string",
            "network": "string", // mainnet, testnet, signet, or regtest
            "block_height": 1,
            "block_hash": "hex string",
            "methods": ["pay_invoice", "get_balance", "make_invoice", "lookup_invoice", "list_transactions", "get_info"], // list of supported methods for this connection
    }
}
```


# get\_balance

Request the balance of the wallet account

### **Use case**

The app requests the balance of the account from the wallet.

### **Request**

```json
{
    "method": "get_balance",
    "params": {
    }
}
```

### **Response**

```json
{
    "result_type": "get_balance",
    "result": {
        "balance": 10000, // user's balance in msats
    }
}
```


# make\_invoice

Request an invoice

### **Use case**

The app requests a [BOLT-11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md) invoice from the wallet.

### **Request**

```json
{
    "method": "make_invoice",
    "params": {
        "amount": 123, // value in msats
        "description": "string", // invoice's description, optional
        "description_hash": "string", // invoice's description hash, optional
        "expiry": 213 // expiry in seconds from time invoice is created, optional
    }
}
```

### **Response**

```json
 "result_type": "make_invoice",
    "result": {        
        "type": "incoming", // "incoming" for invoices, "outgoing" for payments
        "invoice": "string", // encoded invoice, optional
        "description": "string", // invoice's description, optional
        "description_hash": "string", // invoice's description hash, optional
        "preimage": "string", // payment's preimage, optional if unpaid
        "payment_hash": "string", // Payment hash for the payment
        "amount": 123, // value in msats
        "fees_paid": 123, // value in msats
        "created_at": unixtimestamp, // invoice/payment creation time
        "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable
        "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
    }
}
```


# pay\_invoice

Requests payment of an invoice.

### **Use case**

The app request a payment from a user by presenting a [BOLT-11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md) invoice to the wallet.

### **Request**

```json
{
    "method": "pay_invoice",
    "params": {
        "invoice": "lnbc50n1..." // bolt11 invoice
    }
}
```

### **Response**

```json
{
    "result_type": "pay_invoice",
    "result": { 
        "preimage": "0123456789abcdef..." // preimage of the payment
    }
}
```

### **Errors**

* `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.


# multi\_pay\_invoice

Request payment of multiple invoices.

### **Use case**

The app requests a payment of multiple [BOLT-11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md) invoices from the wallet.

### **Request**

```json
{
    "method": "multi_pay_invoice",
    "params": {
        "invoices": [
          {"invoice": lnbc1...", "amount": 123}, // bolt11 invoice and amount in msats, amount is optional
          {"invoice": lnbc50n1..."},
        ],
    }
}
```

### **Response**

For every invoice in the request, a separate response event is sent. To differentiate between the responses, each response event contains an `payment_hash` **tag** with the payment hash of the invoice it is responding to.

```json
{
    "result_type": "multi_pay_invoice",
    "result": {
        "preimage": "0123456789abcdef..." // preimage of the payment
    }
}
```

### **Errors**

* `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.


# pay\_keysend

### U**se case**

The app requests a [keysend](https://github.com/alexbosworth/keysend_protocols) payment from the wallet.

### **Request**

```json
{
    "method": "pay_keysend",
    "params": {
        "amount": 123, // invoice amount in msats, required
        "pubkey": "03...", // payee pubkey, required
        "preimage": "0123456789abcdef...", // preimage of the payment, optional
        "tlv_records: [ // tlv records, optional
            {
                "type": 5482373484, // tlv type
                "value": "0123456789abcdef" // hex encoded tlv value
            }
        ]
    }
}
```

### **Response**

```json
{
    "result_type": "pay_keysend",
    "result": {
        "preimage": "0123456789abcdef...", // preimage of the payment
    }
}
```


# lookup\_invoice

Lookup data of a specific invoice

### **Use case**

The app requests to lookup a [BOLT-11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md) invoice from the wallet.

### **Request**

```json
{ 
    "method": "lookup_invoice",
    "params": {
        "payment_hash": "31afdf1..", // payment hash of the invoice, one of payment_hash or invoice is required
        "invoice": "lnbc50n1..." // invoice to lookup
            }
}
```

### **Response**

```json
{
    "result_type": "lookup_invoice",
    "result": {
        "type": "incoming", // "incoming" for invoices, "outgoing" for payments
        "invoice": "string", // encoded invoice, optional
        "description": "string", // invoice's description, optional
        "description_hash": "string", // invoice's description hash, optional
        "preimage": "string", // payment's preimage, optional if unpaid
        "payment_hash": "string", // Payment hash for the payment
        "amount": 123, // value in msats
        "fees_paid": 123, // value in msats
        "created_at": unixtimestamp, // invoice/payment creation time
        "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable
        "settled_at": unixtimestamp, // invoice/payment settlement time, optional if unpaid
        "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
    }
}
```


# list\_transactions

List invoices and payments.

### **Use case**

The app asks for a list of invoices and payments.&#x20;

### **Request**

```json
{
    "method": "list_transactions",
    "params": {
        "from": 1693876973, // starting timestamp in seconds since epoch (inclusive), optional
        "until": 1703225078, // ending timestamp in seconds since epoch (inclusive), optional
        "limit": 10, // maximum number of invoices to return, optional
        "offset": 0, // offset of the first invoice to return, optional
        "unpaid": true, // include unpaid invoices, optional, default false
        "type": "incoming", // "incoming" for invoices, "outgoing" for payments, undefined for both
    }
}
```

### **Response**

If `type` is not specified, both invoices and payments are returned. The `from` and `until` parameters are timestamps in seconds since epoch. If `from` is not specified, it defaults to 0. If `until` is not specified, it defaults to the current time. Transactions are returned in descending order of creation time.

```json
{
    "result_type": "list_transactions",
    "result": {
        "transactions": [
            {
               "type": "incoming", // "incoming" for invoices, "outgoing" for payments
               "invoice": "string", // encoded invoice, optional
               "description": "string", // invoice's description, optional
               "description_hash": "string", // invoice's description hash, optional
               "preimage": "string", // payment's preimage, optional if unpaid
               "payment_hash": "string", // Payment hash for the payment
               "amount": 123, // value in msats
               "fees_paid": 123, // value in msats
               "created_at": unixtimestamp, // invoice/payment creation time
               "expires_at": unixtimestamp, // invoice expiration time, optional if not applicable
               "settled_at": unixtimestamp, // invoice/payment settlement time, optional if unpaid
               "metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
           }
        ],
    },
}
```


# Error Codes

List of error codes

* `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds.
* `NOT_IMPLEMENTED`: The command is not known or is intentionally not implemented.
* `INSUFFICIENT_BALANCE`: The wallet does not have enough funds to cover a fee reserve or the payment amount.
* `QUOTA_EXCEEDED`: The wallet has exceeded its spending quota.
* `RESTRICTED`: This public key is not allowed to do this operation.
* `UNAUTHORIZED`: This public key has no wallet connected.
* `INTERNAL`: An internal error. Examples:
  * some required service is down which caused the request to fail,&#x20;
  * failure to save something to the database,&#x20;
  * some unexpected error occurred while processing a request.
* `OTHER`: Other error.

Please, [join the Discord community](https://discord.nwc.dev/) or [reach out](mailto:hello@getalby.com) directly if you encounter unknown errors or other problems during the implementation.


# Specification

This page contains the official specification of NWC

{% embed url="<https://github.com/nostr-protocol/nips/blob/master/47.md>" %}


# Design Assets

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>NWC logo</strong></td><td>Use this logo on light backgrounds</td><td><a href="https://www.figma.com/community/file/1335050217979045629">Download</a></td><td><a href="/files/MJrRbvjTbQVlmcPDvNEm">/files/MJrRbvjTbQVlmcPDvNEm</a></td></tr><tr><td><strong>NWC logo</strong></td><td>Use this logo on dark backgrounds</td><td><a href="https://www.figma.com/community/file/1335050217979045629">Download</a></td><td><a href="/files/2qFPjNdpGwZbf7T5ARS9">/files/2qFPjNdpGwZbf7T5ARS9</a></td></tr></tbody></table>


