Introduction
Build widgets
SDK
Useful links
Search
/
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)
| Method | Description | Parameters |
|---|---|---|
constructor(type, relaySet, secretKey) | Create a new widget instance | type: Widget type ('basic', 'action', 'tool')relaySet: Array of relay URLs (optional)secretKey: Hex private key (optional) |
init() | Initialize connection to relays | None |
getProps() | Get widget instance properties | None |
publish(components, title, identifier, timeout) | Publish widget to relays | components: SWComponentsSet instancetitle: Widget title (optional)identifier: Unique ID (optional)timeout: Timeout in ms (optional) |
signEvent(components, title, identifier) | Sign event without publishing | components: SWComponentsSet instancetitle: Widget title (optional)identifier: Unique ID (optional) |
searchNostr(filter) | Search Nostr for events | filter: Nostr filter array |
Components
| Component | Constructor | Description |
|---|---|---|
Image(url) | url: Image URL | Main widget image |
Icon(url) | url: Icon URL | 1:1 icon (for action/tool widgets) |
Input(label) | label: Input label/placeholder | Text input field |
Button(index, label, type, url) | index: Position (1-6)label: Button texttype: Button typeurl: Target URL | Interactive button |
SWComponentsSet(components, swInstance) | components: Array of componentsswInstance: SW instance | Group of widget components |
Button Types
| Type | Description | URL Format |
|---|---|---|
redirect | Standard link | http:// or https:// URL |
nostr | Nostr action | nostr: URL or npub/note/etc |
zap | Lightning payment | Email address or lnurl/lnbc |
post | Form submission | http:// or https:// endpoint |
app | App integration | http:// 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