Last active
September 5, 2024 15:06
-
-
Save starbackr-dev/b753e9c1c28fc62a3356960d02a7e3a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {WebSocket} = require('websocket-polyfill'); | |
const {relayInit, | |
getEventHash, | |
getPublicKey, | |
verifySignature, | |
signEvent, | |
generatePrivateKey} = require('nostr-tools'); | |
const https = require('https'); | |
//********* Constants ********************************************************************** | |
const regUserPrivateKey = 'c776822b744112daeb279a7616650d87124df3c04fc16d3a08a4e3a68f7042d3'; | |
const newUserPrivateKey = generatePrivateKey(); | |
const relay_url = 'wss://spool.chat'; | |
const relay_pubkey = '805efff537b6376991cae73a0b0f605d0aa594b4518fbcca4f6ebb74404363e2'; | |
const groupSlug = '/nostrdevs-gpUNoQ7CLjQ'; | |
//******************************************************************************************* | |
let connectStatus = false; | |
let relay = relayInit(relay_url); | |
let groupSlug1= groupSlug; //groupSlug + '-' + makeid(12); | |
let subgroupSlug = groupSlug1+ '/subgroup'; | |
//1. Create a group | |
const createGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 1. create a group with name and confirm relay is creating the group and verify the event generated by the relay: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9000, | |
tags: [['g', groupSlug1], | |
['action', 'name', 'This is a super shadowy group'], | |
['action', 'picture', 'https://i.current.fyi/npub1current/profile/current.png'], | |
], | |
content: 'Test group ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//2. Post message to the group | |
const postMessageToGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 2. Post a message to relay and confirm relay is allowing the user to post messages to the group: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9, | |
tags: [['g', groupSlug1]], | |
content: 'I am posting my message to the group: ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//3. New user joins the group | |
const newUserJoinsGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 3. New user joining the group \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9000, | |
tags: [['g', groupSlug1], | |
['action', 'add', getPublicKey(newUserPrivateKey), 'user'], | |
], | |
content: 'This is content' | |
}; | |
postGroupEventToRelay(postevent, newUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//4. Post message as new user to the group | |
const postMessageAsNewUserToGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 4. Post a message to relay and confirm relay is allowing the user to post messages to the group: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9, | |
tags: [['g', groupSlug1]], | |
content: 'Hello from new user: ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent, newUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//5. New user leaves the group | |
const newUserLeaveGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 5. New user leaving the group \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9000, | |
tags: [['g', groupSlug1], | |
['action', 'remove', getPublicKey(newUserPrivateKey), 'user'], | |
], | |
content: 'this is content' | |
}; | |
postGroupEventToRelay(postevent, newUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//6. Create a Sub group | |
const createSubGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 6. create a sub group with name and confirm relay is creating the group and verify the event generated by the relay: \x1b[0m ', subgroupSlug ); | |
let postevent = { | |
kind: 9000, | |
tags: [ | |
['g', subgroupSlug], | |
['action', 'name', 'This is a super shadowy sub group'], | |
['action', 'picture', 'https://i.current.fyi/npub1current/profile/current.png'], | |
], | |
content: 'Creating subgroup ' + subgroupSlug | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//7. Post message to the sub group | |
const postMessageToSubGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 7. Post a message to subgroup and confirm relay is allowing the user to post messages to the subgroup: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9, | |
tags: [['g', subgroupSlug]], | |
content: 'I am posting my message to the subgroup: ' + subgroupSlug | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//8. Admin adds a user to the group | |
const adminAddsUserGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 8. Group admin adds an user to the group: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9000, | |
tags: [['g', groupSlug1], | |
['action', 'add', getPublicKey(newUserPrivateKey), 'user'] | |
], | |
content: 'Adding user to the group ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//9. Admin removes a user to the group | |
const adminRemovesUserGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 9. Group admin adds an user to the group: \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9000, | |
tags: [['g', groupSlug1], | |
['action', 'remove', getPublicKey(newUserPrivateKey), 'user'] | |
], | |
content: 'Removing user to the group ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent,regUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//10. User tries to message the group but fails since removed by the admin | |
const userMessageFailGroup = async () => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 10. User tries to message the group but fails since removed by the admin \x1b[0m', groupSlug1 ); | |
let postevent = { | |
kind: 9, | |
tags: [['g', groupSlug1]], | |
content: 'Hello from new user again: ' + groupSlug1 | |
}; | |
postGroupEventToRelay(postevent, newUserPrivateKey).then((result) => {resolve(true)}); | |
}); | |
} | |
//11. Get all subscribed groups for a pubkey | |
const get39004Event = async (relay) => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 11. Get all subscribed groups for a pubkey \x1b[0m', getPublicKey(regUserPrivateKey) ); | |
let sub = relay.sub([ | |
{ | |
limit: 1, | |
kinds: [39004], | |
'#p': [getPublicKey(regUserPrivateKey)], | |
} | |
]) | |
sub.on('event', event => { | |
console.log('event: ', event); | |
}) | |
sub.on('eose', () => { | |
resolve(true); | |
}) | |
}); | |
} | |
//12. Get all messages for a group '/nostrdevs-oOXekJwokRSd' | |
const getMessagesForGroup = async (relay) => { | |
return new Promise((resolve, reject) => { | |
console.log('\x1b[33m 12. Get all messages for a group /nostrdevs-oOXekJwokRSd \x1b[0m', getPublicKey(regUserPrivateKey) ); | |
let sub = relay.sub([ | |
{ | |
limit: 100, | |
kinds: [9], | |
'#g': ['/nostrdevs-oOXekJwokRSd'], | |
} | |
]) | |
sub.on('event', event => { | |
//console.log('event: ', event); | |
if (event.kind === 9) console.log('kind 9 event content: ', event.content); | |
}) | |
sub.on('eose', () => { | |
resolve(true); | |
}) | |
}); | |
} | |
const connectToRelay = (relay) => { | |
return new Promise((resolve, reject) => { | |
relay.connect(); | |
relay.on('connect', () => { | |
console.log(`connected to ${relay.url}`) | |
resolve(true); | |
}) | |
relay.on('error', () => { | |
console.log(`failed to connect to ${relay.url}`) | |
reject(false); | |
}) | |
relay.on('notice', (msg) => { | |
console.log('notice: ', msg); | |
}) | |
}); | |
} | |
const postGroupEventToRelay = (postevent, privateKey) => { | |
return new Promise((resolve, reject) => { | |
(async () => { | |
postevent.created_at= Math.floor(Date.now() / 1000), | |
postevent.pubkey = getPublicKey(privateKey); | |
postevent.id = await getEventHash(postevent); | |
postevent.sig = await signEvent(postevent, privateKey); | |
const ready = await verifySignature(postevent); | |
let pub = await relay.publish(postevent); | |
pub.on('ok', () => { | |
console.log(`${relay.url} has accepted our event`) | |
resolve(true); | |
}) | |
pub.on('failed', reason => { | |
console.log(`failed to publish to ${relay.url}: ${reason}`) | |
resolve(false); | |
}) | |
})() | |
}); | |
} | |
const subscribeGroupEvents = () => { | |
return new Promise((resolve, reject) => { | |
let sub = relay.sub([ | |
{ | |
limit: 0, | |
kinds: [39000, 39001, 39003, 39004], | |
//'#g': ['/no-bitcoin-talk'], | |
} | |
]) | |
sub.on('event', event => { | |
//console.log('event: ', event); | |
console.log('Event with kind ' + event.kind + ' received. Signature verfication is ' + verifySignature(event)); | |
if (event.pubkey === relay_pubkey) console.log('Relay pubkey matched with event'); | |
if (event.kind === 9) console.log('kind 9 event content: ', event.content); | |
if (event.kind === 39000) console.log('kind 39000 tags: ', event.tags); | |
if (event.kind === 39001) console.log('kind 39001 p tag is: ', event.tags); | |
}) | |
sub.on('eose', () => { | |
resolve(true); | |
}) | |
}); | |
} | |
function makeid(length) { | |
let result = ''; | |
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | |
const charactersLength = characters.length; | |
let counter = 0; | |
while (counter < length) { | |
result += characters.charAt(Math.floor(Math.random() * charactersLength)); | |
counter += 1; | |
} | |
return result; | |
} | |
function sleep(ms) { | |
return new Promise((resolve) => { | |
setTimeout(resolve, ms); | |
}); | |
} | |
async function run() { | |
console.log('Relay URL: ', relay_url); | |
console.log('Relay pubkey: ', relay_pubkey); | |
console.log('Registered user pubkey: ', getPublicKey(regUserPrivateKey)); | |
console.log('New user pubkey: ', getPublicKey(newUserPrivateKey)); | |
connectStatus = await connectToRelay(relay); | |
if (connectStatus) await subscribeGroupEvents(); | |
if (connectStatus) await createGroup(); //1 | |
if (connectStatus) await postMessageToGroup(); //2 | |
await sleep(5000); | |
if (connectStatus) await newUserJoinsGroup(); //3 | |
if (connectStatus) await postMessageAsNewUserToGroup(); //4 | |
if (connectStatus) await newUserLeaveGroup(); //5 | |
await sleep(5000); | |
if (connectStatus) await createSubGroup(); //6 | |
if (connectStatus) await postMessageToSubGroup(); //7 | |
await sleep(5000); | |
if (connectStatus) await adminAddsUserGroup() //8 | |
if (connectStatus) await adminRemovesUserGroup() //9 | |
if (connectStatus) await userMessageFailGroup() //10 | |
if (connectStatus) await get39002Event(relay) //11 | |
if (connectStatus) await getMessagesForGroup(relay) //12 | |
if (connectStatus) await newUserJoinsGroup(); //3 | |
if (connectStatus) await postMessageAsNewUserToGroup(); //4 | |
if (connectStatus) await newUserLeaveGroup(); //5 | |
} | |
run().catch(console.log); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment