Alby Developer Guide
User GuideDeveloper Portal
NWC API
NWC API
  • Introduction
    • ❔What is Nostr Wallet Connect?
  • Building Lightning Apps
    • ⛓️NWC HTTP API
      • ℹ️Fetch NWC Info
      • 📢Publish NWC Request
      • ✍️Publish Event
      • 📩Subscribe to Events
      • 🔔Subscribe to NWC Notifications
      • 🔕Delete Subscriptions
      • ↔️Code examples: Creating Requests
    • ⚡NWC JS SDK
  • Building NWC Wallet Services
    • 🗼Alby NWC Relay
Powered by GitBook
LogoLogo

Our content

  • Website
  • Blog
  • GitHub

Follow us

  • Nostr
  • Twitter / X
  • Youtube

Contact us

  • E-mail
  • Community Chat
  • Open Hours

Your bitcoin & nostr companion / from 🐝 with 🧡

On this page
  • Prerequisites
  • Code Example

Was this helpful?

  1. Building Lightning Apps
  2. NWC HTTP API

Code examples: Creating Requests

Last updated 12 months ago

Was this helpful?

Below is an example demonstrating how to

  1. Create a Request Event (NIP-47)

  2. Sign it using Shared Secret (from Pubkey and Secret in NWC string)

  3. Send it to the API endpoint and receive the Response Event

  4. And finally decrypting the content in the response using the Shared Secret

Prerequisites

Before you begin, ensure you have the necessary packages installed:

yarn add node-fetch
yarn add nostr-tools
go get github.com/nbd-wtf/go-nostr
go get github.com/nbd-wtf/go-nostr/nip04

You also need a NWC connection string for testing:

  1. Get an Alby Account with .

  2. Create your NWC connection string at .

Code Example

import fetch from 'node-fetch'
import { hexToBytes } from '@noble/hashes/utils';
import { nip04, finalizeEvent } from 'nostr-tools'

async function main() {
  const nwcString = "nostr+walletconnect://69effe7b49a6dd5cf525bd0905917a5005ffe480b58eeb8e861418cf3ae760d9?relay=wss://relay.getalby.com/v1&secret=05800d24907112b01a07a745c33de84f565fd1c7938578a120ef7d522e0972d7&lud16=adithya@getalby.com";

  const url = new URL(nwcString);
  const pubkey = url.hostname;
  const secret = url.searchParams.get('secret');

  const jsonStr = JSON.stringify({
    method: "get_balance"
  });

  const payload = await nip04.encrypt(secret, pubkey, jsonStr);

  const event = {
    created_at: Math.floor(Date.now() / 1000),
    kind: 23194, // REQUEST_KIND
    tags: [['p', pubkey]],
    content: payload,
  };

  const postPayload = {
    walletPubkey: pubkey,
    event: finalizeEvent(event, hexToBytes(secret)),
  };

  try {
    const response = await fetch("https://api.getalby.com/nwc/nip47", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(postPayload),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    const content = result.content;

    const decryptedContent = await nip04.decrypt(secret, pubkey, content);
    console.log(decryptedContent);
    // {"result":{"balance":2121212121,"max_amount":100000000,"budget_renewal":"monthly"},"result_type":"get_balance"}


  } catch (error) {
    console.error('Error:', error);
  }
}

main()
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"

	"github.com/nbd-wtf/go-nostr"
	"github.com/nbd-wtf/go-nostr/nip04"
)

func main() {
	// Extract the pubkey and secret from the nwc connection string
	nwcString := "your-nwc-connection-string"

	parsedString, err := url.Parse(nwcString)
	if err != nil {
		fmt.Println("Error parsing URL:", err)
		return
	}
	pubkey := strings.TrimPrefix(parsedString.Host, "")
	secret := parsedString.Query().Get("secret")

	// Compute the shared secret using the pubkey and secret
	ss, err := nip04.ComputeSharedSecret(pubkey, secret)
	if err != nil {
		fmt.Println("Error computing secret:", err)
		return
	}

	// Encrypt the JSON request payload using the shared secret
	payload, err := nip04.Encrypt(`{
		"method": "get_balance"
	}`, ss)
	if err != nil {
		fmt.Println("Error encrypting JSON:", err)
		return
	}

	// Prepare the nostr event to make the NWC request
	req := &nostr.Event{
		PubKey:    pubkey,
		CreatedAt: nostr.Now(),
		Kind:      23194, // REQUEST_KIND
		Tags:      nostr.Tags{[]string{"p", pubkey}},
		Content:   payload,
	}

	// Sign it with the secret
	err = req.Sign(secret)
	if err != nil {
		fmt.Println("Error signing request event:", err)
		return
	}

	// Prepare the payload for the HTTP POST request using the signed event
	postPayload := map[string]interface{}{
		"walletPubkey": pubkey,
		"event":        req,
	}
	postPayloadJSON, err := json.Marshal(postPayload)
	if err != nil {
		fmt.Println("Error marshaling post payload:", err)
		return
	}

	// Make the HTTP POST request
	resp, err := http.Post("https://api.getalby.com/nwc/nip47", "application/json", bytes.NewBuffer(postPayloadJSON))
	if err != nil {
		fmt.Println("Error making POST request:", err)
		return
	}
	defer resp.Body.Close()

	// Print response
	var result map[string]interface{}
	err = json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		fmt.Println("Error decoding response:", err)
		return
	}

	content, ok := result["content"].(string)
	if !ok {
		fmt.Println("Error: content not found or is not a string")
		return
	}

	// Decrypt the content using the shared secret
	content, _ = nip04.Decrypt(content, ss)
	fmt.Println(content)
	// {"result":{"balance":2121212121,"max_amount":100000000,"budget_renewal":"monthly"},"result_type":"get_balance"}
}

⛓️
↔️
this link
nwc.getalby.com