@dxos/echo-db 2.33.8-dev.8609bc45 → 2.33.9-dev.e605934d
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/dist/src/echo.test.js +10 -10
- package/dist/src/echo.test.js.map +1 -1
- package/dist/src/halo/halo-factory.d.ts +1 -1
- package/dist/src/halo/halo-factory.d.ts.map +1 -1
- package/dist/src/halo/halo-factory.js +8 -8
- package/dist/src/halo/halo-factory.js.map +1 -1
- package/dist/src/halo/halo-party.d.ts +4 -6
- package/dist/src/halo/halo-party.d.ts.map +1 -1
- package/dist/src/halo/halo-party.js +10 -4
- package/dist/src/halo/halo-party.js.map +1 -1
- package/dist/src/halo/halo.d.ts.map +1 -1
- package/dist/src/halo/halo.js +2 -1
- package/dist/src/halo/halo.js.map +1 -1
- package/dist/src/halo/identity-manager.d.ts.map +1 -1
- package/dist/src/halo/identity-manager.js +8 -2
- package/dist/src/halo/identity-manager.js.map +1 -1
- package/dist/src/halo/party-opener.d.ts.map +1 -1
- package/dist/src/halo/party-opener.js +2 -4
- package/dist/src/halo/party-opener.js.map +1 -1
- package/dist/src/halo/preferences.d.ts.map +1 -1
- package/dist/src/halo/preferences.js +3 -6
- package/dist/src/halo/preferences.js.map +1 -1
- package/dist/src/invitations/greeting-initiator.d.ts +5 -4
- package/dist/src/invitations/greeting-initiator.d.ts.map +1 -1
- package/dist/src/invitations/greeting-initiator.js +4 -5
- package/dist/src/invitations/greeting-initiator.js.map +1 -1
- package/dist/src/invitations/greeting-protocol-provider.js +2 -2
- package/dist/src/invitations/greeting-protocol-provider.js.map +1 -1
- package/dist/src/invitations/greeting-responder.d.ts +4 -7
- package/dist/src/invitations/greeting-responder.d.ts.map +1 -1
- package/dist/src/invitations/greeting-responder.js +7 -21
- package/dist/src/invitations/greeting-responder.js.map +1 -1
- package/dist/src/invitations/halo-recovery-initiator.js +2 -2
- package/dist/src/invitations/halo-recovery-initiator.js.map +1 -1
- package/dist/src/invitations/invitation-descriptor.js +3 -3
- package/dist/src/invitations/invitation-descriptor.js.map +1 -1
- package/dist/src/invitations/invitation-factory.d.ts +2 -1
- package/dist/src/invitations/invitation-factory.d.ts.map +1 -1
- package/dist/src/invitations/invitation-factory.js +3 -5
- package/dist/src/invitations/invitation-factory.js.map +1 -1
- package/dist/src/invitations/offline-invitation-claimer.js +2 -2
- package/dist/src/invitations/offline-invitation-claimer.js.map +1 -1
- package/dist/src/packlets/database/data-mirror.test.js +1 -1
- package/dist/src/packlets/database/data-mirror.test.js.map +1 -1
- package/dist/src/packlets/database/item-demuxer.test.js +1 -1
- package/dist/src/packlets/database/item-demuxer.test.js.map +1 -1
- package/dist/src/packlets/database/testing.js +1 -1
- package/dist/src/packlets/database/testing.js.map +1 -1
- package/dist/src/packlets/database/timeframe-clock.d.ts +2 -1
- package/dist/src/packlets/database/timeframe-clock.d.ts.map +1 -1
- package/dist/src/packlets/database/timeframe-clock.js +15 -5
- package/dist/src/packlets/database/timeframe-clock.js.map +1 -1
- package/dist/src/parties/data-party.d.ts +4 -3
- package/dist/src/parties/data-party.d.ts.map +1 -1
- package/dist/src/parties/data-party.js +9 -5
- package/dist/src/parties/data-party.js.map +1 -1
- package/dist/src/parties/data-party.test.js +12 -12
- package/dist/src/parties/data-party.test.js.map +1 -1
- package/dist/src/parties/party-factory.d.ts +2 -4
- package/dist/src/parties/party-factory.d.ts.map +1 -1
- package/dist/src/parties/party-factory.js +14 -11
- package/dist/src/parties/party-factory.js.map +1 -1
- package/dist/src/parties/party-manager.d.ts +1 -1
- package/dist/src/parties/party-manager.d.ts.map +1 -1
- package/dist/src/parties/party-manager.js +13 -13
- package/dist/src/parties/party-manager.js.map +1 -1
- package/dist/src/parties/party-manager.test.js +16 -12
- package/dist/src/parties/party-manager.test.js.map +1 -1
- package/dist/src/pipeline/feed-muxer.d.ts.map +1 -1
- package/dist/src/pipeline/feed-muxer.js +3 -3
- package/dist/src/pipeline/feed-muxer.js.map +1 -1
- package/dist/src/pipeline/feed-muxer.test.js +2 -2
- package/dist/src/pipeline/feed-muxer.test.js.map +1 -1
- package/dist/src/pipeline/message-selector.d.ts +1 -2
- package/dist/src/pipeline/message-selector.d.ts.map +1 -1
- package/dist/src/pipeline/message-selector.js +4 -31
- package/dist/src/pipeline/message-selector.js.map +1 -1
- package/dist/src/pipeline/metadata-store.d.ts +7 -2
- package/dist/src/pipeline/metadata-store.d.ts.map +1 -1
- package/dist/src/pipeline/metadata-store.js +9 -0
- package/dist/src/pipeline/metadata-store.js.map +1 -1
- package/dist/src/pipeline/party-feed-provider.d.ts +2 -2
- package/dist/src/pipeline/party-feed-provider.d.ts.map +1 -1
- package/dist/src/pipeline/party-feed-provider.js +2 -1
- package/dist/src/pipeline/party-feed-provider.js.map +1 -1
- package/dist/src/pipeline/party-pipeline.d.ts +5 -5
- package/dist/src/pipeline/party-pipeline.d.ts.map +1 -1
- package/dist/src/pipeline/party-pipeline.js +6 -7
- package/dist/src/pipeline/party-pipeline.js.map +1 -1
- package/dist/src/pipeline/party-pipeline.test.js +13 -18
- package/dist/src/pipeline/party-pipeline.test.js.map +1 -1
- package/dist/src/protocol/identity-credentials.d.ts.map +1 -1
- package/dist/src/protocol/identity-credentials.js +2 -2
- package/dist/src/protocol/identity-credentials.js.map +1 -1
- package/dist/src/protocol/party-protocol-factory.js +1 -1
- package/dist/src/protocol/party-protocol-factory.js.map +1 -1
- package/dist/src/protocol/replicator-plugin.d.ts.map +1 -1
- package/dist/src/protocol/replicator-plugin.js +1 -2
- package/dist/src/protocol/replicator-plugin.js.map +1 -1
- package/dist/src/snapshots/snapshot-generator.js +2 -2
- package/dist/src/snapshots/snapshot-generator.js.map +1 -1
- package/dist/src/snapshots/snapshot-store.d.ts.map +1 -1
- package/dist/src/snapshots/snapshot-store.js +2 -2
- package/dist/src/snapshots/snapshot-store.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -20
- package/src/echo.test.ts +1 -1
- package/src/halo/halo-factory.ts +7 -8
- package/src/halo/halo-party.ts +14 -6
- package/src/halo/halo.ts +3 -1
- package/src/halo/identity-manager.ts +11 -2
- package/src/halo/party-opener.ts +2 -4
- package/src/halo/preferences.ts +4 -8
- package/src/invitations/greeting-initiator.ts +10 -5
- package/src/invitations/greeting-protocol-provider.ts +2 -2
- package/src/invitations/greeting-responder.ts +11 -30
- package/src/invitations/halo-recovery-initiator.ts +3 -3
- package/src/invitations/invitation-descriptor.ts +5 -5
- package/src/invitations/invitation-factory.ts +2 -2
- package/src/invitations/offline-invitation-claimer.ts +3 -3
- package/src/packlets/database/data-mirror.test.ts +2 -2
- package/src/packlets/database/item-demuxer.test.ts +2 -2
- package/src/packlets/database/testing.ts +2 -2
- package/src/packlets/database/timeframe-clock.ts +4 -1
- package/src/parties/data-party.test.ts +12 -12
- package/src/parties/data-party.ts +14 -6
- package/src/parties/party-factory.ts +20 -12
- package/src/parties/party-manager.test.ts +12 -8
- package/src/parties/party-manager.ts +14 -12
- package/src/pipeline/feed-muxer.test.ts +2 -2
- package/src/pipeline/feed-muxer.ts +4 -4
- package/src/pipeline/message-selector.ts +4 -35
- package/src/pipeline/metadata-store.ts +15 -2
- package/src/pipeline/party-feed-provider.ts +2 -2
- package/src/pipeline/party-pipeline.test.ts +13 -19
- package/src/pipeline/party-pipeline.ts +13 -12
- package/src/protocol/identity-credentials.ts +5 -2
- package/src/protocol/party-protocol-factory.ts +2 -2
- package/src/protocol/replicator-plugin.ts +1 -2
- package/src/snapshots/snapshot-generator.ts +1 -1
- package/src/snapshots/snapshot-store.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo-db",
|
|
3
|
-
"version": "2.33.
|
|
3
|
+
"version": "2.33.9-dev.e605934d",
|
|
4
4
|
"description": "ECHO database.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -10,22 +10,22 @@
|
|
|
10
10
|
"src"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dxos/async": "2.33.
|
|
14
|
-
"@dxos/codec-protobuf": "2.33.
|
|
15
|
-
"@dxos/credentials": "2.33.
|
|
16
|
-
"@dxos/crypto": "2.33.
|
|
17
|
-
"@dxos/debug": "2.33.
|
|
18
|
-
"@dxos/echo-protocol": "2.33.
|
|
19
|
-
"@dxos/feed-store": "2.33.
|
|
20
|
-
"@dxos/mesh-protocol": "2.33.
|
|
21
|
-
"@dxos/model-factory": "2.33.
|
|
22
|
-
"@dxos/network-manager": "2.33.
|
|
23
|
-
"@dxos/object-model": "2.33.
|
|
24
|
-
"@dxos/protocol-plugin-presence": "2.33.
|
|
25
|
-
"@dxos/protocol-plugin-replicator": "2.33.
|
|
26
|
-
"@dxos/protocols": "2.33.
|
|
27
|
-
"@dxos/random-access-multi-storage": "2.33.
|
|
28
|
-
"@dxos/util": "2.33.
|
|
13
|
+
"@dxos/async": "2.33.9-dev.e605934d",
|
|
14
|
+
"@dxos/codec-protobuf": "2.33.9-dev.e605934d",
|
|
15
|
+
"@dxos/credentials": "2.33.9-dev.e605934d",
|
|
16
|
+
"@dxos/crypto": "2.33.9-dev.e605934d",
|
|
17
|
+
"@dxos/debug": "2.33.9-dev.e605934d",
|
|
18
|
+
"@dxos/echo-protocol": "2.33.9-dev.e605934d",
|
|
19
|
+
"@dxos/feed-store": "2.33.9-dev.e605934d",
|
|
20
|
+
"@dxos/mesh-protocol": "2.33.9-dev.e605934d",
|
|
21
|
+
"@dxos/model-factory": "2.33.9-dev.e605934d",
|
|
22
|
+
"@dxos/network-manager": "2.33.9-dev.e605934d",
|
|
23
|
+
"@dxos/object-model": "2.33.9-dev.e605934d",
|
|
24
|
+
"@dxos/protocol-plugin-presence": "2.33.9-dev.e605934d",
|
|
25
|
+
"@dxos/protocol-plugin-replicator": "2.33.9-dev.e605934d",
|
|
26
|
+
"@dxos/protocols": "2.33.9-dev.e605934d",
|
|
27
|
+
"@dxos/random-access-multi-storage": "2.33.9-dev.e605934d",
|
|
28
|
+
"@dxos/util": "2.33.9-dev.e605934d",
|
|
29
29
|
"base-x": "~3.0.9",
|
|
30
30
|
"buffer-json-encoding": "^1.0.2",
|
|
31
31
|
"debug": "^4.3.3",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"pify": "~5.0.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@dxos/browser-mocha": "2.33.
|
|
38
|
+
"@dxos/browser-mocha": "2.33.8",
|
|
39
39
|
"@dxos/eslint-plugin": "~1.0.34",
|
|
40
|
-
"@dxos/protocols-toolchain": "2.33.
|
|
41
|
-
"@dxos/testutils": "2.33.
|
|
40
|
+
"@dxos/protocols-toolchain": "2.33.8",
|
|
41
|
+
"@dxos/testutils": "2.33.8",
|
|
42
42
|
"@types/columnify": "^1.5.1",
|
|
43
43
|
"@types/debug": "^4.1.7",
|
|
44
44
|
"@types/faker": "^5.5.1",
|
package/src/echo.test.ts
CHANGED
|
@@ -11,9 +11,9 @@ import { latch, promiseTimeout, waitForCondition } from '@dxos/async';
|
|
|
11
11
|
import {
|
|
12
12
|
defaultSecretProvider, defaultSecretValidator, generateSeedPhrase, keyPairFromSeedPhrase
|
|
13
13
|
} from '@dxos/credentials';
|
|
14
|
-
import { humanize } from '@dxos/crypto';
|
|
15
14
|
import { ObjectModel } from '@dxos/object-model';
|
|
16
15
|
import { afterTest } from '@dxos/testutils';
|
|
16
|
+
import { humanize } from '@dxos/util';
|
|
17
17
|
|
|
18
18
|
import { ECHO } from './echo';
|
|
19
19
|
import { Contact } from './halo';
|
package/src/halo/halo-factory.ts
CHANGED
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
Filter,
|
|
17
17
|
SecretProvider
|
|
18
18
|
} from '@dxos/credentials';
|
|
19
|
-
import { keyToString } from '@dxos/crypto';
|
|
20
19
|
import { ModelFactory } from '@dxos/model-factory';
|
|
21
20
|
import { NetworkManager } from '@dxos/network-manager';
|
|
22
21
|
import { ObjectModel } from '@dxos/object-model';
|
|
@@ -55,17 +54,15 @@ export class HaloFactory {
|
|
|
55
54
|
private readonly _options: PipelineOptions = {}
|
|
56
55
|
) {}
|
|
57
56
|
|
|
58
|
-
async constructParty (
|
|
57
|
+
async constructParty (): Promise<HaloParty> {
|
|
59
58
|
const credentialsSigner = CredentialsSigner.createDirectDeviceSigner(this._keyring);
|
|
60
59
|
const feedProvider = this._feedProviderFactory(credentialsSigner.getIdentityKey().publicKey);
|
|
61
|
-
const writableFeed = await feedProvider.createOrOpenWritableFeed();
|
|
62
60
|
const halo = new HaloParty(
|
|
63
61
|
this._modelFactory,
|
|
64
62
|
this._snapshotStore,
|
|
65
63
|
feedProvider,
|
|
66
64
|
credentialsSigner,
|
|
67
65
|
this._networkManager,
|
|
68
|
-
[...feedHints, writableFeed.key],
|
|
69
66
|
undefined,
|
|
70
67
|
this._options
|
|
71
68
|
);
|
|
@@ -82,10 +79,11 @@ export class HaloFactory {
|
|
|
82
79
|
await this._keyring.createKeyRecord({ type: KeyType.DEVICE });
|
|
83
80
|
|
|
84
81
|
// 1. Create a feed for the HALO.
|
|
85
|
-
const halo = await this.constructParty(
|
|
82
|
+
const halo = await this.constructParty();
|
|
86
83
|
const feedKey = await halo.getWriteFeedKey();
|
|
87
84
|
const feedKeyPair = this._keyring.getKey(feedKey);
|
|
88
85
|
assert(feedKeyPair);
|
|
86
|
+
halo._setGenesisFeedKey(feedKey);
|
|
89
87
|
|
|
90
88
|
// Connect the pipeline.
|
|
91
89
|
await halo.open();
|
|
@@ -152,7 +150,7 @@ export class HaloFactory {
|
|
|
152
150
|
}
|
|
153
151
|
|
|
154
152
|
private async _joinHalo (invitationDescriptor: InvitationDescriptor, secretProvider: SecretProvider) {
|
|
155
|
-
log(`Admitting device with invitation: ${
|
|
153
|
+
log(`Admitting device with invitation: ${PublicKey.stringify(invitationDescriptor.invitation)}`);
|
|
156
154
|
assert(invitationDescriptor.identityKey);
|
|
157
155
|
|
|
158
156
|
let identityKey = this._keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
|
|
@@ -194,9 +192,10 @@ export class HaloFactory {
|
|
|
194
192
|
);
|
|
195
193
|
|
|
196
194
|
await initiator.connect();
|
|
197
|
-
const {
|
|
195
|
+
const { genesisFeedKey } = await initiator.redeemInvitation(secretProvider);
|
|
198
196
|
|
|
199
|
-
const halo = await this.constructParty(
|
|
197
|
+
const halo = await this.constructParty();
|
|
198
|
+
halo._setGenesisFeedKey(genesisFeedKey);
|
|
200
199
|
await halo.open();
|
|
201
200
|
|
|
202
201
|
await initiator.destroy();
|
package/src/halo/halo-party.ts
CHANGED
|
@@ -5,12 +5,10 @@
|
|
|
5
5
|
import assert from 'assert';
|
|
6
6
|
|
|
7
7
|
import { Event, synchronized } from '@dxos/async';
|
|
8
|
-
import { KeyHint } from '@dxos/credentials';
|
|
9
8
|
import { timed } from '@dxos/debug';
|
|
10
|
-
import { Timeframe } from '@dxos/echo-protocol';
|
|
11
9
|
import { ModelFactory } from '@dxos/model-factory';
|
|
12
10
|
import { NetworkManager } from '@dxos/network-manager';
|
|
13
|
-
import { PublicKey } from '@dxos/protocols';
|
|
11
|
+
import { PublicKey, Timeframe } from '@dxos/protocols';
|
|
14
12
|
|
|
15
13
|
import { InvitationAuthenticator, InvitationDescriptor, InvitationFactory, InvitationOptions } from '../invitations';
|
|
16
14
|
import { PARTY_ITEM_TYPE } from '../parties';
|
|
@@ -32,7 +30,7 @@ export const HALO_PARTY_DEVICE_PREFERENCES_TYPE = 'dxos:item/halo/device/prefere
|
|
|
32
30
|
*/
|
|
33
31
|
export interface JoinedParty {
|
|
34
32
|
partyKey: PublicKey,
|
|
35
|
-
|
|
33
|
+
genesisFeed: PublicKey,
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
/**
|
|
@@ -48,13 +46,14 @@ export class HaloParty {
|
|
|
48
46
|
private readonly _contactManager: ContactManager;
|
|
49
47
|
private readonly _preferences: Preferences;
|
|
50
48
|
|
|
49
|
+
private _genesisFeedKey?: PublicKey | undefined;
|
|
50
|
+
|
|
51
51
|
constructor (
|
|
52
52
|
modelFactory: ModelFactory,
|
|
53
53
|
snapshotStore: SnapshotStore,
|
|
54
54
|
private readonly _feedProvider: PartyFeedProvider,
|
|
55
55
|
private readonly _credentialsSigner: CredentialsSigner,
|
|
56
56
|
private readonly _networkManager: NetworkManager,
|
|
57
|
-
private readonly _feedHints: PublicKey[] = [],
|
|
58
57
|
private readonly _initialTimeframe: Timeframe | undefined,
|
|
59
58
|
_options: PipelineOptions
|
|
60
59
|
) {
|
|
@@ -134,6 +133,13 @@ export class HaloParty {
|
|
|
134
133
|
return this._partyCore.processor;
|
|
135
134
|
}
|
|
136
135
|
|
|
136
|
+
/**
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
139
|
+
_setGenesisFeedKey (genesisFeedKey: PublicKey) {
|
|
140
|
+
this._genesisFeedKey = genesisFeedKey;
|
|
141
|
+
}
|
|
142
|
+
|
|
137
143
|
/**
|
|
138
144
|
* Opens the pipeline and connects the streams.
|
|
139
145
|
*/
|
|
@@ -144,13 +150,15 @@ export class HaloParty {
|
|
|
144
150
|
return this;
|
|
145
151
|
}
|
|
146
152
|
|
|
153
|
+
assert(this._genesisFeedKey);
|
|
147
154
|
await this._partyCore.open({
|
|
148
|
-
|
|
155
|
+
genesisFeedKey: this._genesisFeedKey,
|
|
149
156
|
initialTimeframe: this._initialTimeframe
|
|
150
157
|
});
|
|
151
158
|
|
|
152
159
|
this._invitationManager = new InvitationFactory(
|
|
153
160
|
this._partyCore.processor,
|
|
161
|
+
this._genesisFeedKey,
|
|
154
162
|
this._credentialsSigner,
|
|
155
163
|
this._partyCore.credentialsWriter,
|
|
156
164
|
this._networkManager
|
package/src/halo/halo.ts
CHANGED
|
@@ -7,11 +7,12 @@ import debug from 'debug';
|
|
|
7
7
|
|
|
8
8
|
import { synchronized } from '@dxos/async';
|
|
9
9
|
import { KeyRecord, Keyring, KeyType, SecretProvider } from '@dxos/credentials';
|
|
10
|
-
import { createKeyPair,
|
|
10
|
+
import { createKeyPair, KeyPair } from '@dxos/crypto';
|
|
11
11
|
import { raise } from '@dxos/debug';
|
|
12
12
|
import { ModelFactory } from '@dxos/model-factory';
|
|
13
13
|
import { NetworkManager } from '@dxos/network-manager';
|
|
14
14
|
import { PublicKey } from '@dxos/protocols';
|
|
15
|
+
import { humanize } from '@dxos/util';
|
|
15
16
|
|
|
16
17
|
import { ResultSet } from '../api';
|
|
17
18
|
import { InvitationAuthenticator, InvitationDescriptor, InvitationOptions } from '../invitations';
|
|
@@ -225,6 +226,7 @@ export class HALO {
|
|
|
225
226
|
*/
|
|
226
227
|
async createInvitation (authenticationDetails: InvitationAuthenticator, options?: InvitationOptions) {
|
|
227
228
|
assert(this.identity?.halo, 'HALO not initialized.');
|
|
229
|
+
|
|
228
230
|
return this.identity.halo.createInvitation(authenticationDetails, options);
|
|
229
231
|
}
|
|
230
232
|
|
|
@@ -69,9 +69,14 @@ export class IdentityManager {
|
|
|
69
69
|
async loadFromStorage () {
|
|
70
70
|
const identityKey = this.getIdentityKey();
|
|
71
71
|
if (identityKey) {
|
|
72
|
-
|
|
72
|
+
const metadata = this._metadataStore.getParty(identityKey.publicKey);
|
|
73
|
+
if (metadata) {
|
|
73
74
|
// TODO(marik-d): Snapshots for halo party?
|
|
74
|
-
const halo = await this._haloFactory.constructParty(
|
|
75
|
+
const halo = await this._haloFactory.constructParty();
|
|
76
|
+
|
|
77
|
+
assert(metadata.genesisFeedKey);
|
|
78
|
+
halo._setGenesisFeedKey(metadata.genesisFeedKey);
|
|
79
|
+
|
|
75
80
|
// Always open the HALO.
|
|
76
81
|
await halo.open();
|
|
77
82
|
await this._initialize(halo);
|
|
@@ -89,6 +94,10 @@ export class IdentityManager {
|
|
|
89
94
|
assert(!this._identity, 'Identity already initialized.');
|
|
90
95
|
|
|
91
96
|
const halo = await this._haloFactory.createHalo(options);
|
|
97
|
+
|
|
98
|
+
const identityKey = this.getIdentityKey() ?? failUndefined();
|
|
99
|
+
await this._metadataStore.setGenesisFeed(identityKey.publicKey, await halo.getWriteFeedKey());
|
|
100
|
+
|
|
92
101
|
await this._initialize(halo);
|
|
93
102
|
return halo;
|
|
94
103
|
}
|
package/src/halo/party-opener.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import debug from 'debug';
|
|
6
6
|
|
|
7
|
-
import { KeyType } from '@dxos/credentials';
|
|
8
7
|
import { SubscriptionGroup, Unsubscribe } from '@dxos/util';
|
|
9
8
|
|
|
10
9
|
import { PartyManager } from '../parties';
|
|
@@ -25,9 +24,8 @@ export const autoPartyOpener = (preferences: Preferences, partyManager: PartyMan
|
|
|
25
24
|
|
|
26
25
|
for (const partyDesc of values) {
|
|
27
26
|
if (!partyManager.parties.some(x => x.key === partyDesc.partyKey)) {
|
|
28
|
-
log(`Auto-opening new Party from HALO: ${partyDesc.partyKey.toHex()}
|
|
29
|
-
|
|
30
|
-
await partyManager.addParty(partyDesc.partyKey, feedHints);
|
|
27
|
+
log(`Auto-opening new Party from HALO: ${partyDesc.partyKey.toHex()}`);
|
|
28
|
+
await partyManager.addParty(partyDesc.partyKey, partyDesc.genesisFeed);
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
}));
|
package/src/halo/preferences.ts
CHANGED
|
@@ -7,7 +7,6 @@ import stableStringify from 'json-stable-stringify';
|
|
|
7
7
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
8
8
|
|
|
9
9
|
import { Event } from '@dxos/async';
|
|
10
|
-
import { KeyHint } from '@dxos/credentials';
|
|
11
10
|
import { raise } from '@dxos/debug';
|
|
12
11
|
import { ObjectModel } from '@dxos/object-model';
|
|
13
12
|
import { PublicKey } from '@dxos/protocols';
|
|
@@ -151,8 +150,8 @@ export class Preferences {
|
|
|
151
150
|
type: HALO_PARTY_DESCRIPTOR_TYPE,
|
|
152
151
|
props: {
|
|
153
152
|
publicKey: joinedParty.partyKey.asBuffer(),
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
genesisFeed: joinedParty.genesisFeed.toHex(),
|
|
154
|
+
subscribed: true
|
|
156
155
|
}
|
|
157
156
|
});
|
|
158
157
|
}
|
|
@@ -160,12 +159,9 @@ export class Preferences {
|
|
|
160
159
|
subscribeToJoinedPartyList (callback: (parties: JoinedParty[]) => void): () => void {
|
|
161
160
|
const database = this._getDatabase() ?? raise(new IdentityNotInitializedError());
|
|
162
161
|
|
|
163
|
-
const converter = (partyDesc: Item<any>) => ({
|
|
162
|
+
const converter = (partyDesc: Item<any>): JoinedParty => ({
|
|
164
163
|
partyKey: PublicKey.from(partyDesc.model.get('publicKey')),
|
|
165
|
-
|
|
166
|
-
...hint,
|
|
167
|
-
publicKey: PublicKey.from(hint.publicKey)
|
|
168
|
-
} as KeyHint))
|
|
164
|
+
genesisFeed: PublicKey.from(partyDesc.model.get('genesisFeed'))
|
|
169
165
|
});
|
|
170
166
|
|
|
171
167
|
const result = database.select({ type: HALO_PARTY_DESCRIPTOR_TYPE }).exec();
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
SignedMessage,
|
|
24
24
|
NotarizeResponse
|
|
25
25
|
} from '@dxos/credentials';
|
|
26
|
-
import { keyToString } from '@dxos/crypto';
|
|
27
26
|
import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
|
|
28
27
|
import { PublicKey } from '@dxos/protocols';
|
|
29
28
|
|
|
@@ -36,6 +35,11 @@ const log = debug('dxos:echo-db:greeting-initiator');
|
|
|
36
35
|
|
|
37
36
|
const DEFAULT_TIMEOUT = 30_000;
|
|
38
37
|
|
|
38
|
+
export interface InvitationResult {
|
|
39
|
+
partyKey: PublicKey;
|
|
40
|
+
genesisFeedKey: PublicKey
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
/**
|
|
40
44
|
* Attempts to connect to a greeting responder to 'redeem' an invitation, potentially with some out-of-band
|
|
41
45
|
* authentication check, in order to be admitted to a Party.
|
|
@@ -88,10 +92,10 @@ export class GreetingInitiator {
|
|
|
88
92
|
// Therefore at present the greeter discovers the invitation id from session metadata, via the invitee's peer id.
|
|
89
93
|
// TODO(dboreham): Invitation is actually invitationID.
|
|
90
94
|
const localPeerId = invitation;
|
|
91
|
-
log('Local PeerId:',
|
|
95
|
+
log('Local PeerId:', PublicKey.stringify(localPeerId));
|
|
92
96
|
this._greeterPlugin = new GreetingCommandPlugin(Buffer.from(localPeerId), new Greeter().createMessageHandler());
|
|
93
97
|
|
|
94
|
-
log(
|
|
98
|
+
log(PublicKey.stringify(localPeerId), 'connecting to', PublicKey.stringify(swarmKey));
|
|
95
99
|
|
|
96
100
|
const peerJoinedWaiter = waitForEvent(this._greeterPlugin, 'peer:joined',
|
|
97
101
|
(remotePeerId: any) => remotePeerId && Buffer.from(responderPeerId).equals(remotePeerId),
|
|
@@ -113,7 +117,7 @@ export class GreetingInitiator {
|
|
|
113
117
|
/**
|
|
114
118
|
* Called after connecting to initiate greeting protocol exchange.
|
|
115
119
|
*/
|
|
116
|
-
async redeemInvitation (secretProvider: SecretProvider): Promise<
|
|
120
|
+
async redeemInvitation (secretProvider: SecretProvider): Promise<InvitationResult> {
|
|
117
121
|
assert(this._state === GreetingState.CONNECTED);
|
|
118
122
|
const { swarmKey } = this._invitationDescriptor;
|
|
119
123
|
|
|
@@ -171,9 +175,10 @@ export class GreetingInitiator {
|
|
|
171
175
|
await this.disconnect();
|
|
172
176
|
|
|
173
177
|
this._state = GreetingState.SUCCEEDED;
|
|
178
|
+
assert(notarizeResponse.genesisFeed);
|
|
174
179
|
return {
|
|
175
180
|
partyKey,
|
|
176
|
-
|
|
181
|
+
genesisFeedKey: notarizeResponse.genesisFeed
|
|
177
182
|
};
|
|
178
183
|
}
|
|
179
184
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright 2020 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { keyToString } from '@dxos/crypto';
|
|
6
5
|
import { protocolFactory } from '@dxos/network-manager';
|
|
6
|
+
import { PublicKey } from '@dxos/protocols';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates a duplex connection with a single peer using a common rendezvous key as topic.
|
|
@@ -16,6 +16,6 @@ import { protocolFactory } from '@dxos/network-manager';
|
|
|
16
16
|
// TODO(dboreham): Write a test to check resources are released (no resource leaks).
|
|
17
17
|
export const greetingProtocolProvider = (rendezvousKey: any, peerId: Buffer | Uint8Array, protocolPlugins: any[]) => protocolFactory({
|
|
18
18
|
getTopics: () => [rendezvousKey],
|
|
19
|
-
session: { peerId:
|
|
19
|
+
session: { peerId: PublicKey.stringify(peerId) },
|
|
20
20
|
plugins: protocolPlugins
|
|
21
21
|
});
|
|
@@ -9,14 +9,13 @@ import { Event, waitForCondition } from '@dxos/async';
|
|
|
9
9
|
import {
|
|
10
10
|
admitsKeys,
|
|
11
11
|
createEnvelopeMessage, Greeter,
|
|
12
|
-
GreetingCommandPlugin,
|
|
12
|
+
GreetingCommandPlugin,
|
|
13
13
|
Keyring,
|
|
14
|
-
KeyType,
|
|
15
14
|
SecretProvider,
|
|
16
|
-
SecretValidator
|
|
17
|
-
|
|
15
|
+
SecretValidator,
|
|
16
|
+
Message as HaloMessage
|
|
18
17
|
} from '@dxos/credentials';
|
|
19
|
-
import {
|
|
18
|
+
import { randomBytes } from '@dxos/crypto';
|
|
20
19
|
import { FeedWriter, SwarmKey } from '@dxos/echo-protocol';
|
|
21
20
|
import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
|
|
22
21
|
import { PublicKey } from '@dxos/protocols';
|
|
@@ -60,13 +59,14 @@ export class GreetingResponder {
|
|
|
60
59
|
constructor (
|
|
61
60
|
private readonly _networkManager: NetworkManager,
|
|
62
61
|
private readonly _partyProcessor: PartyStateProvider,
|
|
62
|
+
private readonly _genesisFeedKey: PublicKey,
|
|
63
63
|
private readonly _credentialsSigner: CredentialsSigner,
|
|
64
64
|
private readonly _credentialsWriter: FeedWriter<HaloMessage>
|
|
65
65
|
) {
|
|
66
66
|
this._greeter = new Greeter(
|
|
67
67
|
this._partyProcessor.partyKey,
|
|
68
|
-
|
|
69
|
-
async () => this.
|
|
68
|
+
this._genesisFeedKey,
|
|
69
|
+
async (messages: any) => this._writeCredentialsToParty(messages)
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
this._greeterPlugin = new GreetingCommandPlugin(Buffer.from(this._swarmKey), this._greeter.createMessageHandler());
|
|
@@ -130,11 +130,11 @@ export class GreetingResponder {
|
|
|
130
130
|
// TODO(dboreham): Add tests for idempotence and transactional integrity over the greet flow.
|
|
131
131
|
(this._greeterPlugin as any).once('peer:joined', (joinedPeerId: Buffer) => {
|
|
132
132
|
if (joinedPeerId.equals(invitation.id)) {
|
|
133
|
-
log(`Initiator connected: ${
|
|
133
|
+
log(`Initiator connected: ${PublicKey.stringify(joinedPeerId)}`);
|
|
134
134
|
this._state = GreetingState.CONNECTED;
|
|
135
135
|
this.connected.emit(invitation.id);
|
|
136
136
|
} else {
|
|
137
|
-
log(`Unexpected initiator connected: ${
|
|
137
|
+
log(`Unexpected initiator connected: ${PublicKey.stringify(joinedPeerId)}`);
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
140
|
|
|
@@ -158,7 +158,7 @@ export class GreetingResponder {
|
|
|
158
158
|
label: 'Greeting responder'
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
-
log(`Greeting for: ${this._partyProcessor.partyKey.toHex()} on swarmKey ${
|
|
161
|
+
log(`Greeting for: ${this._partyProcessor.partyKey.toHex()} on swarmKey ${PublicKey.stringify(this._swarmKey)}`);
|
|
162
162
|
|
|
163
163
|
this._state = GreetingState.LISTENING;
|
|
164
164
|
log('Listening');
|
|
@@ -210,6 +210,7 @@ export class GreetingResponder {
|
|
|
210
210
|
// Place the self-signed messages inside an Envelope, sign then write the signed Envelope to the Party.
|
|
211
211
|
const envelopes = [];
|
|
212
212
|
for (const message of messages) {
|
|
213
|
+
// TODO(dmaretskyi): Refactor to pass in a callback: `await admitKeys(messages)`.
|
|
213
214
|
const admittedKeys = admitsKeys(message);
|
|
214
215
|
|
|
215
216
|
// TODO(telackey): Add hasKey/isMember to PartyProcessor?
|
|
@@ -238,24 +239,4 @@ export class GreetingResponder {
|
|
|
238
239
|
// Return the signed messages to the caller because copies are sent back to the invitee.
|
|
239
240
|
return envelopes;
|
|
240
241
|
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Callback to gather member key and feed "hints" for the Invitee.
|
|
244
|
-
* @private
|
|
245
|
-
*/
|
|
246
|
-
_gatherHints (): KeyHint[] {
|
|
247
|
-
assert(this._state === GreetingState.SUCCEEDED);
|
|
248
|
-
|
|
249
|
-
const memberKeys = this._partyProcessor.memberKeys.map((publicKey) => ({
|
|
250
|
-
publicKey,
|
|
251
|
-
type: KeyType.UNKNOWN
|
|
252
|
-
}));
|
|
253
|
-
|
|
254
|
-
const memberFeeds = this._partyProcessor.feedKeys.map((publicKey) => ({
|
|
255
|
-
publicKey,
|
|
256
|
-
type: KeyType.FEED
|
|
257
|
-
}));
|
|
258
|
-
|
|
259
|
-
return [...memberKeys, ...memberFeeds];
|
|
260
|
-
}
|
|
261
242
|
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
SignedMessage,
|
|
20
20
|
codec
|
|
21
21
|
} from '@dxos/credentials';
|
|
22
|
-
import {
|
|
22
|
+
import { randomBytes, verify } from '@dxos/crypto';
|
|
23
23
|
import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
|
|
24
24
|
import { PublicKey } from '@dxos/protocols';
|
|
25
25
|
|
|
@@ -66,7 +66,7 @@ export class HaloRecoveryInitiator {
|
|
|
66
66
|
|
|
67
67
|
// This is a temporary connection, there is no need to any special or permanent ID.
|
|
68
68
|
this._peerId = randomBytes();
|
|
69
|
-
log('Local PeerId:',
|
|
69
|
+
log('Local PeerId:', PublicKey.stringify(this._peerId));
|
|
70
70
|
|
|
71
71
|
const swarmKey = this._credentialsSigner.getIdentityKey().publicKey.asBuffer();
|
|
72
72
|
|
|
@@ -102,7 +102,7 @@ export class HaloRecoveryInitiator {
|
|
|
102
102
|
|
|
103
103
|
// Send to the first peer (any peer will do).
|
|
104
104
|
const peer = this._greeterPlugin.peers[0];
|
|
105
|
-
const responderPeerId =
|
|
105
|
+
const responderPeerId = PublicKey.bufferize(peer.getSession().peerId);
|
|
106
106
|
|
|
107
107
|
// Synthesize an "invitationID" which is the signature of both peerIds signed by our Identity key.
|
|
108
108
|
const signature = this._credentialsSigner.signer.rawSign(
|
|
@@ -6,7 +6,7 @@ import assert from 'assert';
|
|
|
6
6
|
import base from 'base-x';
|
|
7
7
|
import stableStringify from 'json-stable-stringify';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { ripemd160 } from '@dxos/crypto';
|
|
10
10
|
import { SwarmKey } from '@dxos/echo-protocol';
|
|
11
11
|
import * as proto from '@dxos/echo-protocol';
|
|
12
12
|
import { PublicKey } from '@dxos/protocols';
|
|
@@ -46,8 +46,8 @@ export class InvitationDescriptor {
|
|
|
46
46
|
static fromQueryParameters (queryParameters: InvitationQueryParameters): InvitationDescriptor {
|
|
47
47
|
const { hash, swarmKey, invitation, identityKey, type } = queryParameters;
|
|
48
48
|
|
|
49
|
-
const descriptor = new InvitationDescriptor(parseInvitationType(type),
|
|
50
|
-
|
|
49
|
+
const descriptor = new InvitationDescriptor(parseInvitationType(type), PublicKey.bufferize(swarmKey),
|
|
50
|
+
PublicKey.bufferize(invitation), identityKey ? PublicKey.from(identityKey) : undefined);
|
|
51
51
|
|
|
52
52
|
if (hash !== descriptor.hash) {
|
|
53
53
|
throw new InvalidInvitationError();
|
|
@@ -104,8 +104,8 @@ export class InvitationDescriptor {
|
|
|
104
104
|
*/
|
|
105
105
|
toQueryParameters (): InvitationQueryParameters {
|
|
106
106
|
const query: Partial<InvitationQueryParameters> = {
|
|
107
|
-
swarmKey:
|
|
108
|
-
invitation:
|
|
107
|
+
swarmKey: PublicKey.stringify(this.swarmKey),
|
|
108
|
+
invitation: PublicKey.stringify(this.invitation),
|
|
109
109
|
type: stringifyInvitationType(this.type)
|
|
110
110
|
};
|
|
111
111
|
|
|
@@ -21,8 +21,7 @@ import { InvitationDescriptor, InvitationDescriptorType } from './invitation-des
|
|
|
21
21
|
export class InvitationFactory {
|
|
22
22
|
constructor (
|
|
23
23
|
private readonly _partyProcessor: PartyStateProvider,
|
|
24
|
-
|
|
25
|
-
// Then the identity would be changed after this is instantiated.
|
|
24
|
+
private readonly _genesisFeedKey: PublicKey,
|
|
26
25
|
private readonly _credentialsSigner: CredentialsSigner,
|
|
27
26
|
private readonly _credentialsWriter: FeedWriter<HaloMessage>,
|
|
28
27
|
private readonly _networkManager: NetworkManager
|
|
@@ -62,6 +61,7 @@ export class InvitationFactory {
|
|
|
62
61
|
const responder = new GreetingResponder(
|
|
63
62
|
this._networkManager,
|
|
64
63
|
this._partyProcessor,
|
|
64
|
+
this._genesisFeedKey,
|
|
65
65
|
this._credentialsSigner,
|
|
66
66
|
this._credentialsWriter
|
|
67
67
|
);
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
SignedMessage,
|
|
21
21
|
codec
|
|
22
22
|
} from '@dxos/credentials';
|
|
23
|
-
import {
|
|
23
|
+
import { randomBytes } from '@dxos/crypto';
|
|
24
24
|
import { FullyConnectedTopology, NetworkManager } from '@dxos/network-manager';
|
|
25
25
|
import { PublicKey } from '@dxos/protocols';
|
|
26
26
|
|
|
@@ -66,7 +66,7 @@ export class OfflineInvitationClaimer {
|
|
|
66
66
|
|
|
67
67
|
// This is a temporary connection, there is no need to any special or permanent ID.
|
|
68
68
|
const localPeerId = randomBytes();
|
|
69
|
-
log('Local PeerId:',
|
|
69
|
+
log('Local PeerId:', PublicKey.stringify(localPeerId));
|
|
70
70
|
|
|
71
71
|
this._greeterPlugin = new GreetingCommandPlugin(localPeerId, async () => false);
|
|
72
72
|
|
|
@@ -100,7 +100,7 @@ export class OfflineInvitationClaimer {
|
|
|
100
100
|
const { invitation: invitationID } = this._invitationDescriptor;
|
|
101
101
|
|
|
102
102
|
// Send to the first peer (any peer will do).
|
|
103
|
-
const responderPeerId =
|
|
103
|
+
const responderPeerId = PublicKey.bufferize(this._greeterPlugin.peers[0].getSession().peerId);
|
|
104
104
|
|
|
105
105
|
// We expect to receive a new swarm/rendezvousKey to use for the full Greeting process.
|
|
106
106
|
const claimResponse = await this._greeterPlugin.send(
|
|
@@ -6,10 +6,10 @@ import expect from 'expect';
|
|
|
6
6
|
import { it as test } from 'mocha';
|
|
7
7
|
|
|
8
8
|
import { promiseTimeout } from '@dxos/async';
|
|
9
|
-
import { EchoEnvelope, MockFeedWriter
|
|
9
|
+
import { EchoEnvelope, MockFeedWriter } from '@dxos/echo-protocol';
|
|
10
10
|
import { ModelFactory } from '@dxos/model-factory';
|
|
11
11
|
import { ObjectModel } from '@dxos/object-model';
|
|
12
|
-
import { PublicKey } from '@dxos/protocols';
|
|
12
|
+
import { PublicKey, Timeframe } from '@dxos/protocols';
|
|
13
13
|
|
|
14
14
|
import { DataMirror } from './data-mirror';
|
|
15
15
|
import { DataServiceHost } from './data-service-host';
|
|
@@ -9,10 +9,10 @@ import { it as test } from 'mocha';
|
|
|
9
9
|
import { latch } from '@dxos/async';
|
|
10
10
|
import { createId } from '@dxos/crypto';
|
|
11
11
|
import { checkType } from '@dxos/debug';
|
|
12
|
-
import { EchoEnvelope, MockFeedWriter
|
|
12
|
+
import { EchoEnvelope, MockFeedWriter } from '@dxos/echo-protocol';
|
|
13
13
|
import { ModelFactory, TestModel } from '@dxos/model-factory';
|
|
14
14
|
import { ObjectModel } from '@dxos/object-model';
|
|
15
|
-
import { PublicKey } from '@dxos/protocols';
|
|
15
|
+
import { PublicKey, Timeframe } from '@dxos/protocols';
|
|
16
16
|
|
|
17
17
|
import { Item } from './item';
|
|
18
18
|
import { ItemDemuxer } from './item-demuxer';
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { EchoEnvelope, MockFeedWriter
|
|
5
|
+
import { EchoEnvelope, MockFeedWriter } from '@dxos/echo-protocol';
|
|
6
6
|
import { ModelFactory } from '@dxos/model-factory';
|
|
7
|
-
import { PublicKey } from '@dxos/protocols';
|
|
7
|
+
import { PublicKey, Timeframe } from '@dxos/protocols';
|
|
8
8
|
|
|
9
9
|
import { DataServiceHost } from './data-service-host';
|
|
10
10
|
import { DataServiceRouter } from './data-service-router';
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
|
-
import {
|
|
6
|
+
import { timed } from '@dxos/debug';
|
|
7
|
+
import { FeedKey } from '@dxos/echo-protocol';
|
|
8
|
+
import { Timeframe } from '@dxos/protocols';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Keeps state of the last timeframe that was processed by ECHO.
|
|
@@ -29,6 +31,7 @@ export class TimeframeClock {
|
|
|
29
31
|
return !gaps.isEmpty();
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
@timed(5_000)
|
|
32
35
|
async waitUntilReached (target: Timeframe) {
|
|
33
36
|
await this.update.waitForCondition(() => Timeframe.dependencies(target, this._timeframe).isEmpty());
|
|
34
37
|
}
|