mirror of https://github.com/waku-org/js-waku.git
Allow specifying decryption methods and content topic (#409)
This commit is contained in:
parent
f9d066252c
commit
96cf24d34e
|
@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Implement DNS Discovery as per [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459),
|
||||
with ENR records as defined in [31/WAKU2-ENR](https://rfc.vac.dev/spec/31/);
|
||||
Available by passing `{ bootstrap: { enrUrl: enrtree://... } }` to `Waku.create`.
|
||||
- When using `addDecryptionKey`,
|
||||
it is now possible to specify the decryption method and the content topics of the messages to decrypt;
|
||||
this is to reduce the number of decryption attempt done and improve performance.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -20,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Minimum node version changed to 16.
|
||||
- **Breaking**: Changed `Waku.create` bootstrap option from `{ bootstrap: boolean }` to `{ bootstrap: BootstrapOptions }`.
|
||||
Replace `{ boostrap: true }` with `{ boostrap: { default: true } }` to retain same behaviour.
|
||||
- **Breaking**: `WakuMessage.decode` and `WakuMessage.decodeProto` now accepts method and content topics for the decryption key.
|
||||
`WakuMessage.decode(bytes, [key])` becomes `WakuMessage.decode(bytes, [{key: key}])`.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -18,11 +18,10 @@ import Ping from 'libp2p/src/ping';
|
|||
import { Multiaddr, multiaddr } from 'multiaddr';
|
||||
import PeerId from 'peer-id';
|
||||
|
||||
import { Bootstrap } from './discovery';
|
||||
import { BootstrapOptions } from './discovery/bootstrap';
|
||||
import { Bootstrap, BootstrapOptions } from './discovery';
|
||||
import { getPeersForProtocol } from './select_peer';
|
||||
import { LightPushCodec, WakuLightPush } from './waku_light_push';
|
||||
import { WakuMessage } from './waku_message';
|
||||
import { DecryptionMethod, WakuMessage } from './waku_message';
|
||||
import { RelayCodecs, WakuRelay } from './waku_relay';
|
||||
import { RelayPingContentTopic } from './waku_relay/constants';
|
||||
import { StoreCodec, WakuStore } from './waku_store';
|
||||
|
@ -135,7 +134,9 @@ export class Waku {
|
|||
this.stopKeepAlive(connection.remotePeer);
|
||||
});
|
||||
|
||||
options?.decryptionKeys?.forEach(this.addDecryptionKey);
|
||||
options?.decryptionKeys?.forEach((key) => {
|
||||
this.addDecryptionKey(key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,9 +271,12 @@ export class Waku {
|
|||
*
|
||||
* Strings must be in hex format.
|
||||
*/
|
||||
addDecryptionKey(key: Uint8Array | string): void {
|
||||
this.relay.addDecryptionKey(key);
|
||||
this.store.addDecryptionKey(key);
|
||||
addDecryptionKey(
|
||||
key: Uint8Array | string,
|
||||
options?: { method?: DecryptionMethod; contentTopics?: string[] }
|
||||
): void {
|
||||
this.relay.addDecryptionKey(key, options);
|
||||
this.store.addDecryptionKey(key, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,15 +36,15 @@ describe('Waku Message: Browser & Node', function () {
|
|||
fc.asyncProperty(
|
||||
fc.uint8Array({ minLength: 1 }),
|
||||
fc.uint8Array({ minLength: 32, maxLength: 32 }),
|
||||
async (payload, privKey) => {
|
||||
const publicKey = getPublicKey(privKey);
|
||||
async (payload, key) => {
|
||||
const publicKey = getPublicKey(key);
|
||||
|
||||
const msg = await WakuMessage.fromBytes(payload, TestContentTopic, {
|
||||
encPublicKey: publicKey,
|
||||
});
|
||||
|
||||
const wireBytes = msg.encode();
|
||||
const actual = await WakuMessage.decode(wireBytes, [privKey]);
|
||||
const actual = await WakuMessage.decode(wireBytes, [{ key }]);
|
||||
|
||||
expect(actual?.payload).to.deep.equal(payload);
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ describe('Waku Message: Browser & Node', function () {
|
|||
});
|
||||
|
||||
const wireBytes = msg.encode();
|
||||
const actual = await WakuMessage.decode(wireBytes, [encPrivKey]);
|
||||
const actual = await WakuMessage.decode(wireBytes, [
|
||||
{ key: encPrivKey },
|
||||
]);
|
||||
|
||||
expect(actual?.payload).to.deep.equal(payload);
|
||||
expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey);
|
||||
|
@ -88,7 +90,7 @@ describe('Waku Message: Browser & Node', function () {
|
|||
});
|
||||
|
||||
const wireBytes = msg.encode();
|
||||
const actual = await WakuMessage.decode(wireBytes, [key]);
|
||||
const actual = await WakuMessage.decode(wireBytes, [{ key }]);
|
||||
|
||||
expect(actual?.payload).to.deep.equal(payload);
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ describe('Waku Message: Browser & Node', function () {
|
|||
});
|
||||
|
||||
const wireBytes = msg.encode();
|
||||
const actual = await WakuMessage.decode(wireBytes, [symKey]);
|
||||
const actual = await WakuMessage.decode(wireBytes, [{ key: symKey }]);
|
||||
|
||||
expect(actual?.payload).to.deep.equal(payload);
|
||||
expect(actual?.signaturePublicKey).to.deep.equal(sigPubKey);
|
||||
|
|
|
@ -12,6 +12,11 @@ import * as version_1 from './version_1';
|
|||
const DefaultVersion = 0;
|
||||
const dbg = debug('waku:message');
|
||||
|
||||
export enum DecryptionMethod {
|
||||
Asymmetric = 'asymmetric',
|
||||
Symmetric = 'symmetric',
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
/**
|
||||
* Timestamp to set on the message, defaults to now if not passed.
|
||||
|
@ -44,7 +49,7 @@ export class WakuMessage {
|
|||
) {}
|
||||
|
||||
/**
|
||||
* Create Message with a utf-8 string as payload.
|
||||
* Create Message with an utf-8 string as payload.
|
||||
*/
|
||||
static async fromUtf8String(
|
||||
utf8: string,
|
||||
|
@ -116,11 +121,15 @@ export class WakuMessage {
|
|||
* @params decryptionKeys If the payload is encrypted (version = 1), then the
|
||||
* keys are used to attempt decryption of the message. The passed key can either
|
||||
* be asymmetric private keys or symmetric keys, both method are tried for each
|
||||
* key until the message is decrypted or combinations are ran out.
|
||||
* key until the message is decrypted or combinations are run out.
|
||||
*/
|
||||
static async decode(
|
||||
bytes: Uint8Array,
|
||||
decryptionKeys?: Uint8Array[]
|
||||
decryptionKeys?: Array<{
|
||||
key: Uint8Array;
|
||||
method?: DecryptionMethod;
|
||||
contentTopic?: string[];
|
||||
}>
|
||||
): Promise<WakuMessage | undefined> {
|
||||
const protoBuf = proto.WakuMessage.decode(Reader.create(bytes));
|
||||
|
||||
|
@ -134,11 +143,15 @@ export class WakuMessage {
|
|||
* @params decryptionKeys If the payload is encrypted (version = 1), then the
|
||||
* keys are used to attempt decryption of the message. The passed key can either
|
||||
* be asymmetric private keys or symmetric keys, both method are tried for each
|
||||
* key until the message is decrypted or combinations are ran out.
|
||||
* key until the message is decrypted or combinations are run out.
|
||||
*/
|
||||
static async decodeProto(
|
||||
protoBuf: proto.WakuMessage,
|
||||
decryptionKeys?: Uint8Array[]
|
||||
decryptionKeys?: Array<{
|
||||
key: Uint8Array;
|
||||
method?: DecryptionMethod;
|
||||
contentTopics?: string[];
|
||||
}>
|
||||
): Promise<WakuMessage | undefined> {
|
||||
if (protoBuf.payload === undefined) {
|
||||
dbg('Payload is undefined');
|
||||
|
@ -156,17 +169,55 @@ export class WakuMessage {
|
|||
|
||||
// Returns a bunch of `undefined` and hopefully one decrypted result
|
||||
const allResults = await Promise.all(
|
||||
decryptionKeys.map(async (privateKey) => {
|
||||
try {
|
||||
return await version_1.decryptSymmetric(payload, privateKey);
|
||||
} catch (e) {
|
||||
dbg('Failed to decrypt message using symmetric encryption', e);
|
||||
try {
|
||||
return await version_1.decryptAsymmetric(payload, privateKey);
|
||||
} catch (e) {
|
||||
dbg('Failed to decrypt message using asymmetric encryption', e);
|
||||
return;
|
||||
decryptionKeys.map(async ({ key, method, contentTopics }) => {
|
||||
if (
|
||||
!contentTopics ||
|
||||
(protoBuf.contentTopic &&
|
||||
contentTopics.includes(protoBuf.contentTopic))
|
||||
) {
|
||||
switch (method) {
|
||||
case DecryptionMethod.Asymmetric:
|
||||
try {
|
||||
return await version_1.decryptAsymmetric(payload, key);
|
||||
} catch (e) {
|
||||
dbg(
|
||||
'Failed to decrypt message using symmetric encryption despite decryption method being specified',
|
||||
e
|
||||
);
|
||||
return;
|
||||
}
|
||||
case DecryptionMethod.Symmetric:
|
||||
try {
|
||||
return await version_1.decryptSymmetric(payload, key);
|
||||
} catch (e) {
|
||||
dbg(
|
||||
'Failed to decrypt message using asymmetric encryption despite decryption method being specified',
|
||||
e
|
||||
);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
try {
|
||||
return await version_1.decryptSymmetric(payload, key);
|
||||
} catch (e) {
|
||||
dbg(
|
||||
'Failed to decrypt message using symmetric encryption',
|
||||
e
|
||||
);
|
||||
try {
|
||||
return await version_1.decryptAsymmetric(payload, key);
|
||||
} catch (e) {
|
||||
dbg(
|
||||
'Failed to decrypt message using asymmetric encryption',
|
||||
e
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No key available for this content topic
|
||||
return;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
|
|
@ -12,7 +12,12 @@ import {
|
|||
} from '../../test_utils';
|
||||
import { delay } from '../delay';
|
||||
import { DefaultPubSubTopic, Waku } from '../waku';
|
||||
import { WakuMessage } from '../waku_message';
|
||||
import { DecryptionMethod, WakuMessage } from '../waku_message';
|
||||
import {
|
||||
generatePrivateKey,
|
||||
generateSymmetricKey,
|
||||
getPublicKey,
|
||||
} from '../waku_message/version_1';
|
||||
|
||||
const log = debug('waku:test');
|
||||
|
||||
|
@ -158,6 +163,72 @@ describe('Waku Relay [node only]', () => {
|
|||
expect(allMessages[1].payloadAsUtf8).to.eq(barMessageText);
|
||||
});
|
||||
|
||||
it('Decrypt messages', async function () {
|
||||
this.timeout(10000);
|
||||
|
||||
const encryptedAsymmetricMessageText =
|
||||
'This message is encrypted using asymmetric';
|
||||
const encryptedAsymmetricContentTopic = '/test/1/asymmetric/proto';
|
||||
const encryptedSymmetricMessageText =
|
||||
'This message is encrypted using symmetric encryption';
|
||||
const encryptedSymmetricContentTopic = '/test/1/symmetric/proto';
|
||||
|
||||
const privateKey = generatePrivateKey();
|
||||
const symKey = generateSymmetricKey();
|
||||
const publicKey = getPublicKey(privateKey);
|
||||
|
||||
const [encryptedAsymmetricMessage, encryptedSymmetricMessage] =
|
||||
await Promise.all([
|
||||
WakuMessage.fromUtf8String(
|
||||
encryptedAsymmetricMessageText,
|
||||
encryptedAsymmetricContentTopic,
|
||||
{
|
||||
encPublicKey: publicKey,
|
||||
}
|
||||
),
|
||||
WakuMessage.fromUtf8String(
|
||||
encryptedSymmetricMessageText,
|
||||
encryptedSymmetricContentTopic,
|
||||
{
|
||||
symKey: symKey,
|
||||
}
|
||||
),
|
||||
]);
|
||||
|
||||
waku2.addDecryptionKey(privateKey, {
|
||||
contentTopics: [encryptedAsymmetricContentTopic],
|
||||
method: DecryptionMethod.Asymmetric,
|
||||
});
|
||||
waku2.addDecryptionKey(symKey, {
|
||||
contentTopics: [encryptedSymmetricContentTopic],
|
||||
method: DecryptionMethod.Symmetric,
|
||||
});
|
||||
|
||||
const msgs: WakuMessage[] = [];
|
||||
waku2.relay.addObserver((wakuMsg) => {
|
||||
msgs.push(wakuMsg);
|
||||
});
|
||||
|
||||
await waku1.relay.send(encryptedAsymmetricMessage);
|
||||
await waku1.relay.send(encryptedSymmetricMessage);
|
||||
|
||||
while (msgs.length < 2) {
|
||||
await delay(200);
|
||||
}
|
||||
|
||||
expect(msgs.length).to.eq(2);
|
||||
expect(msgs[0].contentTopic).to.eq(
|
||||
encryptedAsymmetricMessage.contentTopic
|
||||
);
|
||||
expect(msgs[0].version).to.eq(encryptedAsymmetricMessage.version);
|
||||
expect(msgs[0].payloadAsUtf8).to.eq(encryptedAsymmetricMessageText);
|
||||
expect(msgs[1].contentTopic).to.eq(
|
||||
encryptedSymmetricMessage.contentTopic
|
||||
);
|
||||
expect(msgs[1].version).to.eq(encryptedSymmetricMessage.version);
|
||||
expect(msgs[1].payloadAsUtf8).to.eq(encryptedSymmetricMessageText);
|
||||
});
|
||||
|
||||
it('Delete observer', async function () {
|
||||
this.timeout(10000);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import PeerId from 'peer-id';
|
|||
|
||||
import { hexToBuf } from '../utils';
|
||||
import { CreateOptions, DefaultPubSubTopic } from '../waku';
|
||||
import { WakuMessage } from '../waku_message';
|
||||
import { DecryptionMethod, WakuMessage } from '../waku_message';
|
||||
|
||||
import * as constants from './constants';
|
||||
import { RelayCodecs } from './constants';
|
||||
|
@ -65,7 +65,10 @@ export class WakuRelay extends Gossipsub {
|
|||
heartbeat: RelayHeartbeat;
|
||||
pubSubTopic: string;
|
||||
|
||||
public decryptionKeys: Set<Uint8Array>;
|
||||
public decryptionKeys: Map<
|
||||
Uint8Array,
|
||||
{ method?: DecryptionMethod; contentTopics?: string[] }
|
||||
>;
|
||||
|
||||
/**
|
||||
* observers called when receiving new message.
|
||||
|
@ -89,13 +92,17 @@ export class WakuRelay extends Gossipsub {
|
|||
|
||||
this.heartbeat = new RelayHeartbeat(this);
|
||||
this.observers = {};
|
||||
this.decryptionKeys = new Set();
|
||||
this.decryptionKeys = new Map();
|
||||
|
||||
const multicodecs = constants.RelayCodecs;
|
||||
|
||||
Object.assign(this, { multicodecs });
|
||||
|
||||
this.pubSubTopic = options?.pubSubTopic || DefaultPubSubTopic;
|
||||
|
||||
options?.decryptionKeys?.forEach((key) => {
|
||||
this.addDecryptionKey(key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,8 +135,11 @@ export class WakuRelay extends Gossipsub {
|
|||
*
|
||||
* Strings must be in hex format.
|
||||
*/
|
||||
addDecryptionKey(key: Uint8Array | string): void {
|
||||
this.decryptionKeys.add(hexToBuf(key));
|
||||
addDecryptionKey(
|
||||
key: Uint8Array | string,
|
||||
options?: { method?: DecryptionMethod; contentTopics?: string[] }
|
||||
): void {
|
||||
this.decryptionKeys.set(hexToBuf(key), options ?? {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,8 +220,18 @@ export class WakuRelay extends Gossipsub {
|
|||
*/
|
||||
subscribe(pubSubTopic: string): void {
|
||||
this.on(pubSubTopic, (event) => {
|
||||
const decryptionKeys = Array.from(this.decryptionKeys).map(
|
||||
([key, { method, contentTopics }]) => {
|
||||
return {
|
||||
key,
|
||||
method,
|
||||
contentTopics,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
dbg(`Message received on ${pubSubTopic}`);
|
||||
WakuMessage.decode(event.data, Array.from(this.decryptionKeys))
|
||||
WakuMessage.decode(event.data, decryptionKeys)
|
||||
.then((wakuMsg) => {
|
||||
if (!wakuMsg) {
|
||||
dbg('Failed to decode Waku Message');
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from '../../test_utils';
|
||||
import { delay } from '../delay';
|
||||
import { Waku } from '../waku';
|
||||
import { WakuMessage } from '../waku_message';
|
||||
import { DecryptionMethod, WakuMessage } from '../waku_message';
|
||||
import {
|
||||
generatePrivateKey,
|
||||
generateSymmetricKey,
|
||||
|
@ -335,6 +335,122 @@ describe('Waku Store', () => {
|
|||
await Promise.all([waku1.stop(), waku2.stop()]);
|
||||
});
|
||||
|
||||
it('Retrieves history with asymmetric & symmetric encrypted messages on different content topics', async function () {
|
||||
this.timeout(10_000);
|
||||
|
||||
nimWaku = new NimWaku(makeLogFileName(this));
|
||||
await nimWaku.start({ persistMessages: true, lightpush: true });
|
||||
|
||||
const encryptedAsymmetricMessageText =
|
||||
'This message is encrypted for me using asymmetric';
|
||||
const encryptedAsymmetricContentTopic = '/test/1/asymmetric/proto';
|
||||
const encryptedSymmetricMessageText =
|
||||
'This message is encrypted for me using symmetric encryption';
|
||||
const encryptedSymmetricContentTopic = '/test/1/symmetric/proto';
|
||||
const clearMessageText =
|
||||
'This is a clear text message for everyone to read';
|
||||
const otherEncMessageText =
|
||||
'This message is not for and I must not be able to read it';
|
||||
|
||||
const privateKey = generatePrivateKey();
|
||||
const symKey = generateSymmetricKey();
|
||||
const publicKey = getPublicKey(privateKey);
|
||||
|
||||
const [
|
||||
encryptedAsymmetricMessage,
|
||||
encryptedSymmetricMessage,
|
||||
clearMessage,
|
||||
otherEncMessage,
|
||||
] = await Promise.all([
|
||||
WakuMessage.fromUtf8String(
|
||||
encryptedAsymmetricMessageText,
|
||||
encryptedAsymmetricContentTopic,
|
||||
{
|
||||
encPublicKey: publicKey,
|
||||
}
|
||||
),
|
||||
WakuMessage.fromUtf8String(
|
||||
encryptedSymmetricMessageText,
|
||||
encryptedSymmetricContentTopic,
|
||||
{
|
||||
symKey: symKey,
|
||||
}
|
||||
),
|
||||
WakuMessage.fromUtf8String(
|
||||
clearMessageText,
|
||||
encryptedAsymmetricContentTopic
|
||||
),
|
||||
WakuMessage.fromUtf8String(
|
||||
otherEncMessageText,
|
||||
encryptedSymmetricContentTopic,
|
||||
{
|
||||
encPublicKey: getPublicKey(generatePrivateKey()),
|
||||
}
|
||||
),
|
||||
]);
|
||||
|
||||
dbg('Messages have been encrypted');
|
||||
|
||||
const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([
|
||||
Waku.create({
|
||||
staticNoiseKey: NOISE_KEY_1,
|
||||
libp2p: { modules: { transport: [TCP] } },
|
||||
}),
|
||||
Waku.create({
|
||||
staticNoiseKey: NOISE_KEY_2,
|
||||
libp2p: { modules: { transport: [TCP] } },
|
||||
}),
|
||||
nimWaku.getMultiaddrWithId(),
|
||||
]);
|
||||
|
||||
dbg('Waku nodes created');
|
||||
|
||||
await Promise.all([
|
||||
waku1.dial(nimWakuMultiaddr),
|
||||
waku2.dial(nimWakuMultiaddr),
|
||||
]);
|
||||
|
||||
dbg('Waku nodes connected to nim Waku');
|
||||
|
||||
let lightPushPeers = waku1.lightPush.peers;
|
||||
while (lightPushPeers.length == 0) {
|
||||
await delay(100);
|
||||
lightPushPeers = waku1.lightPush.peers;
|
||||
}
|
||||
|
||||
dbg('Sending messages using light push');
|
||||
await Promise.all([
|
||||
waku1.lightPush.push(encryptedAsymmetricMessage),
|
||||
waku1.lightPush.push(encryptedSymmetricMessage),
|
||||
waku1.lightPush.push(otherEncMessage),
|
||||
waku1.lightPush.push(clearMessage),
|
||||
]);
|
||||
|
||||
let storePeers = waku2.store.peers;
|
||||
while (storePeers.length == 0) {
|
||||
await delay(100);
|
||||
storePeers = waku2.store.peers;
|
||||
}
|
||||
|
||||
waku2.addDecryptionKey(symKey, {
|
||||
contentTopics: [encryptedSymmetricContentTopic],
|
||||
method: DecryptionMethod.Symmetric,
|
||||
});
|
||||
|
||||
dbg('Retrieve messages from store');
|
||||
const messages = await waku2.store.queryHistory([], {
|
||||
decryptionKeys: [privateKey],
|
||||
});
|
||||
|
||||
expect(messages?.length).eq(3);
|
||||
if (!messages) throw 'Length was tested';
|
||||
expect(messages[0].payloadAsUtf8).to.eq(clearMessageText);
|
||||
expect(messages[1].payloadAsUtf8).to.eq(encryptedSymmetricMessageText);
|
||||
expect(messages[2].payloadAsUtf8).to.eq(encryptedAsymmetricMessageText);
|
||||
|
||||
await Promise.all([waku1.stop(), waku2.stop()]);
|
||||
});
|
||||
|
||||
it('Retrieves history using start and end time', async function () {
|
||||
this.timeout(5_000);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { HistoryResponse_Error } from '../../proto';
|
|||
import { getPeersForProtocol, selectRandomPeer } from '../select_peer';
|
||||
import { hexToBuf } from '../utils';
|
||||
import { DefaultPubSubTopic } from '../waku';
|
||||
import { WakuMessage } from '../waku_message';
|
||||
import { DecryptionMethod, WakuMessage } from '../waku_message';
|
||||
|
||||
import { HistoryRPC, PageDirection } from './history_rpc';
|
||||
|
||||
|
@ -96,7 +96,10 @@ export interface QueryOptions {
|
|||
*/
|
||||
export class WakuStore {
|
||||
pubSubTopic: string;
|
||||
public decryptionKeys: Set<Uint8Array>;
|
||||
public decryptionKeys: Map<
|
||||
Uint8Array,
|
||||
{ method?: DecryptionMethod; contentTopics?: string[] }
|
||||
>;
|
||||
|
||||
constructor(public libp2p: Libp2p, options?: CreateOptions) {
|
||||
if (options?.pubSubTopic) {
|
||||
|
@ -105,7 +108,7 @@ export class WakuStore {
|
|||
this.pubSubTopic = DefaultPubSubTopic;
|
||||
}
|
||||
|
||||
this.decryptionKeys = new Set();
|
||||
this.decryptionKeys = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,10 +160,25 @@ export class WakuStore {
|
|||
const connection = this.libp2p.connectionManager.get(peer.id);
|
||||
if (!connection) throw 'Failed to get a connection to the peer';
|
||||
|
||||
const decryptionKeys = Array.from(this.decryptionKeys.values());
|
||||
const decryptionKeys = Array.from(this.decryptionKeys).map(
|
||||
([key, { method, contentTopics }]) => {
|
||||
return {
|
||||
key,
|
||||
method,
|
||||
contentTopics,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Add the decryption keys passed to this function against the
|
||||
// content topics also passed to this function.
|
||||
if (opts.decryptionKeys) {
|
||||
opts.decryptionKeys.forEach((key) => {
|
||||
decryptionKeys.push(hexToBuf(key));
|
||||
decryptionKeys.push({
|
||||
key: hexToBuf(key),
|
||||
contentTopics: contentTopics.length ? contentTopics : undefined,
|
||||
method: undefined,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -248,8 +266,11 @@ export class WakuStore {
|
|||
*
|
||||
* Strings must be in hex format.
|
||||
*/
|
||||
addDecryptionKey(key: Uint8Array | string): void {
|
||||
this.decryptionKeys.add(hexToBuf(key));
|
||||
addDecryptionKey(
|
||||
key: Uint8Array | string,
|
||||
options?: { method?: DecryptionMethod; contentTopics?: string[] }
|
||||
): void {
|
||||
this.decryptionKeys.set(hexToBuf(key), options ?? {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue