nostr-tools 0.10.2 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,4 +67,6 @@ pool.addRelay('<url>')
67
67
  // will automatically subscribe to the all the events called with .sub above
68
68
  ```
69
69
 
70
+ All functions expect bytearrays as hex strings and output bytearrays as hex strings.
71
+
70
72
  For other utils please read the source (for now).
package/event.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import {Buffer} from 'buffer'
2
- import * as secp256k1 from '@noble/secp256k1'
3
-
4
- import {sha256} from './utils'
2
+ import createHash from 'create-hash'
3
+ import {signSchnorr, verifySchnorr} from 'tiny-secp256k1'
5
4
 
6
5
  export function getBlankEvent() {
7
6
  return {
@@ -24,20 +23,24 @@ export function serializeEvent(evt) {
24
23
  ])
25
24
  }
26
25
 
27
- export async function getEventHash(event) {
28
- let eventHash = await sha256(Buffer.from(serializeEvent(event)))
26
+ export function getEventHash(event) {
27
+ let eventHash = createHash('sha256')
28
+ .update(Buffer.from(serializeEvent(event)))
29
+ .digest()
29
30
  return Buffer.from(eventHash).toString('hex')
30
31
  }
31
32
 
32
- export async function verifySignature(event) {
33
- return await secp256k1.schnorr.verify(
34
- event.sig,
35
- await getEventHash(event),
36
- event.pubkey
33
+ export function verifySignature(event) {
34
+ if (event.id !== getEventHash(event)) return false
35
+ return verifySchnorr(
36
+ Buffer.from(event.id, 'hex'),
37
+ Buffer.from(event.pubkey, 'hex')
38
+ Buffer.from(event.sig, 'hex'),
37
39
  )
38
40
  }
39
41
 
40
- export async function signEvent(event, key) {
41
- let eventHash = await getEventHash(event)
42
- return await secp256k1.schnorr.sign(eventHash, key)
42
+ export function signEvent(event, key) {
43
+ let eventHash = Buffer.from(getEventHash(event), 'hex')
44
+ let key = Buffer.from(key, 'hex')
45
+ return Buffer.from(signSchnorr(eventHash, key)).toString('hex')
43
46
  }
package/filter.js CHANGED
@@ -6,12 +6,12 @@ export function matchFilter(filter, event) {
6
6
  return false
7
7
  if (
8
8
  filter['#e'] &&
9
- event.tags.find(([t, v]) => t === 'e' && v === filter['#e']) === null
9
+ !event.tags.find(([t, v]) => t === 'e' && v === filter['#e'])
10
10
  )
11
11
  return false
12
12
  if (
13
13
  filter['#p'] &&
14
- event.tags.find(([t, v]) => t === 'p' && v === filter['#p']) === null
14
+ !event.tags.find(([t, v]) => t === 'p' && v === filter['#p'])
15
15
  )
16
16
  return false
17
17
  if (filter.since && event.created_at <= filter.since) return false
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import {generatePrivateKey, getPublicKey} from './keys'
1
2
  import {relayConnect} from './relay'
2
3
  import {relayPool} from './pool'
3
4
  import {
@@ -8,7 +9,6 @@ import {
8
9
  getEventHash
9
10
  } from './event'
10
11
  import {matchFilter, matchFilters} from './filter'
11
- import {makeRandom32, sha256, getPublicKey} from './utils'
12
12
 
13
13
  export {
14
14
  relayConnect,
@@ -17,8 +17,6 @@ export {
17
17
  verifySignature,
18
18
  serializeEvent,
19
19
  getEventHash,
20
- makeRandom32,
21
- sha256,
22
20
  getPublicKey,
23
21
  getBlankEvent,
24
22
  matchFilter,
package/keys.js ADDED
@@ -0,0 +1,19 @@
1
+ import randomBytes from 'randombytes'
2
+ import {isPrivate, pointFromScalar} from 'tiny-secp256k1'
3
+
4
+ export function generatePrivateKey() {
5
+ let i = 8
6
+ while (i--) {
7
+ let r32 = Buffer.from(randomBytes(32))
8
+ if (isPrivate(r32)) return r32.toString('hex')
9
+ }
10
+ throw new Error(
11
+ 'Valid private key was not found in 8 iterations. PRNG is broken'
12
+ )
13
+ }
14
+
15
+ export function getPublicKey(privateKey) {
16
+ return Buffer.from(
17
+ pointFromScalar(Buffer.from(privateKey, 'hex'), true)
18
+ ).toString('hex')
19
+ }
package/nip04.js CHANGED
@@ -1,3 +1,4 @@
1
+ import aes from 'browserify-cipher'
1
2
  import {Buffer} from 'buffer'
2
3
  import randomBytes from 'randombytes'
3
4
  import * as secp256k1 from '@noble/secp256k1'
@@ -7,7 +8,7 @@ export function encrypt(privkey, pubkey, text) {
7
8
  const normalizedKey = getOnlyXFromFullSharedSecret(key)
8
9
 
9
10
  let iv = Uint8Array.from(randomBytes(16))
10
- var cipher = crypto.createCipheriv(
11
+ var cipher = aes.createCipheriv(
11
12
  'aes-256-cbc',
12
13
  Buffer.from(normalizedKey, 'hex'),
13
14
  iv
@@ -22,7 +23,7 @@ export function decrypt(privkey, pubkey, ciphertext, iv) {
22
23
  const key = secp256k1.getSharedSecret(privkey, '02' + pubkey)
23
24
  const normalizedKey = getOnlyXFromFullSharedSecret(key)
24
25
 
25
- var decipher = crypto.createDecipheriv(
26
+ var decipher = aes.createDecipheriv(
26
27
  'aes-256-cbc',
27
28
  Buffer.from(normalizedKey, 'hex'),
28
29
  Buffer.from(iv, 'base64')
package/nip06.js CHANGED
@@ -1,17 +1,28 @@
1
1
  import createHmac from 'create-hmac'
2
- import randomBytes from 'randombytes'
3
- import * as bip39 from 'bip39'
2
+ import {wordlist} from 'micro-bip39/wordlists/english'
3
+ import {
4
+ generateMnemonic,
5
+ mnemonicToSeedSync,
6
+ validateMnemonic
7
+ } from 'micro-bip39'
8
+ import BIP32Factory from 'bip32'
9
+ import * as ecc from 'tiny-secp256k1'
10
+
11
+ const bip32 = BIP32Factory(ecc)
4
12
 
5
13
  export function privateKeyFromSeed(seed) {
6
- let hmac = createHmac('sha512', Buffer.from('Nostr seed', 'utf8'))
7
- hmac.update(seed)
8
- return hmac.digest().slice(0, 32).toString('hex')
14
+ let root = bip32.fromSeed(Buffer.from(seed, 'hex'))
15
+ return root.derivePath(`m/44'/1237'/0'/0'`).privateKey.toString('hex')
9
16
  }
10
17
 
11
18
  export function seedFromWords(mnemonic) {
12
- return bip39.mnemonicToSeedSync(mnemonic)
19
+ return Buffer.from(mnemonicToSeedSync(mnemonic, wordlist)).toString('hex')
13
20
  }
14
21
 
15
22
  export function generateSeedWords() {
16
- return bip39.entropyToMnemonic(randomBytes(16).toString('hex'))
23
+ return generateMnemonic(wordlist)
24
+ }
25
+
26
+ export function validateWords(words) {
27
+ return validateMnemonic(words, wordlist)
17
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nostr-tools",
3
- "version": "0.10.2",
3
+ "version": "0.12.1",
4
4
  "description": "Tools for making a Nostr client.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,11 +8,15 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@noble/secp256k1": "^1.3.0",
11
- "bip39": "^3.0.4",
12
- "buffer": "^6.0.3",
13
- "create-hmac": "^1.1.7",
11
+ "bip32": "^3.0.1",
12
+ "browserify-cipher": ">=1",
13
+ "buffer": ">=5",
14
+ "create-hash": "^1.2.0",
15
+ "create-hmac": ">=1",
14
16
  "dns-packet": "^5.2.4",
15
- "randombytes": "^2.1.0",
17
+ "micro-bip39": "^0.1.3",
18
+ "randombytes": ">=2",
19
+ "tiny-secp256k1": "^2.1.2",
16
20
  "websocket-polyfill": "^0.0.3"
17
21
  },
18
22
  "keywords": [
package/pool.js CHANGED
@@ -95,11 +95,12 @@ export function relayPool(globalPrivateKey) {
95
95
  if (index !== -1) noticeCallbacks.splice(index, 1)
96
96
  },
97
97
  async publish(event, statusCallback = (status, relayURL) => {}) {
98
+ event.id = await getEventHash(event)
99
+
98
100
  if (!event.sig) {
99
101
  event.tags = event.tags || []
100
102
 
101
103
  if (globalPrivateKey) {
102
- event.id = await getEventHash(event)
103
104
  event.sig = await signEvent(event, globalPrivateKey)
104
105
  } else {
105
106
  throw new Error(
package/utils.js DELETED
@@ -1,6 +0,0 @@
1
- import * as secp256k1 from '@noble/secp256k1'
2
-
3
- export const makeRandom32 = () => secp256k1.utils.randomPrivateKey()
4
- export const sha256 = m => secp256k1.utils.sha256(Uint8Array.from(m))
5
- export const getPublicKey = privateKey =>
6
- secp256k1.schnorr.getPublicKey(privateKey)