Tools for developing Nostr clients.
Go to file
fiatjaf 3f1025f551
nip05.queryProfile() and test.
2022-12-20 18:36:49 -03:00
.github/workflows better publishing built files. 2022-12-20 16:56:05 -03:00
.eslintrc.json fix typescript types everywhere, delete pool.js and refactor relay.js to use event listeners everywhere. 2022-12-18 17:02:19 -03:00
.gitignore better publishing built files. 2022-12-20 16:56:05 -03:00
.prettierrc.yaml update secp256k1 library, add nip04.js 2021-12-10 21:41:05 -03:00
README.md fix standalone script URL. 2022-12-20 17:01:35 -03:00
build.js better publishing built files. 2022-12-20 16:56:05 -03:00
event.test.js better publishing built files. 2022-12-20 16:56:05 -03:00
event.ts add a bunch of tests. 2022-12-19 20:02:01 -03:00
filter.test.js better publishing built files. 2022-12-20 16:56:05 -03:00
filter.ts add a bunch of tests. 2022-12-19 20:02:01 -03:00
index.ts add nip19. 2022-12-20 18:26:30 -03:00
keys.test.js better publishing built files. 2022-12-20 16:56:05 -03:00
keys.ts fix typescript types everywhere, delete pool.js and refactor relay.js to use event listeners everywhere. 2022-12-18 17:02:19 -03:00
nip04.test.js better publishing built files. 2022-12-20 16:56:05 -03:00
nip04.ts fix typescript types everywhere, delete pool.js and refactor relay.js to use event listeners everywhere. 2022-12-18 17:02:19 -03:00
nip05.test.js nip05.queryProfile() and test. 2022-12-20 18:36:49 -03:00
nip05.ts nip05.queryProfile() and test. 2022-12-20 18:36:49 -03:00
nip06.ts fix typescript types everywhere, delete pool.js and refactor relay.js to use event listeners everywhere. 2022-12-18 17:02:19 -03:00
nip19.test.js add nip19. 2022-12-20 18:26:30 -03:00
nip19.ts nip05.queryProfile() and test. 2022-12-20 18:36:49 -03:00
package.json nip05.queryProfile() and test. 2022-12-20 18:36:49 -03:00
relay.test.js better publishing built files. 2022-12-20 16:56:05 -03:00
relay.ts some fixes on relay.ts and tests. 2022-12-20 15:25:34 -03:00
tsconfig.json fix typescript types everywhere, delete pool.js and refactor relay.js to use event listeners everywhere. 2022-12-18 17:02:19 -03:00

README.md

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/lib/nostr.bundle.js"></script>
<script>
  window.NostrTools.generatePrivateKey('...') // and so on
</script>

License

Public domain.