libp2r2p 0.0.1 → 0.1.0
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 +68 -21
- package/base93/index.js +193 -0
- package/package.json +23 -1
- package/private-channel/index.js +3 -3
- package/private-message/index.js +65 -39
- package/private-messenger/index.js +35 -11
- package/relay/helpers/publish.js +1 -2
- package/relay/services/relay-pool.js +2 -5
- package/AGENTS.md +0 -20
- package/tests/base16.test.js +0 -19
- package/tests/base64.test.js +0 -18
- package/tests/content-key-event.test.js +0 -48
- package/tests/fixtures/nip44v3-vectors.json +0 -1
- package/tests/helpers/test-signer.js +0 -185
- package/tests/idb-queue.test.js +0 -153
- package/tests/idb.test.js +0 -91
- package/tests/nip44-v3.test.js +0 -73
- package/tests/nip46.test.js +0 -668
- package/tests/private-channel.test.js +0 -1899
- package/tests/private-message.test.js +0 -460
- package/tests/private-messenger.test.js +0 -1715
- package/tests/queries.test.js +0 -101
- package/tests/queue-parity.test.js +0 -105
- package/tests/relay-hll.test.js +0 -32
- package/tests/relay-pool.test.js +0 -2067
- package/tests/temporary-storage.test.js +0 -89
- package/tests/web-storage-queue.test.js +0 -480
package/README.md
CHANGED
|
@@ -44,40 +44,87 @@ await messenger.tell({
|
|
|
44
44
|
|
|
45
45
|
### Deleting Private Broadcasts
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
logical message.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
By default, each high-level private-message send creates one fresh deletion
|
|
48
|
+
keypair for its logical message. Every outer kind `3560` event produced for that
|
|
49
|
+
send, including router chunks, recipient subsets, and nym carriers, carries the
|
|
50
|
+
same public key in its `s` tag. The result always contains `delivery.reports`.
|
|
51
|
+
When libp2r2p generated the keypair, it also contains
|
|
52
|
+
`delivery.deletionSeckey`; the public key can be derived from that secret.
|
|
53
|
+
|
|
54
|
+
This shared `s` value deliberately makes the outer events for one logical send
|
|
55
|
+
linkable to relay operators and other observers. Disable automatic capabilities
|
|
56
|
+
when that tradeoff is not acceptable. The messenger-wide setting defaults to
|
|
57
|
+
`true`, and a channel setting takes precedence:
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
```js
|
|
60
|
+
const messenger = await createPrivateMessenger({
|
|
61
|
+
userSigner,
|
|
62
|
+
autoDeletionCapability: false,
|
|
63
|
+
channels: [{
|
|
64
|
+
signer: privateChannelSigner,
|
|
65
|
+
relays: ['wss://relay.example'],
|
|
66
|
+
autoDeletionCapability: true
|
|
67
|
+
}]
|
|
68
|
+
})
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
With automatic capabilities disabled and no caller-supplied key, the outer
|
|
72
|
+
events have no `s` tag. They are not deliberately linkable through this
|
|
73
|
+
extension, but cannot later be deleted with it. A caller that already owns a
|
|
74
|
+
deletion key can supply its public key on an individual send; libp2r2p then
|
|
75
|
+
does not generate or return a key. Use a fresh caller-owned key for each
|
|
76
|
+
logical message unless cross-message linkability is intentional:
|
|
56
77
|
|
|
57
78
|
```js
|
|
58
79
|
import { generateKeypair } from 'libp2r2p/key'
|
|
59
80
|
|
|
60
81
|
const deletionKey = generateKeypair()
|
|
61
|
-
|
|
82
|
+
await messenger.tell({
|
|
62
83
|
receiverPubkey,
|
|
63
84
|
payload: { text: 'remove this later' },
|
|
64
85
|
deletionPubkey: deletionKey.pubkey
|
|
65
86
|
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
import { finalizeEvent } from 'nostr-tools'
|
|
91
|
+
import { keypairFromSeckey } from 'libp2r2p/key'
|
|
92
|
+
import { relayPool } from 'libp2r2p/relay'
|
|
93
|
+
|
|
94
|
+
const sent = await messenger.tell({
|
|
95
|
+
receiverPubkey,
|
|
96
|
+
payload: { text: 'remove this later' }
|
|
97
|
+
})
|
|
66
98
|
|
|
67
|
-
|
|
68
|
-
|
|
99
|
+
if (sent.delivery.deletionSeckey) {
|
|
100
|
+
const deletionKey = keypairFromSeckey(sent.delivery.deletionSeckey)
|
|
101
|
+
// Persist this secret with the application's copy of the logical message.
|
|
102
|
+
|
|
103
|
+
const { result: outerEvents } = await relayPool.getEvents({
|
|
104
|
+
kinds: [3560],
|
|
105
|
+
authors: [channelPubkey],
|
|
106
|
+
'#s': [deletionKey.pubkey]
|
|
107
|
+
}, relays)
|
|
108
|
+
for (let offset = 0; offset < outerEvents.length; offset += 100) {
|
|
109
|
+
const deletion = finalizeEvent({
|
|
110
|
+
kind: 5,
|
|
111
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
112
|
+
tags: [['k', '3560'], ...outerEvents.slice(offset, offset + 100).map(event => ['e', event.id])],
|
|
113
|
+
content: ''
|
|
114
|
+
}, deletionKey.secretKey)
|
|
115
|
+
await relayPool.sendEvent(deletion, relays)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
69
118
|
```
|
|
70
119
|
|
|
71
|
-
The `s` tag is public metadata
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
signed by the outer event's private-channel key MUST NOT delete a kind `3560`
|
|
80
|
-
event, whether or not that event carries an `s` tag.
|
|
120
|
+
The `s` tag is public metadata and a deletion capability, not the channel key
|
|
121
|
+
or sender identity. libp2r2p does not delete anything automatically.
|
|
122
|
+
|
|
123
|
+
Relay support for this capability is not universal. A relay that implements it
|
|
124
|
+
should accept only a kind `5` request signed by the matching `s` key with exactly
|
|
125
|
+
one `['k', '3560']` tag, explicit matching `e` targets, and no `a` tags. A
|
|
126
|
+
regular NIP-09 kind `5` request signed by the outer event's private-channel key
|
|
127
|
+
must not delete a kind `3560` event, whether or not that event has an `s` tag.
|
|
81
128
|
|
|
82
129
|
### Temporary Send Storage
|
|
83
130
|
|
package/base93/index.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Derived from https://github.com/ticlo/arrow-code/blob/master/src/base93.ts
|
|
2
|
+
// Apache-2.0. JSON-safe alphabet: space is included; double quote and
|
|
3
|
+
// backslash are intentionally excluded.
|
|
4
|
+
|
|
5
|
+
export const BASE93_ALPHABET =
|
|
6
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'()*+,-./:;<=>?@[]^_`{|}~ "
|
|
7
|
+
|
|
8
|
+
const ENCODING_TABLE = (() => {
|
|
9
|
+
const out = new Uint16Array(93)
|
|
10
|
+
for (let i = 0; i < out.length; i++) out[i] = BASE93_ALPHABET.charCodeAt(i)
|
|
11
|
+
return out
|
|
12
|
+
})()
|
|
13
|
+
|
|
14
|
+
const DECODING_TABLE = (() => {
|
|
15
|
+
const out = new Int16Array(128)
|
|
16
|
+
out.fill(-1)
|
|
17
|
+
for (let i = 0; i < BASE93_ALPHABET.length; i++) out[BASE93_ALPHABET.charCodeAt(i)] = i
|
|
18
|
+
return out
|
|
19
|
+
})()
|
|
20
|
+
|
|
21
|
+
function codesToString (codes, length) {
|
|
22
|
+
const chunkLength = 16384
|
|
23
|
+
let result = ''
|
|
24
|
+
for (let i = 0; i < length; i += chunkLength) {
|
|
25
|
+
result += String.fromCharCode.apply(
|
|
26
|
+
null,
|
|
27
|
+
Array.prototype.slice.call(codes, i, Math.min(i + chunkLength, length))
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
return result
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function asBytes (bytes) {
|
|
34
|
+
if (bytes instanceof Uint8Array) return bytes
|
|
35
|
+
if (ArrayBuffer.isView(bytes)) return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
36
|
+
if (bytes instanceof ArrayBuffer) return new Uint8Array(bytes)
|
|
37
|
+
return Uint8Array.from(bytes)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class Base93Encoder {
|
|
41
|
+
constructor (prefix = '') {
|
|
42
|
+
this.queuedBits = 0
|
|
43
|
+
this.bitCount = 0
|
|
44
|
+
this.parts = prefix ? [String(prefix)] : []
|
|
45
|
+
this.finished = false
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
update (bytes) {
|
|
49
|
+
if (this.finished) throw new Error('Base93 encoder is already finalized.')
|
|
50
|
+
const source = asBytes(bytes)
|
|
51
|
+
const output = new Uint16Array(Math.ceil(source.length * 8 / 6.5) + 4)
|
|
52
|
+
let position = 0
|
|
53
|
+
let queuedBits = this.queuedBits
|
|
54
|
+
let bitCount = this.bitCount
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < source.length; i++) {
|
|
57
|
+
queuedBits |= source[i] << bitCount
|
|
58
|
+
bitCount += 8
|
|
59
|
+
if (bitCount > 13) {
|
|
60
|
+
let value = queuedBits & 0x1fff
|
|
61
|
+
if (value > 456) {
|
|
62
|
+
queuedBits >>>= 13
|
|
63
|
+
bitCount -= 13
|
|
64
|
+
} else {
|
|
65
|
+
value = queuedBits & 0x3fff
|
|
66
|
+
queuedBits >>>= 14
|
|
67
|
+
bitCount -= 14
|
|
68
|
+
}
|
|
69
|
+
output[position++] = ENCODING_TABLE[value % 93]
|
|
70
|
+
output[position++] = ENCODING_TABLE[Math.floor(value / 93)]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.queuedBits = queuedBits
|
|
75
|
+
this.bitCount = bitCount
|
|
76
|
+
if (position > 0) this.parts.push(codesToString(output, position))
|
|
77
|
+
return this
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getEncoded () {
|
|
81
|
+
if (!this.finished) {
|
|
82
|
+
if (this.bitCount > 0) {
|
|
83
|
+
const output = new Uint16Array(2)
|
|
84
|
+
let position = 0
|
|
85
|
+
output[position++] = ENCODING_TABLE[this.queuedBits % 93]
|
|
86
|
+
if (this.bitCount > 7 || this.queuedBits > 92) {
|
|
87
|
+
output[position++] = ENCODING_TABLE[Math.floor(this.queuedBits / 93)]
|
|
88
|
+
}
|
|
89
|
+
this.parts.push(codesToString(output, position))
|
|
90
|
+
}
|
|
91
|
+
this.finished = true
|
|
92
|
+
this.queuedBits = 0
|
|
93
|
+
this.bitCount = 0
|
|
94
|
+
}
|
|
95
|
+
return this.parts.join('')
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function encode (bytes) {
|
|
100
|
+
return new Base93Encoder().update(bytes).getEncoded()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function decodeUnchecked (value) {
|
|
104
|
+
const output = new Uint8Array(Math.ceil(value.length * 7 / 8))
|
|
105
|
+
let queuedBits = 0
|
|
106
|
+
let bitCount = 0
|
|
107
|
+
let first = -1
|
|
108
|
+
let position = 0
|
|
109
|
+
|
|
110
|
+
for (let i = 0; i < value.length; i++) {
|
|
111
|
+
const code = value.charCodeAt(i)
|
|
112
|
+
if (code >= DECODING_TABLE.length || DECODING_TABLE[code] < 0) {
|
|
113
|
+
throw new Error(`Invalid Base93 character at offset ${i}.`)
|
|
114
|
+
}
|
|
115
|
+
const decoded = DECODING_TABLE[code]
|
|
116
|
+
if (first === -1) {
|
|
117
|
+
first = decoded
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const pair = first + decoded * 93
|
|
122
|
+
first = -1
|
|
123
|
+
queuedBits |= pair << bitCount
|
|
124
|
+
bitCount += (pair & 0x1fff) > 456 ? 13 : 14
|
|
125
|
+
while (bitCount > 7) {
|
|
126
|
+
output[position++] = queuedBits & 0xff
|
|
127
|
+
queuedBits >>>= 8
|
|
128
|
+
bitCount -= 8
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (first !== -1) output[position++] = (queuedBits | (first << bitCount)) & 0xff
|
|
133
|
+
return output.slice(0, position)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function decode (text, offset = 0, length = -1) {
|
|
137
|
+
if (typeof text !== 'string') throw new TypeError('Base93 input must be a string.')
|
|
138
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > text.length) throw new RangeError('Invalid Base93 offset.')
|
|
139
|
+
if (!Number.isSafeInteger(length) || length < -1) throw new RangeError('Invalid Base93 length.')
|
|
140
|
+
|
|
141
|
+
const end = length < 0 ? text.length : Math.min(text.length, offset + length)
|
|
142
|
+
const encoded = text.slice(offset, end)
|
|
143
|
+
const bytes = decodeUnchecked(encoded)
|
|
144
|
+
if (encode(bytes) !== encoded) throw new Error('Non-canonical or truncated Base93 input.')
|
|
145
|
+
return bytes
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function normalizeSource (source) {
|
|
149
|
+
if (typeof source === 'function') source = source()
|
|
150
|
+
if (typeof source === 'string') return [source]
|
|
151
|
+
if (source?.[Symbol.asyncIterator] || source?.[Symbol.iterator]) return source
|
|
152
|
+
throw new TypeError('Base93 stream source must be iterable.')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export class Base93Decoder {
|
|
156
|
+
constructor (source, { mimeType = '', preferTextStreamDecoding = false } = {}) {
|
|
157
|
+
this.source = normalizeSource(source)
|
|
158
|
+
this.asText = preferTextStreamDecoding && mimeType.startsWith('text/')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async * decodedValues () {
|
|
162
|
+
const textDecoder = this.asText ? new TextDecoder() : null
|
|
163
|
+
for await (const encoded of this.source) {
|
|
164
|
+
const bytes = decode(encoded)
|
|
165
|
+
const value = textDecoder ? textDecoder.decode(bytes, { stream: true }) : bytes
|
|
166
|
+
if (value.length > 0) yield value
|
|
167
|
+
}
|
|
168
|
+
if (textDecoder) {
|
|
169
|
+
const tail = textDecoder.decode()
|
|
170
|
+
if (tail.length > 0) yield tail
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
getDecoded () {
|
|
175
|
+
const iterator = this.decodedValues()[Symbol.asyncIterator]()
|
|
176
|
+
return new ReadableStream({
|
|
177
|
+
async pull (controller) {
|
|
178
|
+
try {
|
|
179
|
+
const { value, done } = await iterator.next()
|
|
180
|
+
if (done) controller.close()
|
|
181
|
+
else controller.enqueue(value)
|
|
182
|
+
} catch (error) {
|
|
183
|
+
controller.error(error)
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
async cancel () {
|
|
187
|
+
await iterator.return?.()
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export default Base93Decoder
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libp2r2p",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Peer-to-relay-to-peer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"p2r2p",
|
|
@@ -11,6 +11,27 @@
|
|
|
11
11
|
"author": "arthurfranca",
|
|
12
12
|
"type": "module",
|
|
13
13
|
"sideEffects": false,
|
|
14
|
+
"files": [
|
|
15
|
+
"base16",
|
|
16
|
+
"base64",
|
|
17
|
+
"base93",
|
|
18
|
+
"content-key",
|
|
19
|
+
"double-dh",
|
|
20
|
+
"ecdh",
|
|
21
|
+
"idb",
|
|
22
|
+
"idb-queue",
|
|
23
|
+
"index.js",
|
|
24
|
+
"key",
|
|
25
|
+
"network",
|
|
26
|
+
"nip44-v3",
|
|
27
|
+
"nip46",
|
|
28
|
+
"private-channel",
|
|
29
|
+
"private-message",
|
|
30
|
+
"private-messenger",
|
|
31
|
+
"relay",
|
|
32
|
+
"temporary-storage",
|
|
33
|
+
"web-storage-queue"
|
|
34
|
+
],
|
|
14
35
|
"scripts": {
|
|
15
36
|
"test": "node --test --experimental-test-module-mocks 'tests/**/*.test.js'",
|
|
16
37
|
"test:only": "node --test --test-only --experimental-test-module-mocks 'tests/**/*.test.js'"
|
|
@@ -19,6 +40,7 @@
|
|
|
19
40
|
".": "./index.js",
|
|
20
41
|
"./base16": "./base16/index.js",
|
|
21
42
|
"./base64": "./base64/index.js",
|
|
43
|
+
"./base93": "./base93/index.js",
|
|
22
44
|
"./content-key": "./content-key/index.js",
|
|
23
45
|
"./content-key/event": "./content-key/event/index.js",
|
|
24
46
|
"./double-dh": "./double-dh/index.js",
|
package/private-channel/index.js
CHANGED
|
@@ -527,13 +527,13 @@ export async function publish ({ senderSigner, imkcSigner, privateChannelSigner
|
|
|
527
527
|
} finally {
|
|
528
528
|
cleanupEnvelopeRows(context.preparedRows)
|
|
529
529
|
}
|
|
530
|
-
return
|
|
530
|
+
return results
|
|
531
531
|
}
|
|
532
532
|
|
|
533
533
|
for await (const wrappedEvent of wrapEvents({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers, receiverTag, deletionPubkey: normalizedDeletionPubkey, event, expirationSeconds, temporaryStorageArea, _getIykcProofs })) {
|
|
534
534
|
results.push(await _publish(wrappedEvent, withRecoveryRelays(relays, recoveryRelays)))
|
|
535
535
|
}
|
|
536
|
-
return
|
|
536
|
+
return results
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
export async function publishNymEvent ({ nymSigner, privateChannelSigner, privateChannelReaderPubkey, deletionPubkey, event, relays, relayToReceivers, recoveryRelays, expirationSeconds, _publish = sendToRelays }) {
|
|
@@ -543,7 +543,7 @@ export async function publishNymEvent ({ nymSigner, privateChannelSigner, privat
|
|
|
543
543
|
for await (const wrappedEvent of wrapNymEvents({ nymSigner, privateChannelSigner, privateChannelReaderPubkey, deletionPubkey: normalizedDeletionPubkey, event, expirationSeconds })) {
|
|
544
544
|
results.push(await _publish(wrappedEvent, publishRelays))
|
|
545
545
|
}
|
|
546
|
-
return
|
|
546
|
+
return results
|
|
547
547
|
}
|
|
548
548
|
|
|
549
549
|
function readSignerFromMap (signersByPubkey, pubkey) {
|
package/private-message/index.js
CHANGED
|
@@ -21,22 +21,32 @@ function uniq (values) {
|
|
|
21
21
|
return [...new Set((values || []).filter(Boolean))]
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function
|
|
25
|
-
if (deletionPubkey
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
return { deletionPubkey: deletionPubkey.toLowerCase() }
|
|
24
|
+
function normalizeDeletionPubkey (deletionPubkey) {
|
|
25
|
+
if (deletionPubkey === undefined) return undefined
|
|
26
|
+
if (typeof deletionPubkey !== 'string' || !HEX_PUBKEY.test(deletionPubkey)) {
|
|
27
|
+
throw new Error('INVALID_DELETION_PUBKEY')
|
|
30
28
|
}
|
|
29
|
+
return deletionPubkey.toLowerCase()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveDeletionCapability ({ deletionPubkey, deletionSeckey, autoDeletionCapability = true }) {
|
|
33
|
+
if (deletionSeckey !== undefined) throw new Error('DELETION_SECKEY_NOT_ACCEPTED')
|
|
34
|
+
if (typeof autoDeletionCapability !== 'boolean') throw new Error('AUTO_DELETION_CAPABILITY_BOOLEAN_REQUIRED')
|
|
35
|
+
|
|
36
|
+
const normalizedDeletionPubkey = normalizeDeletionPubkey(deletionPubkey)
|
|
37
|
+
if (normalizedDeletionPubkey) return { deletionPubkey: normalizedDeletionPubkey }
|
|
38
|
+
if (!autoDeletionCapability) return {}
|
|
39
|
+
|
|
31
40
|
const { pubkey, seckey } = generateKeypair()
|
|
32
41
|
return { deletionPubkey: pubkey, deletionSeckey: seckey }
|
|
33
42
|
}
|
|
34
43
|
|
|
35
|
-
function
|
|
44
|
+
function withDelivery (result, reports, deletionSeckey) {
|
|
45
|
+
const delivery = { reports }
|
|
46
|
+
if (deletionSeckey !== undefined) delivery.deletionSeckey = deletionSeckey
|
|
36
47
|
return {
|
|
37
48
|
...result,
|
|
38
|
-
|
|
39
|
-
...(capability.deletionSeckey && { deletionSeckey: capability.deletionSeckey })
|
|
49
|
+
delivery
|
|
40
50
|
}
|
|
41
51
|
}
|
|
42
52
|
|
|
@@ -457,8 +467,10 @@ export async function ask ({
|
|
|
457
467
|
content,
|
|
458
468
|
expirationSeconds,
|
|
459
469
|
temporaryStorageArea,
|
|
460
|
-
deletionPubkey,
|
|
461
470
|
_getIykcProofs,
|
|
471
|
+
deletionPubkey,
|
|
472
|
+
deletionSeckey,
|
|
473
|
+
autoDeletionCapability = true,
|
|
462
474
|
_publish = privateChannel.publish
|
|
463
475
|
}) {
|
|
464
476
|
if (!receiverPubkey) throw new Error('RECEIVER_PUBKEY_REQUIRED')
|
|
@@ -474,10 +486,10 @@ export async function ask ({
|
|
|
474
486
|
message: message || { code, payload, error, content }
|
|
475
487
|
})
|
|
476
488
|
})
|
|
477
|
-
const
|
|
478
|
-
const
|
|
489
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
490
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers: [receiverPubkey], receiverTag: receiverPubkey, deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
479
491
|
|
|
480
|
-
return
|
|
492
|
+
return withDelivery({ question }, reports, deletion.deletionSeckey)
|
|
481
493
|
}
|
|
482
494
|
|
|
483
495
|
export async function reply ({
|
|
@@ -497,8 +509,10 @@ export async function reply ({
|
|
|
497
509
|
content,
|
|
498
510
|
expirationSeconds,
|
|
499
511
|
temporaryStorageArea,
|
|
500
|
-
deletionPubkey,
|
|
501
512
|
_getIykcProofs,
|
|
513
|
+
deletionPubkey,
|
|
514
|
+
deletionSeckey,
|
|
515
|
+
autoDeletionCapability = true,
|
|
502
516
|
_publish = privateChannel.publish
|
|
503
517
|
}) {
|
|
504
518
|
if (!question?.id) throw new Error('QUESTION_REQUIRED')
|
|
@@ -511,9 +525,9 @@ export async function reply ({
|
|
|
511
525
|
message: message || { code, payload, error, content }
|
|
512
526
|
})
|
|
513
527
|
})
|
|
514
|
-
const
|
|
515
|
-
const
|
|
516
|
-
return
|
|
528
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
529
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers: [receiverPubkey], receiverTag: receiverPubkey, deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
530
|
+
return withDelivery({ reply: event }, reports, deletion.deletionSeckey)
|
|
517
531
|
}
|
|
518
532
|
|
|
519
533
|
export async function tell ({
|
|
@@ -532,8 +546,10 @@ export async function tell ({
|
|
|
532
546
|
content,
|
|
533
547
|
expirationSeconds,
|
|
534
548
|
temporaryStorageArea,
|
|
535
|
-
deletionPubkey,
|
|
536
549
|
_getIykcProofs,
|
|
550
|
+
deletionPubkey,
|
|
551
|
+
deletionSeckey,
|
|
552
|
+
autoDeletionCapability = true,
|
|
537
553
|
_publish = privateChannel.publish
|
|
538
554
|
}) {
|
|
539
555
|
if (!receiverPubkey) throw new Error('RECEIVER_PUBKEY_REQUIRED')
|
|
@@ -545,9 +561,9 @@ export async function tell ({
|
|
|
545
561
|
message: message || { code, payload, error, content }
|
|
546
562
|
})
|
|
547
563
|
})
|
|
548
|
-
const
|
|
549
|
-
const
|
|
550
|
-
return
|
|
564
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
565
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers: [receiverPubkey], receiverTag: receiverPubkey, deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
566
|
+
return withDelivery({ tell: event }, reports, deletion.deletionSeckey)
|
|
551
567
|
}
|
|
552
568
|
|
|
553
569
|
export async function yell ({
|
|
@@ -566,8 +582,10 @@ export async function yell ({
|
|
|
566
582
|
content,
|
|
567
583
|
expirationSeconds,
|
|
568
584
|
temporaryStorageArea,
|
|
569
|
-
deletionPubkey,
|
|
570
585
|
_getIykcProofs,
|
|
586
|
+
deletionPubkey,
|
|
587
|
+
deletionSeckey,
|
|
588
|
+
autoDeletionCapability = true,
|
|
571
589
|
_publish = privateChannel.publish
|
|
572
590
|
}) {
|
|
573
591
|
const receivers = uniq(receiverPubkeys)
|
|
@@ -580,9 +598,9 @@ export async function yell ({
|
|
|
580
598
|
message: message || { code, payload, error, content }
|
|
581
599
|
})
|
|
582
600
|
})
|
|
583
|
-
const
|
|
584
|
-
const
|
|
585
|
-
return
|
|
601
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
602
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers, receiverTag: '', deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
603
|
+
return withDelivery({ yell: event }, reports, deletion.deletionSeckey)
|
|
586
604
|
}
|
|
587
605
|
|
|
588
606
|
export async function broadcastRumor ({
|
|
@@ -597,16 +615,18 @@ export async function broadcastRumor ({
|
|
|
597
615
|
rumor,
|
|
598
616
|
expirationSeconds,
|
|
599
617
|
temporaryStorageArea,
|
|
600
|
-
deletionPubkey,
|
|
601
618
|
_getIykcProofs,
|
|
619
|
+
deletionPubkey,
|
|
620
|
+
deletionSeckey,
|
|
621
|
+
autoDeletionCapability = true,
|
|
602
622
|
_publish = privateChannel.publish
|
|
603
623
|
}) {
|
|
604
624
|
const receivers = uniq(receiverPubkeys)
|
|
605
625
|
if (!receivers.length) throw new Error('NO_RECEIVERS')
|
|
606
626
|
const { event, wireEvent } = await makeOutgoingRumor({ senderSigner, rumor })
|
|
607
|
-
const
|
|
608
|
-
const
|
|
609
|
-
return
|
|
627
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
628
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers, receiverTag: '', deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
629
|
+
return withDelivery({ rumor: event }, reports, deletion.deletionSeckey)
|
|
610
630
|
}
|
|
611
631
|
|
|
612
632
|
export async function broadcastEvent ({
|
|
@@ -621,16 +641,18 @@ export async function broadcastEvent ({
|
|
|
621
641
|
event,
|
|
622
642
|
expirationSeconds,
|
|
623
643
|
temporaryStorageArea,
|
|
624
|
-
deletionPubkey,
|
|
625
644
|
_getIykcProofs,
|
|
645
|
+
deletionPubkey,
|
|
646
|
+
deletionSeckey,
|
|
647
|
+
autoDeletionCapability = true,
|
|
626
648
|
_publish = privateChannel.publish
|
|
627
649
|
}) {
|
|
628
650
|
const receivers = uniq(receiverPubkeys)
|
|
629
651
|
if (!receivers.length) throw new Error('NO_RECEIVERS')
|
|
630
652
|
const wireEvent = assertValidSignedEvent({ ...event, tags: cloneTags(event?.tags) })
|
|
631
|
-
const
|
|
632
|
-
const
|
|
633
|
-
return
|
|
653
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
654
|
+
const reports = await sendPrivateMessage({ senderSigner, imkcSigner, privateChannelSigner, privateChannelReaderPubkey, receivers, receiverTag: '', deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, temporaryStorageArea, _getIykcProofs, _publish })
|
|
655
|
+
return withDelivery({ event: wireEvent }, reports, deletion.deletionSeckey)
|
|
634
656
|
}
|
|
635
657
|
|
|
636
658
|
export async function broadcastNymRumor ({
|
|
@@ -643,13 +665,15 @@ export async function broadcastNymRumor ({
|
|
|
643
665
|
rumor,
|
|
644
666
|
expirationSeconds,
|
|
645
667
|
deletionPubkey,
|
|
668
|
+
deletionSeckey,
|
|
669
|
+
autoDeletionCapability = true,
|
|
646
670
|
_publish = privateChannel.publishNymEvent
|
|
647
671
|
}) {
|
|
648
672
|
if (!nymSigner?.getPublicKey) throw new Error('NYM_SIGNER_REQUIRED')
|
|
649
673
|
const { event, wireEvent } = await makeOutgoingRumor({ senderSigner: nymSigner, rumor })
|
|
650
|
-
const
|
|
651
|
-
const
|
|
652
|
-
return
|
|
674
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
675
|
+
const reports = await sendNymMessage({ nymSigner, privateChannelSigner, privateChannelReaderPubkey, deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, _publish })
|
|
676
|
+
return withDelivery({ rumor: event }, reports, deletion.deletionSeckey)
|
|
653
677
|
}
|
|
654
678
|
|
|
655
679
|
export async function broadcastNymEvent ({
|
|
@@ -662,11 +686,13 @@ export async function broadcastNymEvent ({
|
|
|
662
686
|
event,
|
|
663
687
|
expirationSeconds,
|
|
664
688
|
deletionPubkey,
|
|
689
|
+
deletionSeckey,
|
|
690
|
+
autoDeletionCapability = true,
|
|
665
691
|
_publish = privateChannel.publishNymEvent
|
|
666
692
|
}) {
|
|
667
693
|
if (!nymSigner?.getPublicKey) throw new Error('NYM_SIGNER_REQUIRED')
|
|
668
694
|
const wireEvent = assertValidSignedEvent({ ...event, tags: cloneTags(event?.tags) })
|
|
669
|
-
const
|
|
670
|
-
const
|
|
671
|
-
return
|
|
695
|
+
const deletion = resolveDeletionCapability({ deletionPubkey, deletionSeckey, autoDeletionCapability })
|
|
696
|
+
const reports = await sendNymMessage({ nymSigner, privateChannelSigner, privateChannelReaderPubkey, deletionPubkey: deletion.deletionPubkey, event: wireEvent, relays, relayToReceivers, recoveryRelays, expirationSeconds, _publish })
|
|
697
|
+
return withDelivery({ event: wireEvent }, reports, deletion.deletionSeckey)
|
|
672
698
|
}
|