libp2r2p 0.0.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/AGENTS.md +20 -0
- package/README.md +129 -0
- package/base16/index.js +14 -0
- package/base64/index.js +29 -0
- package/content-key/event/index.js +85 -0
- package/content-key/index.js +1 -0
- package/content-key/services/iykc-proof.js +129 -0
- package/double-dh/index.js +166 -0
- package/ecdh/index.js +8 -0
- package/idb/index.js +64 -0
- package/idb-queue/index.js +793 -0
- package/index.js +21 -0
- package/key/index.js +139 -0
- package/network/index.js +68 -0
- package/nip44-v3/index.js +175 -0
- package/nip46/constants/index.js +5 -0
- package/nip46/helpers/frame.js +51 -0
- package/nip46/helpers/url.js +96 -0
- package/nip46/index.js +5 -0
- package/nip46/services/bunker-signer.js +49 -0
- package/nip46/services/client.js +252 -0
- package/nip46/services/server-session.js +225 -0
- package/nip46/services/transport.js +265 -0
- package/package.json +49 -0
- package/private-channel/constants/index.js +5 -0
- package/private-channel/helpers/chunk-size.js +61 -0
- package/private-channel/helpers/chunks.js +282 -0
- package/private-channel/helpers/event.js +68 -0
- package/private-channel/index.js +942 -0
- package/private-channel/services/received-chunks.js +398 -0
- package/private-message/index.js +672 -0
- package/private-messenger/constants/index.js +1 -0
- package/private-messenger/index.js +1431 -0
- package/private-messenger/recovery/index.js +316 -0
- package/relay/constants/index.js +18 -0
- package/relay/helpers/hll.js +62 -0
- package/relay/helpers/publish.js +100 -0
- package/relay/helpers/routing.js +36 -0
- package/relay/helpers/timer.js +4 -0
- package/relay/index.js +4 -0
- package/relay/services/query.js +224 -0
- package/relay/services/relay-connection.js +156 -0
- package/relay/services/relay-pool.js +908 -0
- package/temporary-storage/index.js +85 -0
- package/tests/base16.test.js +19 -0
- package/tests/base64.test.js +18 -0
- package/tests/content-key-event.test.js +48 -0
- package/tests/fixtures/nip44v3-vectors.json +1 -0
- package/tests/helpers/test-signer.js +185 -0
- package/tests/idb-queue.test.js +153 -0
- package/tests/idb.test.js +91 -0
- package/tests/nip44-v3.test.js +73 -0
- package/tests/nip46.test.js +668 -0
- package/tests/private-channel.test.js +1899 -0
- package/tests/private-message.test.js +460 -0
- package/tests/private-messenger.test.js +1715 -0
- package/tests/queries.test.js +101 -0
- package/tests/queue-parity.test.js +105 -0
- package/tests/relay-hll.test.js +32 -0
- package/tests/relay-pool.test.js +2067 -0
- package/tests/temporary-storage.test.js +89 -0
- package/tests/web-storage-queue.test.js +480 -0
- package/web-storage-queue/index.js +652 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { IDBFactory } from 'fake-indexeddb'
|
|
4
|
+
import { run } from '../idb/index.js'
|
|
5
|
+
|
|
6
|
+
function deferred () {
|
|
7
|
+
let resolve
|
|
8
|
+
let reject
|
|
9
|
+
const promise = new Promise((nextResolve, nextReject) => {
|
|
10
|
+
resolve = nextResolve
|
|
11
|
+
reject = nextReject
|
|
12
|
+
})
|
|
13
|
+
return { promise, resolve, reject }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function transactionDone (tx) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
tx.oncomplete = () => resolve()
|
|
19
|
+
tx.onabort = () => reject(tx.error || new Error('IDB_TRANSACTION_ABORTED'))
|
|
20
|
+
tx.onerror = () => reject(tx.error || new Error('IDB_TRANSACTION_FAILED'))
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function openRowsDb () {
|
|
25
|
+
const indexedDB = new IDBFactory()
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const request = indexedDB.open('idb-run-test', 1)
|
|
28
|
+
request.onerror = () => reject(request.error)
|
|
29
|
+
request.onupgradeneeded = () => {
|
|
30
|
+
const store = request.result.createObjectStore('rows', { keyPath: 'id' })
|
|
31
|
+
store.createIndex('byGroup', 'group')
|
|
32
|
+
}
|
|
33
|
+
request.onsuccess = () => resolve(request.result)
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
test('run performs store and index requests inside a shared transaction', async () => {
|
|
38
|
+
const db = await openRowsDb()
|
|
39
|
+
const tx = db.transaction(['rows'], 'readwrite')
|
|
40
|
+
const done = transactionDone(tx)
|
|
41
|
+
|
|
42
|
+
await run('put', [{ id: 'one', group: 'alpha', value: 1 }], 'rows', null, { db, tx })
|
|
43
|
+
await run('put', [{ id: 'two', group: 'beta', value: 2 }], 'rows', null, { db, tx })
|
|
44
|
+
const found = await run('get', ['alpha'], 'rows', 'byGroup', { db, tx })
|
|
45
|
+
|
|
46
|
+
assert.equal(found.result.id, 'one')
|
|
47
|
+
await done
|
|
48
|
+
db.close()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('run supports the reusable deferred cursor pattern', async () => {
|
|
52
|
+
const db = await openRowsDb()
|
|
53
|
+
const setup = db.transaction(['rows'], 'readwrite')
|
|
54
|
+
const setupDone = transactionDone(setup)
|
|
55
|
+
await run('put', [{ id: 'one', group: 'alpha' }], 'rows', null, { db, tx: setup })
|
|
56
|
+
await run('put', [{ id: 'two', group: 'beta' }], 'rows', null, { db, tx: setup })
|
|
57
|
+
await setupDone
|
|
58
|
+
|
|
59
|
+
const tx = db.transaction(['rows'], 'readonly')
|
|
60
|
+
const done = transactionDone(tx)
|
|
61
|
+
const p = deferred()
|
|
62
|
+
let cursor = (await run('openCursor', [], 'rows', null, { db, tx, p })).result
|
|
63
|
+
const ids = []
|
|
64
|
+
while (cursor) {
|
|
65
|
+
ids.push(cursor.value.id)
|
|
66
|
+
Object.assign(p, deferred())
|
|
67
|
+
cursor.continue()
|
|
68
|
+
cursor = (await p.promise).result
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
assert.deepEqual(ids, ['one', 'two'])
|
|
72
|
+
await done
|
|
73
|
+
db.close()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('run aborts a transaction when a request fails', async () => {
|
|
77
|
+
const db = await openRowsDb()
|
|
78
|
+
const tx = db.transaction(['rows'], 'readwrite')
|
|
79
|
+
const done = transactionDone(tx)
|
|
80
|
+
|
|
81
|
+
await run('add', [{ id: 'one', group: 'alpha' }], 'rows', null, { db, tx })
|
|
82
|
+
await assert.rejects(
|
|
83
|
+
run('add', [{ id: 'one', group: 'beta' }], 'rows', null, { db, tx })
|
|
84
|
+
)
|
|
85
|
+
await assert.rejects(done)
|
|
86
|
+
|
|
87
|
+
const read = db.transaction(['rows'], 'readonly')
|
|
88
|
+
const row = await run('get', ['one'], 'rows', null, { db, tx: read })
|
|
89
|
+
assert.equal(row.result, undefined)
|
|
90
|
+
db.close()
|
|
91
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { getPublicKey } from 'nostr-tools'
|
|
5
|
+
import { sha256 } from '@noble/hashes/sha2.js'
|
|
6
|
+
|
|
7
|
+
import * as nip44v3 from '../nip44-v3/index.js'
|
|
8
|
+
import { bytesToHex, hexToBytes } from '../base16/index.js'
|
|
9
|
+
|
|
10
|
+
const vectors = JSON.parse(readFileSync(new URL('./fixtures/nip44v3-vectors.json', import.meta.url), 'utf8'))
|
|
11
|
+
|
|
12
|
+
function pubOf (sec) {
|
|
13
|
+
return getPublicKey(hexToBytes(sec))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test('nip44-v3 passes the vendored upstream self-test vectors', () => {
|
|
17
|
+
const fails = []
|
|
18
|
+
const check = (section, name, cond, detail = '') => {
|
|
19
|
+
if (!cond) fails.push(`[${section}] ${name}${detail ? `: ${detail}` : ''}`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
for (const [i, v] of (vectors.encrypt_decrypt || []).entries()) {
|
|
23
|
+
const sec1 = hexToBytes(v.secret1)
|
|
24
|
+
const sec2 = hexToBytes(v.secret2)
|
|
25
|
+
const pub1 = pubOf(v.secret1)
|
|
26
|
+
const pub2 = pubOf(v.secret2)
|
|
27
|
+
const nonce = hexToBytes(v.nonce)
|
|
28
|
+
const scope = hexToBytes(v.scope_hex)
|
|
29
|
+
const plaintext = hexToBytes(v.plaintext_hex)
|
|
30
|
+
const keys = nip44v3.deriveKeys(sec1, pub2, nonce)
|
|
31
|
+
check('encrypt_decrypt', `ed[${i}] prk`, bytesToHex(keys.prk) === v.prk)
|
|
32
|
+
check('encrypt_decrypt', `ed[${i}] encryption_key`, bytesToHex(keys.encryption_key) === v.encryption_key)
|
|
33
|
+
check('encrypt_decrypt', `ed[${i}] mac_key`, bytesToHex(keys.mac_key) === v.mac_key)
|
|
34
|
+
check('encrypt_decrypt', `ed[${i}] encrypt party1`, nip44v3.encryptBytes(sec1, pub2, v.kind, scope, plaintext, nonce) === v.ciphertext)
|
|
35
|
+
check('encrypt_decrypt', `ed[${i}] encrypt party2`, nip44v3.encryptBytes(sec2, pub1, v.kind, scope, plaintext, nonce) === v.ciphertext)
|
|
36
|
+
check('encrypt_decrypt', `ed[${i}] decrypt party1`, bytesToHex(nip44v3.decryptBytes(sec1, pub2, v.kind, scope, v.ciphertext)) === v.plaintext_hex)
|
|
37
|
+
check('encrypt_decrypt', `ed[${i}] decrypt party2`, bytesToHex(nip44v3.decryptBytes(sec2, pub1, v.kind, scope, v.ciphertext)) === v.plaintext_hex)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const [i, v] of (vectors.decrypt_only || []).entries()) {
|
|
41
|
+
check('decrypt_only', `do[${i}]`, bytesToHex(nip44v3.decryptBytes(hexToBytes(v.secret1), pubOf(v.secret2), v.kind, hexToBytes(v.scope_hex), v.ciphertext)) === v.plaintext_hex)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const [i, v] of (vectors.long_encrypt_decrypt || []).entries()) {
|
|
45
|
+
const pattern = hexToBytes(v.pattern_hex)
|
|
46
|
+
const plaintext = new Uint8Array(pattern.length * v.repeat)
|
|
47
|
+
for (let r = 0; r < v.repeat; r++) plaintext.set(pattern, r * pattern.length)
|
|
48
|
+
const scope = hexToBytes(v.scope_hex)
|
|
49
|
+
const ciphertext = nip44v3.encryptBytes(hexToBytes(v.secret1), pubOf(v.secret2), v.kind, scope, plaintext, hexToBytes(v.nonce))
|
|
50
|
+
check('long_encrypt_decrypt', `long[${i}] sha256`, bytesToHex(sha256(nip44v3.toBytes(ciphertext))) === v.ciphertext_sha256)
|
|
51
|
+
check('long_encrypt_decrypt', `long[${i}] round-trip`, bytesToHex(nip44v3.decryptBytes(hexToBytes(v.secret1), pubOf(v.secret2), v.kind, scope, ciphertext)) === bytesToHex(plaintext))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (const row of (vectors.padded_length || [])) {
|
|
55
|
+
check('padded_length', `pad[${row[0]}]`, nip44v3.targetSize(row[0]) === row[1])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const [i, v] of (vectors.invalid_decryption || []).entries()) {
|
|
59
|
+
assert.throws(() => nip44v3.decryptBytes(hexToBytes(v.secret), v.public, v.kind, hexToBytes(v.scope_hex), v.ciphertext), Error, `invalid vector ${i} should reject`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
assert.deepEqual(fails, [])
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('nip44-v3 byte payload helpers round-trip arbitrary bytes', () => {
|
|
66
|
+
const alice = hexToBytes('1'.repeat(64))
|
|
67
|
+
const bob = hexToBytes('2'.repeat(64))
|
|
68
|
+
const plaintext = nip44v3.b64encode(new Uint8Array([0, 1, 2, 127, 128, 255]))
|
|
69
|
+
const ciphertext = nip44v3.nip07Encrypt(alice, getPublicKey(bob), '30078', 'spec.nostr.land/nip44v3', plaintext)
|
|
70
|
+
|
|
71
|
+
assert.equal(nip44v3.nip07Decrypt(bob, getPublicKey(alice), 30078, 'spec.nostr.land/nip44v3', ciphertext), plaintext)
|
|
72
|
+
assert.throws(() => nip44v3.nip07Decrypt(bob, getPublicKey(alice), 1, 'spec.nostr.land/nip44v3', ciphertext), /kind mismatch/)
|
|
73
|
+
})
|