From c8223908c172a4eec4399174aa86044c5540597c Mon Sep 17 00:00:00 2001 From: Joachim Happel Date: Mon, 12 Aug 2024 19:38:09 +0200 Subject: [PATCH] initial --- .gitignore | 2 ++ README.md | 25 ++++++++++++++ createEventTextNote.js | 33 ++++++++++++++++++ generateKeys.js | 16 +++++++++ listen.js | 75 ++++++++++++++++++++++++++++++++++++++++ package.json | 17 +++++++++ send.js | 39 +++++++++++++++++++++ yarn.lock | 78 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 285 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 createEventTextNote.js create mode 100644 generateKeys.js create mode 100644 listen.js create mode 100644 package.json create mode 100644 send.js create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25c8fdb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d3162e0 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Nostr Playgraound to SC24 + + Prepare the environment by installing a docker container with the Nostr relay server. + + ```shell + docker pull scsibug/nostr-rs-relay + docker run -p 7000:8080 scsibug/nostr-rs-relay +``` + + Install the necessary dependencies by running the following commands: + + ```shell +git clone https://git.rpi-virtuell.de/Comenius-Institut/nostr-oer-client +cd nostr-oer-client +npm install +``` + + Run the script on your shell with the following command: `node listen.js` + This script listens for new messages on the Nostr network. + It connects to a Nostr relay server and subscribes to text notes/messages. + When a new message is received, it prints the message content, sender's public key, and timestamp. + + Test with the send.js script to send a message. + run the send.js script with the following command: `node send.js` + \ No newline at end of file diff --git a/createEventTextNote.js b/createEventTextNote.js new file mode 100644 index 0000000..b56fffe --- /dev/null +++ b/createEventTextNote.js @@ -0,0 +1,33 @@ +import { finalizeEvent, getEventHash, getPublicKey } from 'nostr-tools' + +const skHex = 'e8913a0b983c8678e3cce83a45ace14f6656bd06ff98803a38d72a5567e7e105' + +const event = { + kind: 1, + created_at: Math.floor(Date.now() / 1000), + tags: [], + content: 'Hello world! Welcome to SC24!', + pubkey: getPublicKey(skHex) +} + +event.id = getEventHash(event) +event.sig = finalizeEvent(event, skHex) + +const signedEvent = ['EVENT', event] + +function getCircularReplacer() { + const seen = new WeakSet(); + return (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; //zyklische Referenzen lassen sich nicht anzeigen + } + seen.add(value); + } + return value; + }; +} + +console.log( + JSON.stringify(signedEvent, getCircularReplacer(), 2) // 2 für schönere Einrückung +) diff --git a/generateKeys.js b/generateKeys.js new file mode 100644 index 0000000..5d0a3f0 --- /dev/null +++ b/generateKeys.js @@ -0,0 +1,16 @@ +/** + * This script generates a secret key and a public key. + * to run this script, use the following command: node generateKeys.js + */ +import { bytesToHex, hexToBytes } from '@noble/hashes/utils' +import { generateSecretKey, getPublicKey } from 'nostr-tools/pure' + +const secretKey = generateSecretKey(); +const publicKey = getPublicKey(secretKey); + + +let skHex = bytesToHex(secretKey) +let backToBytes = hexToBytes(skHex) + +console.log('your sekret key:', skHex) +console.log('your public key = ', publicKey); diff --git a/listen.js b/listen.js new file mode 100644 index 0000000..b346259 --- /dev/null +++ b/listen.js @@ -0,0 +1,75 @@ +/** + * Prepare the environment by installing a docker container with the Nostr relay server. + * docker pull scsibug/nostr-rs-relay + * docker run -p 7000:8080 scsibug/nostr-rs-relay + * + * Install the necessary dependencies by running the following command: + * npm install + * + * Run the script with the following command: node listen.js + * This script listens for new messages on the Nostr network. + * It connects to a Nostr relay server and subscribes to text notes/messages. + * When a new message is received, it prints the message content, sender's public key, and timestamp. + * + * Test with the send.js script to send a message. + * run the send.js script with the following command: node send.js + */ + + +import { Relay } from 'nostr-tools/relay' +import { verifyEvent } from 'nostr-tools/pure' + +// If not running in Node.js, comment the following 3 lines: +import WebSocket from 'ws' +import { useWebSocketImplementation } from 'nostr-tools/relay' +useWebSocketImplementation(WebSocket) + +const RELAY_URL = 'ws://localhost:7000' // Replace with your preferred relay + +async function listenForMessages() { + try { + const relay = await Relay.connect(RELAY_URL) + console.log(`Connected to ${relay.url}`) + + const sub = relay.subscribe( + [ + { + kinds: [1], // Listen for text notes/messages + since: Math.floor(Date.now() / 1000) // Only get new messages from now on + } + ], + { + onevent(event) { + if (verifyEvent(event)) { + console.log('New message received:') + console.log(`From: ${event.pubkey}`) + console.log(`Content: ${event.content}`) + console.log(`Timestamp: ${new Date(event.created_at * 1000).toLocaleString()}`) + console.log('---') + } else { + console.log('Received an invalid event') + } + }, + oneose() { + console.log('Subscription stream ended') + }, + onerror(error) { + console.error('Subscription error:', error) + } + } + ) + + // Keep the script running + process.on('SIGINT', () => { + console.log('Closing subscription and relay connection') + sub.close() + relay.close() + process.exit() + }) + + } catch (error) { + console.error('Error connecting to relay:', error) + } +} + +listenForMessages() \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..04f7f47 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "dependencies": { + "nostr-tools": "^2.7.2", + "ws": "^8.18.0" + }, + "name": "nostr-oer-client", + "type": "module", + "version": "1.0.0", + "main": "createEventTextNote.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "" +} diff --git a/send.js b/send.js new file mode 100644 index 0000000..61a8305 --- /dev/null +++ b/send.js @@ -0,0 +1,39 @@ +import { bytesToHex, hexToBytes } from '@noble/hashes/utils' // already an installed dependency +import { generateSecretKey, getPublicKey, finalizeEvent } from 'nostr-tools/pure' +import { Relay } from 'nostr-tools/relay' +import WebSocket from 'ws'; + +// Provide WebSocket implementation to nostr-tools +global.WebSocket = WebSocket; + +// Generate keys (or use existing ones) +//let secretKey = generateSecretKey() +//let pk = getPublicKey(secretKey) +//let sk = bytesToHex(secretKey) +let sk = 'e8913a0b983c8678e3cce83a45ace14f6656bd06ff98803a38d72a5567e7e105'; + + + +// Create event template +let eventTemplate = { + kind: 1, + created_at: Math.floor(Date.now() / 1000), + tags: [], + content: 'Hello world! Welcome to SC24!', +} + +// Finalize and sign the event +const signedEvent = finalizeEvent(eventTemplate, sk) + +// Connect to a relay and publish +async function publishMessage() { + const relay = await Relay.connect('ws://localhost:7000') + console.log(`connected to ${relay.url}`) + + await relay.publish(signedEvent) + console.log('Event published!') + + relay.close() +} + +publishMessage() \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..bbc473a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,78 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@noble/ciphers@^0.5.1": + version "0.5.3" + resolved "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz" + integrity sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w== + +"@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1", "@noble/hashes@1.3.1": + version "1.3.1" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@scure/base@~1.1.0", "@scure/base@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + +nostr-tools@^2.7.2: + version "2.7.2" + resolved "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.7.2.tgz" + integrity sha512-Bq3Ug0SZFtgtL1+0wCnAe8AJtI7yx/00/a2nUug9SkhfOwlKS92Tef12iCK9FdwXw+oFZWMtRnSwcLayQso+xA== + dependencies: + "@noble/ciphers" "^0.5.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.1" + "@scure/base" "1.1.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + optionalDependencies: + nostr-wasm v0.1.0 + +nostr-wasm@v0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz" + integrity sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA== + +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==