Smart widget builder

On this page



DOCS








Smart widget builder

A Node.js package for creating and managing Nostr Smart Widgets kind:30033. Build widgets that can be embedded in Nostr clients with interactive elements like buttons, inputs, and images.

Installation

npm install smart-widget-builder

or

yarn add smart-widget-builder

Overview

Smart Widget Builder helps you create standardized Nostr widgets kind:30033 with various components:

  • Images: Display images in your widget
  • Icons: Show icons (recommended for action/tool widgets)
  • Inputs: Add input fields for user data entry
  • Buttons: Create interactive buttons with different actions (redirect, nostr, zap, post, app)

The package supports three types of widgets:

  • Basic: Standard widgets with multiple components
  • Action: Simplified widgets for specific actions
  • Tool: Tool-type widgets for utility functions

Usage

Import

const { 
  SW, 
  SWComponentsSet, 
  Image, 
  Icon, 
  Input, 
  Button, 
  DEFAULT_RELAYS 
} = require('smart-widget-builder');

Basic Example

const { 
  SW, 
  SWComponentsSet, 
  Image, 
  Button, 
  Input 
} = require('smart-widget-builder');

// Create a widget and publish it
async function createBasicWidget() {
  try {
    // Create a new Smart Widget instance
    const smartWidget = new SW(
      'basic', // type: 'basic' | 'action' | 'tool'
      undefined, // use default relays
      import.meta.env.NOSTR_SECRET_KEY // your secret key, optional
    );
    
    // Initialize connection to relays
    await smartWidget.init();
    
    // Create widget components
    const widgetImage = new Image('https://example.com/my-widget-image.jpg');
    const widgetInput = new Input('Enter your name');
    const submitButton = new Button(1, 'Submit', 'post', 'https://api.example.com/submit');
    const profileButton = new Button(2, 'View Profile', 'nostr', 'nostr:npub1...');
    
    // Combine components into a set
    const componentsSet = new SWComponentsSet(
      [widgetImage, widgetInput, submitButton, profileButton],
      smartWidget
    );
    
    // Publish the widget
    const result = await smartWidget.publish(
      componentsSet,
      'My First Smart Widget',
      'unique-identifier-123', // optional
      5000 // timeout in ms
    );
    
    // Get the naddr (Nostr address) for sharing
    console.log('Widget created successfully!');
    console.log('Nostr Address:', result.naddr);
    console.log('Event ID:', result.event.id);
    
    return result;
  } catch (err) {
    console.error('Error creating widget:', err.message);
    throw err;
  }
}

// Run the function
createBasicWidget()
  .then(result => {
    console.log('Widget creation complete');
  })
  .catch(err => {
    console.error('Failed to create widget:', err);
  });

Components API

Smart Widget (SW)

The main class for creating and managing widget instances.

// Create a new Smart Widget
const smartWidget = new SW(
  'basic',                  // Widget type ('basic', 'action', or 'tool')
  ['wss://relay1.com'],     // Optional custom relay set
  'your-hex-secret-key'     // Optional secret key for signing
);

// Initialize connection to relays (required before publishing)
await smartWidget.init();

Image Component

Main visual element for the widget.

// Create an image component
const widgetImage = new Image('https://example.com/image.jpg');

// Can also use data URLs
const dataUrlImage = new Image('data:image/png;base64,iVBORw0KGgo...');

Icon Component

A 1:1 ratio icon image (required for 'action' and 'tool' widget types).

// Create an icon component
const widgetIcon = new Icon('https://example.com/icon.png');

Input Component

Text input field for user data entry.

// Create an input component with placeholder/label
const widgetInput = new Input('Enter your search term...');

Button Component

Interactive button for taking actions.

// Create button components
// Format: index, label, type, url

// Regular link button
const linkButton = new Button(1, 'Visit Site', 'redirect', 'https://example.com');

