@enbox/agent 0.6.5 → 0.6.7
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 +18 -5
- package/dist/browser.mjs +11 -11
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/agent-did-resolver-cache.js +5 -5
- package/dist/esm/agent-did-resolver-cache.js.map +1 -1
- package/dist/esm/crypto-api.js.map +1 -1
- package/dist/esm/did-api.js +1 -1
- package/dist/esm/did-api.js.map +1 -1
- package/dist/esm/dwn-api.js +93 -53
- package/dist/esm/dwn-api.js.map +1 -1
- package/dist/esm/dwn-discovery-payload.js +7 -4
- package/dist/esm/dwn-discovery-payload.js.map +1 -1
- package/dist/esm/dwn-key-delivery.js +8 -3
- package/dist/esm/dwn-key-delivery.js.map +1 -1
- package/dist/esm/enbox-connect-protocol.js +34 -14
- package/dist/esm/enbox-connect-protocol.js.map +1 -1
- package/dist/esm/enbox-user-agent.js +11 -3
- package/dist/esm/enbox-user-agent.js.map +1 -1
- package/dist/esm/hd-identity-vault.js +33 -18
- package/dist/esm/hd-identity-vault.js.map +1 -1
- package/dist/esm/identity-api.js +5 -4
- package/dist/esm/identity-api.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/local-dwn.js.map +1 -1
- package/dist/esm/local-key-manager.js.map +1 -1
- package/dist/esm/permissions-api.js +9 -5
- package/dist/esm/permissions-api.js.map +1 -1
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js +9 -9
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js.map +1 -1
- package/dist/esm/secret-store.js +106 -0
- package/dist/esm/secret-store.js.map +1 -0
- package/dist/esm/store-data.js +32 -11
- package/dist/esm/store-data.js.map +1 -1
- package/dist/esm/sync-closure-resolver.js +1 -1
- package/dist/esm/sync-closure-resolver.js.map +1 -1
- package/dist/esm/sync-engine-level.js +418 -141
- package/dist/esm/sync-engine-level.js.map +1 -1
- package/dist/esm/sync-replication-ledger.js +25 -0
- package/dist/esm/sync-replication-ledger.js.map +1 -1
- package/dist/esm/test-harness.js +32 -5
- package/dist/esm/test-harness.js.map +1 -1
- package/dist/esm/types/sync.js +9 -3
- package/dist/esm/types/sync.js.map +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/types/agent-did-resolver-cache.d.ts +1 -1
- package/dist/types/agent-did-resolver-cache.d.ts.map +1 -1
- package/dist/types/anonymous-dwn-api.d.ts +2 -2
- package/dist/types/anonymous-dwn-api.d.ts.map +1 -1
- package/dist/types/crypto-api.d.ts +1 -1
- package/dist/types/crypto-api.d.ts.map +1 -1
- package/dist/types/did-api.d.ts +2 -2
- package/dist/types/did-api.d.ts.map +1 -1
- package/dist/types/dwn-api.d.ts +51 -11
- package/dist/types/dwn-api.d.ts.map +1 -1
- package/dist/types/dwn-key-delivery.d.ts +4 -1
- package/dist/types/dwn-key-delivery.d.ts.map +1 -1
- package/dist/types/enbox-connect-protocol.d.ts +3 -2
- package/dist/types/enbox-connect-protocol.d.ts.map +1 -1
- package/dist/types/enbox-user-agent.d.ts +5 -1
- package/dist/types/enbox-user-agent.d.ts.map +1 -1
- package/dist/types/hd-identity-vault.d.ts +9 -2
- package/dist/types/hd-identity-vault.d.ts.map +1 -1
- package/dist/types/identity-api.d.ts +1 -1
- package/dist/types/identity-api.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/local-dwn.d.ts +3 -3
- package/dist/types/local-dwn.d.ts.map +1 -1
- package/dist/types/local-key-manager.d.ts +2 -2
- package/dist/types/local-key-manager.d.ts.map +1 -1
- package/dist/types/permissions-api.d.ts +1 -1
- package/dist/types/permissions-api.d.ts.map +1 -1
- package/dist/types/secret-store.d.ts +81 -0
- package/dist/types/secret-store.d.ts.map +1 -0
- package/dist/types/store-data.d.ts +15 -3
- package/dist/types/store-data.d.ts.map +1 -1
- package/dist/types/sync-engine-level.d.ts +52 -16
- package/dist/types/sync-engine-level.d.ts.map +1 -1
- package/dist/types/sync-replication-ledger.d.ts +10 -1
- package/dist/types/sync-replication-ledger.d.ts.map +1 -1
- package/dist/types/test-harness.d.ts +3 -0
- package/dist/types/test-harness.d.ts.map +1 -1
- package/dist/types/types/agent.d.ts +3 -0
- package/dist/types/types/agent.d.ts.map +1 -1
- package/dist/types/types/sync.d.ts +27 -4
- package/dist/types/types/sync.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agent-did-resolver-cache.ts +5 -5
- package/src/anonymous-dwn-api.ts +2 -2
- package/src/crypto-api.ts +1 -1
- package/src/did-api.ts +3 -3
- package/src/dwn-api.ts +107 -69
- package/src/dwn-discovery-payload.ts +5 -4
- package/src/dwn-key-delivery.ts +8 -2
- package/src/enbox-connect-protocol.ts +38 -21
- package/src/enbox-user-agent.ts +15 -3
- package/src/hd-identity-vault.ts +47 -21
- package/src/identity-api.ts +6 -5
- package/src/index.ts +1 -0
- package/src/local-dwn.ts +3 -3
- package/src/local-key-manager.ts +2 -2
- package/src/permissions-api.ts +12 -8
- package/src/prototyping/crypto/jose/jwe-flattened.ts +8 -8
- package/src/secret-store.ts +173 -0
- package/src/store-data.ts +40 -14
- package/src/sync-closure-resolver.ts +2 -2
- package/src/sync-engine-level.ts +423 -162
- package/src/sync-replication-ledger.ts +26 -1
- package/src/test-harness.ts +40 -5
- package/src/types/agent.ts +3 -0
- package/src/types/sync.ts +35 -7
- package/src/utils.ts +1 -1
|
@@ -21,7 +21,7 @@ const KEY_SEP = '^';
|
|
|
21
21
|
*/
|
|
22
22
|
export class ReplicationLedger {
|
|
23
23
|
private readonly db: AbstractLevel<string | Buffer | Uint8Array>;
|
|
24
|
-
private sublevel;
|
|
24
|
+
private readonly sublevel;
|
|
25
25
|
|
|
26
26
|
constructor(db: AbstractLevel<string | Buffer | Uint8Array>) {
|
|
27
27
|
this.db = db;
|
|
@@ -126,6 +126,31 @@ export class ReplicationLedger {
|
|
|
126
126
|
return links;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Delegate updates
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Update the `delegateDid` on all persisted links for a tenant and persist.
|
|
135
|
+
* This ensures that repair and reconcile paths — which read `delegateDid`
|
|
136
|
+
* from the durable {@link ReplicationLinkState} — use the current delegate
|
|
137
|
+
* after a hot-swap via `updateIdentityOptions()`.
|
|
138
|
+
*
|
|
139
|
+
* @returns the links that were updated.
|
|
140
|
+
*/
|
|
141
|
+
public async updateDelegateDid(tenantDid: string, delegateDid: string | undefined): Promise<ReplicationLinkState[]> {
|
|
142
|
+
const links = await this.getLinksForTenant(tenantDid);
|
|
143
|
+
const updated: ReplicationLinkState[] = [];
|
|
144
|
+
for (const link of links) {
|
|
145
|
+
if (link.delegateDid !== delegateDid) {
|
|
146
|
+
link.delegateDid = delegateDid;
|
|
147
|
+
await this.saveLink(link);
|
|
148
|
+
updated.push(link);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return updated;
|
|
152
|
+
}
|
|
153
|
+
|
|
129
154
|
// ---------------------------------------------------------------------------
|
|
130
155
|
// Status transitions
|
|
131
156
|
// ---------------------------------------------------------------------------
|
package/src/test-harness.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { SyncEngineLevel } from './sync-engine-level.js';
|
|
|
23
23
|
import { DwnDidStore, InMemoryDidStore } from './store-did.js';
|
|
24
24
|
import { DwnIdentityStore, InMemoryIdentityStore } from './store-identity.js';
|
|
25
25
|
import { DwnKeyStore, InMemoryKeyStore } from './store-key.js';
|
|
26
|
+
import { InMemorySecretStore, VaultBackedSecretStore } from './secret-store.js';
|
|
26
27
|
|
|
27
28
|
type StoreSetupResult = {
|
|
28
29
|
agentVault: HdIdentityVault;
|
|
@@ -31,6 +32,9 @@ type StoreSetupResult = {
|
|
|
31
32
|
identityApi: AgentIdentityApi<LocalKeyManager>;
|
|
32
33
|
keyManager: LocalKeyManager;
|
|
33
34
|
permissionsApi: AgentPermissionsApi;
|
|
35
|
+
secretsApi: InMemorySecretStore | VaultBackedSecretStore;
|
|
36
|
+
/** Backing KeyValueStore for VaultBackedSecretStore (for clear/close lifecycle). */
|
|
37
|
+
secretStore?: KeyValueStore<string, string>;
|
|
34
38
|
vaultStore: KeyValueStore<string, string>;
|
|
35
39
|
};
|
|
36
40
|
|
|
@@ -44,6 +48,8 @@ type PlatformAgentTestHarnessParams = {
|
|
|
44
48
|
dwnStateIndex: StateIndexLevel;
|
|
45
49
|
dwnMessageStore: MessageStoreLevel;
|
|
46
50
|
dwnResumableTaskStore: ResumableTaskStoreLevel;
|
|
51
|
+
/** Backing KeyValueStore for VaultBackedSecretStore (disk mode only). */
|
|
52
|
+
secretStore?: KeyValueStore<string, string>;
|
|
47
53
|
syncStore: AbstractLevel<string | Buffer | Uint8Array>;
|
|
48
54
|
vaultStore: KeyValueStore<string, string>;
|
|
49
55
|
dwnStores: {
|
|
@@ -64,6 +70,7 @@ export class PlatformAgentTestHarness {
|
|
|
64
70
|
public dwnStateIndex: StateIndexLevel;
|
|
65
71
|
public dwnMessageStore: MessageStoreLevel;
|
|
66
72
|
public dwnResumableTaskStore: ResumableTaskStoreLevel;
|
|
73
|
+
public secretStore?: KeyValueStore<string, string>;
|
|
67
74
|
public syncStore: AbstractLevel<string | Buffer | Uint8Array>;
|
|
68
75
|
public vaultStore: KeyValueStore<string, string>;
|
|
69
76
|
|
|
@@ -87,6 +94,7 @@ export class PlatformAgentTestHarness {
|
|
|
87
94
|
this.dwnDataStore = params.dwnDataStore;
|
|
88
95
|
this.dwnStateIndex = params.dwnStateIndex;
|
|
89
96
|
this.dwnMessageStore = params.dwnMessageStore;
|
|
97
|
+
this.secretStore = params.secretStore;
|
|
90
98
|
this.syncStore = params.syncStore;
|
|
91
99
|
this.vaultStore = params.vaultStore;
|
|
92
100
|
this.dwnResumableTaskStore = params.dwnResumableTaskStore;
|
|
@@ -97,6 +105,12 @@ export class PlatformAgentTestHarness {
|
|
|
97
105
|
// first stop any ongoing sync operations
|
|
98
106
|
await this.agent.sync.stopSync();
|
|
99
107
|
|
|
108
|
+
// Drain any in-flight fire-and-forget eager-send promises dispatched by
|
|
109
|
+
// `AgentDwnApi.writeContextKeyRecord` so they cannot outlive the agent
|
|
110
|
+
// and touch a nulled `agentDid` or a cleared LevelDB store. Fast path
|
|
111
|
+
// when the tracker is empty (no pending sends).
|
|
112
|
+
await this.agent.dwn.drainPendingEagerSends();
|
|
113
|
+
|
|
100
114
|
// @ts-expect-error since normally this property shouldn't be set to undefined.
|
|
101
115
|
this.agent.agentDid = undefined;
|
|
102
116
|
await this.didResolverCache.clear();
|
|
@@ -106,6 +120,7 @@ export class PlatformAgentTestHarness {
|
|
|
106
120
|
await this.dwnResumableTaskStore.clear();
|
|
107
121
|
await this.syncStore.clear();
|
|
108
122
|
await this.vaultStore.clear();
|
|
123
|
+
if (this.secretStore) { await this.secretStore.clear(); }
|
|
109
124
|
(this.agent.vault as any)['_cachedInitialized'] = undefined;
|
|
110
125
|
await this.agent.permissions.clear();
|
|
111
126
|
this.dwnStores.clear();
|
|
@@ -120,11 +135,12 @@ export class PlatformAgentTestHarness {
|
|
|
120
135
|
|
|
121
136
|
// Easiest way to start with fresh in-memory stores is to re-instantiate Agent components.
|
|
122
137
|
if (this.agentStores === 'memory') {
|
|
123
|
-
const { didApi, identityApi, permissionsApi, keyManager } = PlatformAgentTestHarness.useMemoryStores({ agent: this.agent });
|
|
138
|
+
const { didApi, identityApi, permissionsApi, keyManager, secretsApi } = PlatformAgentTestHarness.useMemoryStores({ agent: this.agent });
|
|
124
139
|
this.agent.did = didApi;
|
|
125
140
|
this.agent.identity = identityApi;
|
|
126
141
|
this.agent.keyManager = keyManager;
|
|
127
142
|
this.agent.permissions = permissionsApi;
|
|
143
|
+
this.agent.secrets = secretsApi;
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
|
|
@@ -148,11 +164,18 @@ export class PlatformAgentTestHarness {
|
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
public async closeStorage(): Promise<void> {
|
|
167
|
+
// Drain any in-flight fire-and-forget eager-send promises dispatched by
|
|
168
|
+
// `AgentDwnApi.writeContextKeyRecord` before closing the LevelDB-backed
|
|
169
|
+
// stores. Prevents orphan promises from hitting closed handles with
|
|
170
|
+
// `LEVEL_DATABASE_NOT_OPEN` after teardown. Fast path when empty.
|
|
171
|
+
await this.agent.dwn.drainPendingEagerSends();
|
|
172
|
+
|
|
151
173
|
await this.didResolverCache.close();
|
|
152
174
|
await this.dwnDataStore.close();
|
|
153
175
|
await this.dwnStateIndex.close();
|
|
154
176
|
await this.dwnMessageStore.close();
|
|
155
177
|
await this.dwnResumableTaskStore.close();
|
|
178
|
+
if (this.secretStore) { await this.secretStore.close(); }
|
|
156
179
|
await this.syncStore.close();
|
|
157
180
|
await this.vaultStore.close();
|
|
158
181
|
}
|
|
@@ -248,7 +271,9 @@ export class PlatformAgentTestHarness {
|
|
|
248
271
|
keyManager,
|
|
249
272
|
didResolverCache,
|
|
250
273
|
vaultStore,
|
|
251
|
-
permissionsApi
|
|
274
|
+
permissionsApi,
|
|
275
|
+
secretsApi,
|
|
276
|
+
secretStore,
|
|
252
277
|
} = (agentStores === 'memory')
|
|
253
278
|
? PlatformAgentTestHarness.useMemoryStores()
|
|
254
279
|
: PlatformAgentTestHarness.useDiskStores({ testDataLocation, stores: dwnStores });
|
|
@@ -294,6 +319,7 @@ export class PlatformAgentTestHarness {
|
|
|
294
319
|
keyManager,
|
|
295
320
|
permissionsApi,
|
|
296
321
|
rpcClient,
|
|
322
|
+
secretsApi,
|
|
297
323
|
syncApi,
|
|
298
324
|
});
|
|
299
325
|
|
|
@@ -307,8 +333,9 @@ export class PlatformAgentTestHarness {
|
|
|
307
333
|
dwnMessageStore,
|
|
308
334
|
dwnResumableTaskStore,
|
|
309
335
|
dwnStores,
|
|
336
|
+
secretStore,
|
|
310
337
|
syncStore,
|
|
311
|
-
vaultStore
|
|
338
|
+
vaultStore,
|
|
312
339
|
});
|
|
313
340
|
}
|
|
314
341
|
|
|
@@ -346,7 +373,13 @@ export class PlatformAgentTestHarness {
|
|
|
346
373
|
|
|
347
374
|
const permissionsApi = new AgentPermissionsApi({ agent });
|
|
348
375
|
|
|
349
|
-
|
|
376
|
+
const secretStore = new LevelStore<string, string>({ location: testDataPath('SECRET_STORE') });
|
|
377
|
+
const secretsApi = new VaultBackedSecretStore({
|
|
378
|
+
vault : agentVault,
|
|
379
|
+
store : secretStore,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
return { agentVault, didApi, didResolverCache, identityApi, keyManager, permissionsApi, secretsApi, secretStore, vaultStore };
|
|
350
383
|
}
|
|
351
384
|
|
|
352
385
|
private static useMemoryStores({ agent }: { agent?: EnboxPlatformAgent<LocalKeyManager> } = {}): StoreSetupResult {
|
|
@@ -369,6 +402,8 @@ export class PlatformAgentTestHarness {
|
|
|
369
402
|
|
|
370
403
|
const permissionsApi = new AgentPermissionsApi({ agent });
|
|
371
404
|
|
|
372
|
-
|
|
405
|
+
const secretsApi = new InMemorySecretStore();
|
|
406
|
+
|
|
407
|
+
return { agentVault, didApi, didResolverCache, identityApi, keyManager, permissionsApi, secretsApi, vaultStore };
|
|
373
408
|
}
|
|
374
409
|
}
|
package/src/types/agent.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { AgentKeyManager } from './key-manager.js';
|
|
|
7
7
|
import type { AgentPermissionsApi } from '../permissions-api.js';
|
|
8
8
|
import type { EnboxRpc } from '@enbox/dwn-clients';
|
|
9
9
|
import type { IdentityVault } from './identity-vault.js';
|
|
10
|
+
import type { SecretStore } from '../secret-store.js';
|
|
10
11
|
import type { SyncEngine } from './sync.js';
|
|
11
12
|
import type { AgentDidApi, DidInterface, DidRequest, DidResponse } from '../did-api.js';
|
|
12
13
|
import type { DwnInterface, DwnResponse, ProcessDwnRequest, SendDwnRequest } from './dwn.js';
|
|
@@ -169,6 +170,8 @@ export interface EnboxPlatformAgent<TKeyManager extends AgentKeyManager = AgentK
|
|
|
169
170
|
*/
|
|
170
171
|
sync: SyncEngine;
|
|
171
172
|
|
|
173
|
+
/** Vault-backed secret store for classified credentials, encrypted at rest with the vault key. */
|
|
174
|
+
secrets: SecretStore;
|
|
172
175
|
/**
|
|
173
176
|
* An instance of {@link IdentityVault}, providing secure storage and management of an Enbox Agent's
|
|
174
177
|
* DID and cryptographic keys.
|
package/src/types/sync.ts
CHANGED
|
@@ -11,9 +11,11 @@ export type SyncIdentityOptions = {
|
|
|
11
11
|
*/
|
|
12
12
|
delegateDid?: string;
|
|
13
13
|
/**
|
|
14
|
-
* The protocols that should be synced for this identity
|
|
14
|
+
* The protocols that should be synced for this identity.
|
|
15
|
+
* - `'all'` — sync all protocols (full replica).
|
|
16
|
+
* - `string[]` — sync only the listed protocol URIs.
|
|
15
17
|
*/
|
|
16
|
-
protocols: string[];
|
|
18
|
+
protocols: 'all' | [string, ...string[]];
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -65,10 +67,10 @@ export async function computeScopeId(scope: SyncScope): Promise<string> {
|
|
|
65
67
|
if (scope.kind === 'protocol') {
|
|
66
68
|
canonical.protocol = scope.protocol;
|
|
67
69
|
if (scope.protocolPathPrefixes !== undefined) {
|
|
68
|
-
canonical.protocolPathPrefixes = [...new Set(scope.protocolPathPrefixes)].sort();
|
|
70
|
+
canonical.protocolPathPrefixes = [...new Set(scope.protocolPathPrefixes)].sort((a, b) => a.localeCompare(b));
|
|
69
71
|
}
|
|
70
72
|
if (scope.contextIdPrefixes !== undefined) {
|
|
71
|
-
canonical.contextIdPrefixes = [...new Set(scope.contextIdPrefixes)].sort();
|
|
73
|
+
canonical.contextIdPrefixes = [...new Set(scope.contextIdPrefixes)].sort((a, b) => a.localeCompare(b));
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -83,7 +85,11 @@ export async function computeScopeId(scope: SyncScope): Promise<string> {
|
|
|
83
85
|
for (const b of hashArray) {
|
|
84
86
|
base64 += String.fromCharCode(b);
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
const result = btoa(base64).replaceAll('+', '-').replaceAll('/', '_');
|
|
89
|
+
// Strip trailing '=' padding without regex quantifiers (avoids ReDoS scanners).
|
|
90
|
+
let end = result.length;
|
|
91
|
+
while (end > 0 && result.codePointAt(end - 1) === 61) { end--; } // 61 === '='
|
|
92
|
+
return end === result.length ? result : result.slice(0, end);
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
// ---------------------------------------------------------------------------
|
|
@@ -323,13 +329,35 @@ export interface SyncEngine {
|
|
|
323
329
|
*/
|
|
324
330
|
readonly connectivityState: SyncConnectivityState;
|
|
325
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Whether at least one live pull or push subscription is open.
|
|
334
|
+
*
|
|
335
|
+
* This is specifically about live-mode subscriptions — it is `false` in
|
|
336
|
+
* poll mode and `false` when only the integrity timer remains (e.g. after
|
|
337
|
+
* the last identity was removed). Callers use this to avoid calling
|
|
338
|
+
* `startSync()` when live subscriptions are active, which would tear
|
|
339
|
+
* them all down and rebuild from scratch.
|
|
340
|
+
*/
|
|
341
|
+
readonly hasActiveSubscriptions: boolean;
|
|
342
|
+
|
|
326
343
|
/**
|
|
327
344
|
* Register an identity to be managed by the SyncEngine for syncing.
|
|
328
|
-
*
|
|
345
|
+
* Callers must explicitly specify which protocols to sync (`'all'` for a
|
|
346
|
+
* full replica, or a list of protocol URIs) so that sync scope is always
|
|
347
|
+
* a deliberate choice rather than an invisible default.
|
|
348
|
+
*
|
|
349
|
+
* When live sync is active, the new identity is hot-added: its replication
|
|
350
|
+
* links are created and subscriptions opened immediately, without tearing
|
|
351
|
+
* down existing subscriptions for other identities. This enables
|
|
352
|
+
* multi-identity agents (e.g. ElectroBun desktop DWN, multi-persona dApps)
|
|
353
|
+
* to add identities at runtime without disrupting sync for others.
|
|
329
354
|
*/
|
|
330
|
-
registerIdentity(params: { did: string, options
|
|
355
|
+
registerIdentity(params: { did: string, options: SyncIdentityOptions }): Promise<void>;
|
|
331
356
|
/**
|
|
332
357
|
* Unregister an identity from the SyncEngine, this will stop syncing messages for this identity.
|
|
358
|
+
*
|
|
359
|
+
* When live sync is active, the identity is hot-removed: its subscriptions
|
|
360
|
+
* are closed and runtime state cleaned up without affecting other identities.
|
|
333
361
|
*/
|
|
334
362
|
unregisterIdentity(did: string): Promise<void>;
|
|
335
363
|
/**
|
package/src/utils.ts
CHANGED
|
@@ -19,7 +19,7 @@ export async function getDwnServiceEndpointUrls(didUri: string, dereferencer: Di
|
|
|
19
19
|
? [serviceEndpoint]
|
|
20
20
|
: Array.isArray(serviceEndpoint) && serviceEndpoint.every(endpoint => typeof endpoint === 'string')
|
|
21
21
|
// If the service endpoint is an array of strings, use it as is.
|
|
22
|
-
? serviceEndpoint
|
|
22
|
+
? serviceEndpoint
|
|
23
23
|
// If the service endpoint is neither a string nor an array of strings, return an empty array.
|
|
24
24
|
: [];
|
|
25
25
|
|