2022-12-20 15:25:34 -03:00
2022-12-20 15:25:34 -03:00
2022-12-19 20:02:01 -03:00
2022-12-19 20:02:01 -03:00
2022-12-19 20:02:01 -03:00
2022-12-19 20:02:01 -03:00
2022-12-19 20:02:01 -03:00
2022-12-19 20:02:01 -03:00
2022-12-20 16:16:59 -03:00
2022-12-20 16:16:59 -03:00
2022-12-20 16:16:59 -03:00
2022-12-20 15:25:34 -03:00

nostr-tools

Tools for developing Nostr clients.

Usage

Generating a private key and a public key

import { generatePrivateKey, getPublicKey } from 'nostr-tools'

let sk = generatePrivateKey() # `sk` is a hex string
let pk = getPublicKey(sk) # `pk` is a hex string

Creating, signing and verifying events

import {
  validateEvent,
  verifySignature,
  signEvent,
  getEventHash,
  getPublicKey
} from 'nostr-tools'

let event = {
  kind: 1,
  created_at: Math.floor(Date.now() / 1000),
  tags: [],
  content: 'hello'
}

event.id = getEventHash(event.id)
event.pubkey = getPublicKey(privateKey)
event.sig = await signEvent(event, privateKey)

let ok = validateEvent(event)
let veryOk = await verifySignature(event)

Interacting with a relay

import {
  relayInit,
  generatePrivateKey,
  getPublicKey,
  getEventHash,
  signEvent
} from 'nostr-tools'

const relay = relayInit('wss://relay.example.com')
relay.connect()

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

// let's query for an event that exists
let 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
let sk = generatePrivateKey()
let pk = getPublicKey(sk)

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

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

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

let pub = relay.publish(event)
pub.on('ok', () => {
  console.log(`{relay.url} has accepted our event`)
})
pub.on('seen', () => {
  console.log(`we saw the event on {relay.url}`)
})
pub.on('failed', reason => {
  console.log(`failed to publish to {relay.url}: ${reason}`)
})

await relay.close()

Encrypting and decrypting direct messages

import {nip04, getPublicKey, generatePrivateKey} from 'nostr-tools'

// sender
let sk1 = generatePrivateKey()
let pk1 = getPublicKey(sk1)

// receiver
let sk2 = generatePrivateKey()
let pk2 = getPublicKey(sk2)

// on the sender side
let message = 'hello'
let ciphertext = nip04.encrypt(sk1, pk2, 'hello')

let event = {
  kind: 4,
  pubkey: pk1,
  tags: [['p', pk2]],
  content: ciphertext,
  ...otherProperties
}

sendEvent(event)

// on the receiver side

sub.on('event', (event) => {
  let sender = event.tags.find(([k, v]) => k === 'p' && && v && v !== '')[1]
  pk1 === sender
  let plaintext = nip04.decrypt(sk2, pk1, event.content)
})

Please consult the tests or the source code for more information that isn't available here.

Using from the browser (if you don't want to use a bundler)

<script src="https://unpkg.com/nostr-tools/standalone/index.js"></script>
<script>
  window.NostrTools.generatePrivateKey('...') // and so on
</script>

License

Public domain.

Description
Tools for developing Nostr clients.
Readme Unlicense 3.1 MiB
Languages
TypeScript 99.4%
JavaScript 0.3%
Just 0.2%
Dockerfile 0.1%