// Nostr action button (can use nostr: URLs or npub/note/etc identifiers)
const nostrButton = new Button(2, 'View Profile', 'nostr', 'nostr:npub1...');

// Zap button (accepts Lightning addresses)
const zapButton = new Button(3, 'Zap Me', 'zap', 'user@lightning.address');

// Post data button
const postButton = new Button(4, 'Submit', 'post', 'https://api.example.com/endpoint');

// App action button
const appButton = new Button(5, 'Open App', 'app', 'https://app.example.com');

Component Set

Group components together to form a complete widget.

// Create a components set
const componentsSet = new SWComponentsSet(
  [widgetImage, widgetIcon, widgetInput, linkButton, nostrButton],
  smartWidget  // The SW instance
);

Publishing Widgets

Publish a widget to Nostr relays:

// Publish the widget to relays
const result = await smartWidget.publish(
  componentsSet,           // SWComponentsSet instance
  'My Widget Title',       // Optional title
  'unique-identifier',     // Optional unique identifier
  5000                     // Optional timeout in milliseconds
);

console.log('Widget published!');
console.log('Event ID:', result.event.id);
console.log('Nostr Address:', result.naddr);

Signing Without Publishing

Sign a widget event without publishing:

// Just sign the event without publishing
const signedEvent = await smartWidget.signEvent(
  componentsSet,           // SWComponentsSet instance
  'My Widget Title',       // Optional title
  'unique-identifier'      // Optional unique identifier
);

console.log('Signed event:', signedEvent.event);
console.log('Nostr Address:', signedEvent.naddr);

Searching In Nostr

Search Nostr for widgets or other events:

// Example: search for widgets with a specific tag
const results = await smartWidget.searchNostr([
  {
    kinds: [30033],
    "#t": ["widget"]
  }
]);

console.log('Found events:', results.data);
console.log('Related pubkeys:', results.pubkeys);

Widget Types and Constraints

Different widget types have different component constraints:

Basic Widget

  • Required: 1 Image component
  • Optional: Up to 1 Input component
  • Optional: Up to 6 Button components with consecutive indices

Action/Tool Widget

  • Required: 1 Image component
  • Required: 1 Icon component
  • Special case: 1 Button of type 'app'

API Reference

SW (Smart Widget)

MethodDescriptionParameters
constructor(type, relaySet, secretKey)Create a new widget instancetype: Widget type ('basic', 'action', 'tool')
relaySet: Array of relay URLs (optional)
secretKey: Hex private key (optional)
init()Initialize connection to relaysNone
getProps()Get widget instance propertiesNone
publish(components, title, identifier, timeout)Publish widget to relayscomponents: SWComponentsSet instance
title: Widget title (optional)
identifier: Unique ID (optional)
timeout: Timeout in ms (optional)
signEvent(components, title, identifier)Sign event without publishingcomponents: SWComponentsSet instance
title: Widget title (optional)
identifier: Unique ID (optional)
searchNostr(filter)Search Nostr for eventsfilter: Nostr filter array

Components

ComponentConstructorDescription
Image(url)url: Image URLMain widget image
Icon(url)url: Icon URL1:1 icon (for action/tool widgets)
Input(label)label: Input label/placeholderText input field
Button(index, label, type, url)index: Position (1-6)
label: Button text
type: Button type
url: Target URL
Interactive button
SWComponentsSet(components, swInstance)components: Array of components
swInstance: SW instance
Group of widget components

Button Types

TypeDescriptionURL Format
redirectStandard linkhttp:// or https:// URL
nostrNostr actionnostr: URL or npub/note/etc
zapLightning paymentEmail address or lnurl/lnbc
postForm submissionhttp:// or https:// endpoint
appApp integrationhttp:// or https:// URL

Configuration

Create a .env file for the secret key, this will be used as a fallback if the SW() constructor was not provided with one to sign and publish event

SECRET_KEY=your-hex-secret-key

On this page