Skip to content

Commit

Permalink
feat: implement Relay.
Browse files Browse the repository at this point in the history
  • Loading branch information
susumuota committed Apr 5, 2023
1 parent 8190852 commit 79c7e50
Show file tree
Hide file tree
Showing 8 changed files with 734 additions and 108 deletions.
92 changes: 88 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm install nostrain

## Usage

- See [examples](https://github.com/susumuota/nostrain/tree/main/examples).
- See [examples](https://github.com/susumuota/nostrain/tree/main/examples) directory.

### Generating a private key and a public key

Expand All @@ -39,7 +39,14 @@ console.log({ sk, pk });
### Creating, signing and verifying events

```javascript
import { validateEvent, verifySignature, signEvent, getEventHash, generatePrivateKey, getPublicKey } from 'nostrain';
import {
validateEvent,
verifySignature,
signEvent,
getEventHash,
generatePrivateKey,
getPublicKey,
} from 'nostrain';

const privateKey = generatePrivateKey();

Expand All @@ -63,7 +70,83 @@ console.log({ event, validateOk, verifyOk });

### Interacting with a relay

TODO: work in progress
```javascript
import crypto from 'node:crypto';
globalThis.crypto = crypto;

import 'websocket-polyfill';
import { relayInit, generatePrivateKey, getPublicKey, getEventHash, signEvent } from 'nostrain';

const relay = relayInit('wss://relay.damus.io');

relay.on('connect', () => {
console.log(`connected to ${relay.url}`);
});
relay.on('error', () => {
console.log(`failed to connect to ${relay.url}`);
});

await relay.connect();

{
// let's query for an event that exists
const sub = relay.sub([{ ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] }]);

sub.on('event', event => {
console.log('we got the event we wanted:', event);
});
sub.on('eose', () => {
sub.unsub();
});
}

{
// let's publish a new event while simultaneously monitoring the relay for it
const sk = generatePrivateKey();
const pk = getPublicKey(sk);

const sub = relay.sub([{ kinds: [1], authors: [pk] }]);

sub.on('event', event => {
console.log('got event:', event);
});

const event = {
kind: 1,
pubkey: pk,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'hello world',
};
event.id = getEventHash(event);
event.sig = signEvent(event, sk);

const pub = relay.publish(event);
pub.on('ok', () => {
console.log(`${relay.url} has accepted our event`);
});
pub.on('failed', reason => {
console.log(`failed to publish to ${relay.url}: ${reason}`);
});
}

{
// let's query for events by list and get
const events = await relay.list([{ kinds: [0, 1] }]);
console.log(events.length);

const event = await relay.get({ ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] });
console.log({ event });
}

relay.close();
```

To use this on Node.js you first must install `websocket-polyfill` and import it:

```javascript
import 'websocket-polyfill'
```

### Interacting with multiple relays

Expand Down Expand Up @@ -175,7 +258,8 @@ console.log({ tags: event.tags });
// finally any receiver of this event can check for the presence of a valid delegation tag
const delegator = nip26.getDelegator(event);

console.log({ delegator, pk1, success: delegator === pk1 }); // will be null if there is no delegation tag or if it is invalid
// will be null if there is no delegation tag or if it is invalid
console.log({ delegator, pk1, success: delegator === pk1 });
```

## Development
Expand Down
3 changes: 2 additions & 1 deletion examples/delegation.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ console.log({ tags: event.tags });
// finally any receiver of this event can check for the presence of a valid delegation tag
const delegator = nip26.getDelegator(event);

console.log({ delegator, pk1, success: delegator === pk1 }); // will be null if there is no delegation tag or if it is invalid
// will be null if there is no delegation tag or if it is invalid
console.log({ delegator, pk1, success: delegator === pk1 });
74 changes: 74 additions & 0 deletions examples/relay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-FileCopyrightText: 2023 Susumu OTA <1632335+susumuota@users.noreply.github.com>
// SPDX-License-Identifier: MIT

// node examples/relay.js

import crypto from 'node:crypto';
globalThis.crypto = crypto;

import 'websocket-polyfill';
import { relayInit, generatePrivateKey, getPublicKey, getEventHash, signEvent } from 'nostrain';

const relay = relayInit('wss://relay.damus.io');

relay.on('connect', () => {
console.log(`connected to ${relay.url}`);
});
relay.on('error', () => {
console.log(`failed to connect to ${relay.url}`);
});

await relay.connect();

{
// let's query for an event that exists
const sub = relay.sub([{ ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] }]);

sub.on('event', event => {
console.log('we got the event we wanted:', event);
});
sub.on('eose', () => {
sub.unsub();
});
}

{
// let's publish a new event while simultaneously monitoring the relay for it
const sk = generatePrivateKey();
const pk = getPublicKey(sk);

const sub = relay.sub([{ kinds: [1], authors: [pk] }]);

sub.on('event', event => {
console.log('got event:', event);
});

const event = {
kind: 1,
pubkey: pk,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'hello world',
};
event.id = getEventHash(event);
event.sig = signEvent(event, sk);

const pub = relay.publish(event);
pub.on('ok', () => {
console.log(`${relay.url} has accepted our event`);
});
pub.on('failed', reason => {
console.log(`failed to publish to ${relay.url}: ${reason}`);
});
}

{
// let's query for events by list and get
const events = await relay.list([{ kinds: [0, 1] }]);
console.log(events.length);

const event = await relay.get({ ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] });
console.log({ event });
}

relay.close();

0 comments on commit 79c7e50

Please sign in to comment.