initial
This commit is contained in:
commit
c8223908c1
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
25
README.md
Normal file
25
README.md
Normal file
|
@ -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`
|
||||||
|
|
33
createEventTextNote.js
Normal file
33
createEventTextNote.js
Normal file
|
@ -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
|
||||||
|
)
|
16
generateKeys.js
Normal file
16
generateKeys.js
Normal file
|
@ -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);
|
75
listen.js
Normal file
75
listen.js
Normal file
|
@ -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()
|
17
package.json
Normal file
17
package.json
Normal file
|
@ -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": ""
|
||||||
|
}
|
39
send.js
Normal file
39
send.js
Normal file
|
@ -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()
|
78
yarn.lock
Normal file
78
yarn.lock
Normal file
|
@ -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==
|
Loading…
Reference in a new issue