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 +2 -0
- package/event.js +16 -13
- package/filter.js +2 -2
- package/index.js +1 -3
- package/keys.js +19 -0
- package/nip04.js +3 -2
- package/nip06.js +18 -7
- package/package.json +9 -5
- package/pool.js +2 -1
- package/utils.js +0 -6
package/README.md
CHANGED
package/event.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {Buffer} from 'buffer'
|
|
2
|
-
import
|
|
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
|
|
28
|
-
let eventHash =
|
|
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
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
41
|
-
let eventHash =
|
|
42
|
-
|
|
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'])
|
|
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'])
|
|
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 =
|
|
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 =
|
|
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
|
|
3
|
-
import
|
|
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
|
|
7
|
-
|
|
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
|
|
19
|
+
return Buffer.from(mnemonicToSeedSync(mnemonic, wordlist)).toString('hex')
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
export function generateSeedWords() {
|
|
16
|
-
return
|
|
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.
|
|
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
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
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
|
-
"
|
|
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)
|