A lightweight JavaScript/TypeScript library for facilitating communication between a host application and a client widget, with support for Nostr account metadata and event handling via window.postMessage. Ideal for building smart widgets that interact with Nostr-based ecosystems.
Install the package via npm:
npm install smart-widget-handlerThe library provides two main interfaces: host for the parent application and client for the embedded widget. Import the default export SWHandler to send and receive messages between contexts.
Example: Host Sending and Listening Send a connected Nostr account to a widget and listen for messages from the widget:
import SWHandler from "smart-widget-handler";
// Listen for messages from the widget
let listener = SWHandler.host.listen((data) => {
console.log("Received from widget:", data.kind, data.data);
if (data.kind === "custom-data") {
console.log("Custom data:", data.data);
}
});
// To close the listener
listener.close()
// Send user context to the widget
const context = {
pubkey: "npub1example...",
display_name: "string",
name: "string",
picture: "string",
nip05: "string",
lud16: "string",
lud06: "string",
website: "string",
};
let host_origin: "https://myapp.com";
SWHandler.host.sendContext(context, host_origin, "https://widget.example.com", <YOUR_IFRAME_ELEMENT>);Notify the host that the widget is ready, listen for messages, and send custom data:
import SWHandler from "smart-widget-handler";
// Notify host that widget is loaded
SWHandler.client.ready();
// Listen for messages from the host
let listener = SWHandler.client.listen((data) => {
console.log("Received from host:", data.kind, data.data);
if (data.kind === "user-metadata") {
const { display_name } = data.data;
console.log(`Hello, ${display_name}!`);
}
});
// To close the listener
listener.close();
// Send custom data to the host
SWHandler.client.sendContext("User clicked a button", "https://myapp.com");Request the host to sign a Nostr event:
import SWHandler from "smart-widget-handler";
const event = {
content: "Hello, Nostr!",
tags: [["t", "greeting"]],
kind: 1,
};
SWHandler.client.requestEventSign(event, "https://myapp.com");Request the host to initiate a Lightning payment:
import SWHandler from "smart-widget-handler";
const paymentRequest = {
address: "lnbc1...", // or LNURL, or Lightning address
amount: 1000, // sats (ignored if address is a BOLT11 invoice)
nostrPubkey: "npub1example...", // optional
nostrEventIDEncode: "note1example...", // optional
};
SWHandler.client.requestPayment(paymentRequest, "https://myapp.com");Send a payment response from the host to the client:
import SWHandler from "smart-widget-handler";
const paymentResponse = {
status: true, // true for success, false for error
preImage: "abcdef123456...", // optional, only for successful payments
};
SWHandler.host.sendPaymentResponse(paymentResponse, "https://widget.example.com", <YOUR_IFRAME_ELEMENT>);The library uses different message types identified by the data.kind property to handle various communication scenarios between host and client. Here's a comprehensive list of all available message types:
| Message Type | Direction | Description |
|---|---|---|
user-metadata |
Host → Client | Contains Nostr account information of the connected user |
nostr-event |
Host → Client | Contains a signed and/or published Nostr event |
err-msg |
Host → Client | Contains an error message from the host |
payment-response |
Host → Client | Contains the result of a payment request (success/failure) |
app-loaded |
Client → Host | Notifies the host that the client widget is loaded and ready |
sign-event |
Client → Host | Requests the host to sign a Nostr event |
sign-publish |
Client → Host | Requests the host to sign and publish a Nostr event |
payment-request |
Client → Host | Requests the host to make a Lightning payment |
custom-data |
Client → Host | Contains custom data sent from the client to the host |
When implementing listeners with SWHandler.host.listen() or SWHandler.client.listen(), you can filter and handle these message types based on your application's needs.