Skip to content

Instantly share code, notes, and snippets.

@jasl
Last active March 25, 2025 22:56
Show Gist options
  • Save jasl/0e35a5d903c3de8dbe1d1c264389457d to your computer and use it in GitHub Desktop.
Save jasl/0e35a5d903c3de8dbe1d1c264389457d to your computer and use it in GitHub Desktop.
DePHY Messaging layer pub & sub example

DePHY Messaging layer integration

Highlights

  • NoStr-based federated decentrailized network
  • Acts as message queue, allowing pub/sub programming model
  • Design for
    • Decentralized devices&softwares communication
    • Web3-friendly Billing and metering
  • HTTP API for easy sending message

NoStr protocol basis

See https://github.com/nostr-protocol/nips/blob/master/01.md

DePHY message (event) sample

DePHY Messaging layer only accepts message with kind 1573

{
  kind: 1573, // Constant
  created_at: 1742052212, // Timestamp in seconds
  tags: [
    [ "s", "0" ], // Required, use for distinguish conversations, could be any string 
    [ "p", "6f7bb11c04d792784c9dfcb4246e9afc0d6a7eae549531c2fce51adf09b2887e" ] // Optional, the hexified recipient SECP256k1 pubkey
  ],
  content: "Ping", // Data
  pubkey: "8275a3b63fcf95d195121eb7703df11a8955cfdc39c2b79b83fae5c88cfdb52d", // The hexified message sender SECP256k1 pubkey
  id: "b9189e364839a682f2bb9d163d49a6d2dcb9dc49513424a7da5074f62b10a459", // Calatulated by the event, see NoStr protocol basis
  sig: "616d5dc06417d455a04ac7bf388bd415b58afbdfcf5a4f5043f51c8578bb3b5dc556d2cf9161bcd04bf926d235fd731df69cae595fe64ff3e5944c41e0007b73" // Calatulated by the event, see NoStr protocol basis
}

Integration

  • Generate SECP256k1 for each senders (nodes)
  • See <publish_message.js> to know how to send message via HTTP API
  • See <subscribe_messages.js> to know how to subscribe messages via NoStr WebSocket RPC

Message explorer

https://dephy-node-nostr-explorer.pages.dev/relay/dev-relay.dephy.dev

// Use a standard NoStr client, but this is not required because the NoStr event is super easy to construct
import { generateSecretKey, getPublicKey, finalizeEvent, verifyEvent } from "nostr-tools/pure";
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
// Hardcode sender SECP256k1 private key, each sender should has different unique private key as identity
const senderSecretKey = hexToBytes("c885648cc3e4c94fe00b74111247d15ebe35640f7973d8b9f839ced49e3706d5") // generateSecretKey()
// Hardcode recipient SECP256k1 public key, so you can subscribe new messages by the recipient
const recipient = "6f7bb11c04d792784c9dfcb4246e9afc0d6a7eae549531c2fce51adf09b2887e"
let event = finalizeEvent({
kind: 1573,
created_at: Math.floor(Date.now() / 1000),
tags: [["s", "0"], ["p", recipient]],
// Content must be string, size limit in 2KiB, Blob and Json can serialize first
content: JSON.stringify({
foo: "bar",
hello: "world",
}),
}, senderSecretKey)
// A brief preview for the NoStr event
console.log(event);
// This is one of our preview Relay federation
const rpcHost = "https://dev-relay.dephy.dev"
// Publish the message
const resp = await fetch(`${rpcHost}/events`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(event),
})
// Response status should be 200 if everything good, otherwise 400
console.log(resp.status)
// If response status not 400, the body will contains an error message
console.log(await resp.text())
import { Relay } from "nostr-tools/relay";
// Hardcode recipient SECP256k1 public key, which is used in the publish message example
const recipient = "6f7bb11c04d792784c9dfcb4246e9afc0d6a7eae549531c2fce51adf09b2887e"
// This is one of our preview Relay federation, the same as in the publish message example
const relayUrl = "https://dev-relay.dephy.dev"
const relay = await Relay.connect(relayUrl);
console.log(`Listening on ${relay.url}`);
// Subscribe new messages from relay
relay.subscribe(
[
{
kinds: [1573],
since: Math.floor(Date.now() / 1000),
"#p": [recipient], // Subscrbe the exact recipient
},
],
{
onevent: async (event) => {
console.log(event)
},
oneose() {
// console.log("Got eose"); // Used to indicate the end of stored events and the beginning of events newly received in real-time.
},
onclose(reason) {
console.log("Closed:", reason);
},
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment