@interncom/diplomatic 0.22.0 → 0.23.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.
Files changed (84) hide show
  1. package/dist/cli/bun/src/crypto.d.ts +2 -3
  2. package/dist/cli/index.mjs +4 -5
  3. package/dist/cli/shared/api/peek.d.ts +9 -1
  4. package/dist/cli/shared/api/pull.d.ts +9 -1
  5. package/dist/cli/shared/api/push.d.ts +3 -1
  6. package/dist/cli/shared/api/user.d.ts +1 -1
  7. package/dist/cli/shared/bag.d.ts +7 -4
  8. package/dist/cli/shared/client.d.ts +10 -4
  9. package/dist/cli/shared/codecs/kdm.d.ts +6 -0
  10. package/dist/cli/shared/codecs/notifItem.d.ts +2 -0
  11. package/dist/cli/shared/crypto/derivation.d.ts +45 -0
  12. package/dist/cli/shared/crypto/enclave.d.ts +30 -66
  13. package/dist/cli/shared/crypto/largeBlob.d.ts +8 -0
  14. package/dist/cli/shared/crypto/noble.d.ts +15 -22
  15. package/dist/cli/shared/crypto/pairing.d.ts +19 -2
  16. package/dist/cli/shared/crypto/prf.d.ts +52 -0
  17. package/dist/cli/shared/crypto/realms.d.ts +7 -0
  18. package/dist/cli/shared/endpoint.d.ts +2 -2
  19. package/dist/cli/shared/http.d.ts +12 -12
  20. package/dist/cli/shared/sync.d.ts +4 -2
  21. package/dist/cli/shared/types.d.ts +24 -11
  22. package/dist/cli/shared/webauthn/prf.d.ts +8 -0
  23. package/dist/cli/src/index.d.ts +5 -4
  24. package/dist/web/client.d.ts +10 -5
  25. package/dist/web/crypto.d.ts +2 -3
  26. package/dist/web/entdb/cached.d.ts +4 -0
  27. package/dist/web/entdb/entdb.d.ts +3 -0
  28. package/dist/web/entdb/idb.d.ts +9 -4
  29. package/dist/web/index.d.ts +10 -5
  30. package/dist/web/index.mjs +1 -1
  31. package/dist/web/passkey/prf-store.d.ts +26 -10
  32. package/dist/web/passkey/seed.d.ts +12 -6
  33. package/dist/web/shared/api/peek.d.ts +9 -1
  34. package/dist/web/shared/api/pull.d.ts +9 -1
  35. package/dist/web/shared/api/push.d.ts +3 -1
  36. package/dist/web/shared/api/user.d.ts +1 -1
  37. package/dist/web/shared/bag.d.ts +7 -4
  38. package/dist/web/shared/client.d.ts +10 -4
  39. package/dist/web/shared/codecs/kdm.d.ts +6 -0
  40. package/dist/web/shared/codecs/notifItem.d.ts +2 -0
  41. package/dist/web/shared/crypto/derivation.d.ts +45 -0
  42. package/dist/web/shared/crypto/enclave.d.ts +30 -66
  43. package/dist/web/shared/crypto/largeBlob.d.ts +8 -0
  44. package/dist/web/shared/crypto/noble.d.ts +15 -22
  45. package/dist/web/shared/crypto/pairing.d.ts +19 -2
  46. package/dist/web/shared/crypto/prf.d.ts +52 -0
  47. package/dist/web/shared/crypto/realms.d.ts +7 -0
  48. package/dist/web/shared/crypto/tty.d.ts +3 -0
  49. package/dist/web/shared/endpoint.d.ts +2 -2
  50. package/dist/web/shared/http.d.ts +12 -12
  51. package/dist/web/shared/storage/memory.d.ts +2 -2
  52. package/dist/web/shared/sync.d.ts +4 -2
  53. package/dist/web/shared/types.d.ts +24 -11
  54. package/dist/web/shared/webauthn/prf.d.ts +8 -0
  55. package/dist/web/stores/cursor.d.ts +30 -0
  56. package/dist/web/stores/idb/account.d.ts +58 -0
  57. package/dist/web/stores/idb/catalog.d.ts +1 -0
  58. package/dist/web/stores/idb/dnlds.d.ts +3 -2
  59. package/dist/web/stores/idb/hosts.d.ts +8 -7
  60. package/dist/web/stores/idb/idbutil.d.ts +2 -0
  61. package/dist/web/stores/idb/migrate.d.ts +2 -0
  62. package/dist/web/stores/idb/msgs.d.ts +1 -1
  63. package/dist/web/stores/idb/names.d.ts +13 -0
  64. package/dist/web/stores/idb/realms.d.ts +11 -0
  65. package/dist/web/stores/idb/store.d.ts +26 -19
  66. package/dist/web/stores/idb/uplds.d.ts +1 -1
  67. package/dist/web/stores/keyTag.d.ts +14 -0
  68. package/dist/web/stores/label.d.ts +3 -0
  69. package/dist/web/stores/memory/account.d.ts +14 -0
  70. package/dist/web/stores/memory/dnlds.d.ts +4 -2
  71. package/dist/web/stores/memory/hosts.d.ts +8 -6
  72. package/dist/web/stores/memory/realms.d.ts +10 -0
  73. package/dist/web/stores/memory/store.d.ts +6 -2
  74. package/dist/web/stores/realm.d.ts +35 -0
  75. package/dist/web/sync.d.ts +14 -11
  76. package/dist/web/types.d.ts +52 -16
  77. package/dist/web/worker/client.d.ts +1 -1
  78. package/dist/web/worker/protocol.d.ts +6 -0
  79. package/dist/web/worker/runtime.d.ts +4 -2
  80. package/dist/web/worker.mjs +1 -1
  81. package/package.json +1 -1
  82. package/dist/web/stores/idb/seed.d.ts +0 -32
  83. package/dist/web/stores/identityPin.d.ts +0 -19
  84. package/dist/web/stores/memory/seed.d.ts +0 -13
@@ -1,4 +1,5 @@
1
1
  import DiplomaticClientAPI from "./shared/client";
2
+ import type { IKDM } from "./shared/codecs/kdm";
2
3
  import { Status } from "./shared/consts";
3
4
  import { Enclave } from "./shared/crypto/enclave";
4
5
  import { Hash, HostHandle, IBag, ICrypto } from "./shared/types";
@@ -20,7 +21,7 @@ export type IPulled = {
20
21
  bodyCph?: Uint8Array;
21
22
  };
22
23
  /** Host connection methods used by sync phases. */
23
- export type SyncConn<Handle extends HostHandle> = Pick<DiplomaticClientAPI<Handle>, "pull" | "push" | "peek" | "seal" | "identity">;
24
+ export type SyncConn<Handle extends HostHandle> = Pick<DiplomaticClientAPI<Handle>, "pull" | "push" | "peek" | "seal" | "identity" | "hostRlm">;
24
25
  export interface ISyncParams<Handle extends HostHandle> {
25
26
  conn: SyncConn<Handle>;
26
27
  store: IStore<Handle>;
@@ -40,9 +41,11 @@ export interface ISyncParams<Handle extends HostHandle> {
40
41
  * Default `defaultPeekConcurrency`. Set 1 for fully serial.
41
42
  */
42
43
  peekConcurrency?: number;
44
+ /** Realm for this peek. Push and pull use each item's own realm. */
45
+ realm?: IKDM;
43
46
  }
44
- /** Push one batch of sealed bags; deq successes; advance lastSeq from store. */
45
- export declare function pushBatch<Handle extends HostHandle>(conn: Pick<DiplomaticClientAPI<Handle>, "push">, store: IStore<Handle>, hostLabel: string, bags: IBag[], hashes: Hash[]): Promise<Status>;
47
+ /** Push one batch of sealed bags; deq successes; advance that realm's cursor. */
48
+ export declare function pushBatch<Handle extends HostHandle>(conn: Pick<DiplomaticClientAPI<Handle>, "push">, store: IStore<Handle>, hostLabel: string, bags: IBag[], hashes: Hash[], realm?: IKDM): Promise<Status>;
46
49
  /** pull: network only. Download-queue items → ciphertext (still enqueued). */
47
50
  export declare function pullBodies<Handle extends HostHandle>(conn: Pick<DiplomaticClientAPI<Handle>, "pull">, items: IDownloadMessage[]): Promise<ValStat<IPulled[]>>;
48
51
  export type IOpened = {
@@ -61,7 +64,7 @@ export declare function openPulled<Handle extends HostHandle>(store: IStore<Hand
61
64
  */
62
65
  export declare function deqDownloadsForHeadHashes<Handle extends HostHandle>(store: Pick<IStore<Handle>, "downloads">, hashes: Iterable<Hash>, crypto: ICrypto): Promise<void>;
63
66
  /** Discover unseen bags and enqueue download work; advance host lastSeq. */
64
- export declare function syncPeek<Handle extends HostHandle>({ conn, store, enclave, host, crypto, onProgress, peekProgressEvery, peekConcurrency, }: ISyncParams<Handle>): Promise<Status>;
67
+ export declare function syncPeek<Handle extends HostHandle>({ conn, store, enclave, host, crypto, onProgress, peekProgressEvery, peekConcurrency, realm: realmArg, }: ISyncParams<Handle>): Promise<Status>;
65
68
  /** Seal and upload pending msgs; list once so concurrent enqs wait for next sync. */
66
69
  export declare function syncPush<Handle extends HostHandle>({ conn, store, host, maxPushBytes, onProgress }: ISyncParams<Handle>): Promise<Status>;
67
70
  /**
@@ -76,19 +79,19 @@ export declare function syncPush<Handle extends HostHandle>({ conn, store, host,
76
79
  export declare function syncPull<Handle extends HostHandle>({ conn, store, enclave, host, crypto, maxPullBytes, onProgress, }: ISyncParams<Handle>,
77
80
  /** After each opened pull batch (e.g. drainApplyQueue / exec). */
78
81
  afterOpen?: () => Promise<void>): Promise<Status>;
79
- export declare function msg2StoredMsgData({ head, body }: IMsgParts): IStoredMessageWrite;
82
+ export declare function msg2StoredMsgData({ head, body }: IMsgParts, realm?: IKDM): IStoredMessageWrite;
80
83
  /**
81
84
  * notif → open inline bodies into archive; enq incomplete → scheduleSync.
82
85
  * `scheduleSync` runs full peek/push/pull (or worker handoff).
83
86
  */
84
87
  export declare function handleNotif<Handle extends HostHandle>(bytes: Uint8Array, { conn, store, enclave, host, crypto, onProgress, }: ISyncParams<Handle>, scheduleSync: () => void): Promise<void>;
85
88
  /**
86
- * Full host inventory (PEEK from seq 0): set lastSeq; optionally enqueue
87
- * downloads (msgs on host missing locally) and/or uploads (local msgs missing
88
- * on host). Returns ephemeral bag tallies + msgcheck (not persisted). Does not
89
- * pull/push beyond peek — caller should sync() to drain queues.
89
+ * Full host inventory (PEEK from seq 0 in each realm): set that realm's cursor;
90
+ * optionally enqueue downloads (msgs on host missing locally) and/or uploads
91
+ * (local msgs missing on host). Returns ephemeral bag tallies + msgcheck (not
92
+ * persisted). Does not pull/push beyond peek — caller should sync() to drain.
90
93
  *
91
- * lastSeq is set to the max bag seq in the inventory (0 if empty), including
92
- * rewind when the host has fewer bags than a prior cursor believed.
94
+ * Each cursor is the max bag seq in that realm (0 if empty), including rewind
95
+ * when the host has fewer bags than a prior cursor believed.
93
96
  */
94
97
  export declare function reconcileHost<Handle extends HostHandle>(params: ISyncParams<Handle>, opts?: ReconcileOpts): Promise<ValStat<ReconcileResult>>;
@@ -1,10 +1,12 @@
1
1
  import type { SyncProgressEvent } from "./progress";
2
+ import type { IKDM } from "./shared/codecs/kdm";
2
3
  import { Status } from "./shared/consts";
3
4
  import type { Enclave } from "./shared/crypto/enclave";
4
5
  import type { EncodedMessage } from "./shared/message";
5
6
  import type { EntityID, Hash, HostHandle, IDeleteParams, IEntRev, IHostConnectionInfo, IHostMetadata, IInsertParams, IMessageHead, IOp, IUpdateParams, SerializedContent } from "./shared/types";
6
7
  import { ValStat } from "./shared/valstat";
7
8
  import { ICrypto } from "./shared/types";
9
+ import { type EntRlm, type IRealm, type IRealmStore } from "./stores/realm";
8
10
  export interface IMsgParts {
9
11
  head: IMessageHead;
10
12
  body?: EncodedMessage;
@@ -36,13 +38,18 @@ export type SetSeedOpts = {
36
38
  * When true, request durable storage **if the store supports a non-plaintext
37
39
  * durable form** (e.g. passkey largeBlob as IdentityBundle wire).
38
40
  * IDB holds the enclave in memory only — durable identity is the PRF keyring
39
- * via {@link IDBSeedStore.openPrfStore}, never plain seed.
41
+ * via {@link IDBAccountStore.openPrfStore}, never plain seed.
40
42
  * Default false (session enclave only).
41
43
  *
42
44
  * Future: when PRF is unavailable, durable path is passphrase-sealed meta
43
45
  * (KDF + AEAD inside Enclave), not plain seed on disk.
44
46
  */
45
47
  persist?: boolean;
48
+ /**
49
+ * Account to install into. Omitted means the default account, "".
50
+ * A new label creates that account. An existing key tag must match.
51
+ */
52
+ label?: string;
46
53
  };
47
54
  /**
48
55
  * Selective wipe for {@link IClient.wipe}.
@@ -60,28 +67,44 @@ export type WipeOpts = {
60
67
  /** Hosts + upload/download queues. Default true. */
61
68
  meta?: boolean;
62
69
  /**
63
- * Seed / identity ({@link ISeedStore.wipe}). Default **false**.
70
+ * Seed / identity ({@link IAccountStore.wipe}). Default **false**.
64
71
  * When true, passkey stores overwrite largeBlob (UV ceremony).
65
72
  */
66
73
  seed?: boolean;
67
74
  };
68
- export interface ISeedStore {
69
- save: (enclave: Enclave, opts?: SetSeedOpts) => Promise<Enclave>;
70
- load: () => Promise<Enclave | void>;
75
+ export interface IAccountStore {
76
+ /** Record this enclave's key tag under `opts.label`. Does not open the account. */
77
+ save: (enclave: Enclave, opts?: SetSeedOpts) => Promise<ValStat<Enclave>>;
71
78
  /**
72
- * Clear durable seed material for this store (IDB row, largeBlob overwrite, …)
73
- * and drop the in-memory enclave. Called only when client.wipe({ seed: true }).
79
+ * Clear durable account material (IDB rows, largeBlob overwrite, …).
80
+ * Called only when client.wipe({ seed: true }).
74
81
  */
75
82
  wipe: () => Promise<void>;
76
83
  }
84
+ /** Account the client is operating as. */
85
+ export type OpenAccount<H extends HostHandle> = {
86
+ label: string;
87
+ enclave: Enclave;
88
+ /** Host rows as of the last open, link, or unlink. */
89
+ hosts: IHostRow<H>[];
90
+ /** Realm rows from the realms table, refreshed with hosts and before sync. */
91
+ realms: IRealm[];
92
+ };
77
93
  export interface IHostRow<Handle extends HostHandle> extends IHostConnectionInfo<Handle>, Partial<IHostMetadata> {
94
+ /** Default-realm cursor, joined from host_seqs on read. */
78
95
  lastSeq: number;
96
+ /** Other realm cursors, joined from host_seqs on read. */
97
+ seqs?: {
98
+ label: string;
99
+ index: number;
100
+ lastSeq: number;
101
+ }[];
79
102
  }
80
103
  /**
81
104
  * Host row cursor write (one store transaction).
82
105
  * `lastSeq` only advances unless `setLastSeq` is set.
83
106
  */
84
- export type HostStatsUpdate = {
107
+ export type HostSeqsUpdate = {
85
108
  /** New lastSeq if greater than current (incremental peek/push). */
86
109
  lastSeq?: number;
87
110
  /** Absolute lastSeq, including rewind (full inventory). */
@@ -94,9 +117,9 @@ export interface IHostStore<Handle extends HostHandle> {
94
117
  set: (label: string, meta: IHostMetadata) => Promise<Status>;
95
118
  list: () => Promise<Iterable<IHostRow<Handle>>>;
96
119
  wipe: () => Promise<void>;
97
- touch: (label: string, seq: number) => Promise<void>;
98
- /** Apply lastSeq updates in one transaction. */
99
- recordStats: (label: string, u: HostStatsUpdate) => Promise<void>;
120
+ touch: (label: string, seq: number, realm?: IKDM) => Promise<void>;
121
+ /** Apply one host_seqs cursor. The default realm is nullKDM. */
122
+ recordSeqs: (label: string, u: HostSeqsUpdate, realm?: IKDM) => Promise<void>;
100
123
  }
101
124
  /** Options for {@link IClient.reconcile}. */
102
125
  export type ReconcileOpts = {
@@ -152,10 +175,12 @@ export interface IDownloadMessage {
152
175
  * blake3(headEnc). When set with headEnc, open skips re-hashing the head.
153
176
  */
154
177
  headEncHash?: Hash;
178
+ /** Realm KDM. Omit for the default realm. */
179
+ realm?: IKDM;
155
180
  }
156
181
  export interface IDownloadQueue {
157
182
  enq: (msgs: Iterable<IDownloadMessage>) => Promise<void>;
158
- deq: (host: string, seqs: Iterable<number>) => Promise<void>;
183
+ deq: (host: string, seqs: Iterable<number>, realm?: IKDM) => Promise<void>;
159
184
  list: () => Promise<Iterable<IDownloadMessage>>;
160
185
  count: () => Promise<number>;
161
186
  wipe(): Promise<void>;
@@ -180,6 +205,8 @@ export interface IStoredMessageFields {
180
205
  /** Msg head typ. Omit when empty (raw). */
181
206
  typ?: string;
182
207
  body?: EncodedMessage;
208
+ /** Realm label. Omit for the default realm. */
209
+ rlm?: EntRlm;
183
210
  }
184
211
  /**
185
212
  * What may come back from storage (pre-apld rows can omit the field).
@@ -194,7 +221,7 @@ export interface IStoredMessageData extends IStoredMessageFields {
194
221
  /**
195
222
  * Required shape for every put into the message archive (app/API layer).
196
223
  * `apld` is required and must be one of the three {@link ApldState} values.
197
- * Omit optional fields (`off`, `ctr`, `typ`, `body`, `err`) rather than storing empties.
224
+ * Omit optional fields (`off`, `ctr`, `typ`, `body`, `err`, `rlm`) rather than storing empties.
198
225
  */
199
226
  export type IStoredMessageWrite = IStoredMessageFields & {
200
227
  apld: ApldState;
@@ -211,6 +238,8 @@ export interface IStoredMessage {
211
238
  body?: EncodedMessage;
212
239
  /** Apply lifecycle — same {@link ApldState} as the archive row. */
213
240
  apld: ApldState;
241
+ /** Realm label. Omitted for the default realm. */
242
+ rlm?: EntRlm;
214
243
  /** Status code when apld is {@link APLD_ERROR}. */
215
244
  err?: number;
216
245
  }
@@ -276,13 +305,20 @@ export interface IMessageStore {
276
305
  wipe(): Promise<void>;
277
306
  }
278
307
  export interface IStore<Handle extends HostHandle> {
279
- seed: ISeedStore;
308
+ account: IAccountStore;
309
+ /** Realm counters. Not cleared by {@link IStore.wipe}. */
310
+ realms: IRealmStore;
280
311
  hosts: IHostStore<Handle>;
281
312
  uploads: IUploadQueue;
282
313
  downloads: IDownloadQueue;
283
314
  messages: IMessageStore;
284
315
  /**
285
- * Clear protocol tables (hosts, queues, messages). Does not call seed.wipe.
316
+ * Open the protocol database for `label`.
317
+ * A store with one database returns Success.
318
+ */
319
+ bind(label: string): Promise<Status>;
320
+ /**
321
+ * Clear protocol tables (hosts, queues, messages). Does not call account.wipe.
286
322
  */
287
323
  wipe(): Promise<void>;
288
324
  }
@@ -294,7 +330,7 @@ export interface IStateEmitter<T> {
294
330
  }
295
331
  export interface IClient<Handle extends HostHandle> {
296
332
  /** Install session enclave (master seed stays inside enclave). */
297
- setSeed(enclave: Enclave, opts?: SetSeedOpts): Promise<void>;
333
+ setSeed(enclave: Enclave, opts?: SetSeedOpts): Promise<Status>;
298
334
  link(host: IHostConnectionInfo<Handle>, connect?: boolean): Promise<void>;
299
335
  unlink(label: string): Promise<void>;
300
336
  /** Linked hosts from the protocol store (handle, label, lastSeq, …). */
@@ -78,7 +78,7 @@ export declare class WorkerClient implements IClient<URL> {
78
78
  * Persist seed on main, then Enclave.spawnSyncWorker (only worker spawn path).
79
79
  * Awaits the worker's setSeed reply (worker boots, then applies seed).
80
80
  */
81
- setSeed(enclave: Enclave, opts?: SetSeedOpts): Promise<void>;
81
+ setSeed(enclave: Enclave, opts?: SetSeedOpts): Promise<Status>;
82
82
  link(host: IHostConnectionInfo<URL>, connect?: boolean): Promise<void>;
83
83
  unlink(label: string): Promise<void>;
84
84
  /** Hosts live in shared main IDB (same as local writer). */
@@ -15,6 +15,12 @@ export type WorkerCmd = {
15
15
  op: "setSeed";
16
16
  seed: Uint8Array;
17
17
  persist?: boolean;
18
+ } | {
19
+ id: number;
20
+ op: "bind";
21
+ label: string;
22
+ data: string;
23
+ ents: string;
18
24
  } | {
19
25
  id: number;
20
26
  op: "link";
@@ -3,14 +3,16 @@ import type { WorkerCmd, WorkerEvent } from "./protocol";
3
3
  export type PostFn = (msg: WorkerEvent, transfer?: Transferable[]) => void;
4
4
  export declare class WorkerRuntime {
5
5
  private client;
6
+ private store;
6
7
  private entDB;
8
+ private boundLabel;
7
9
  private post;
8
- /** Resolves when init finishes (success or failure). Cmds wait on this. */
10
+ /** Resolves when bind finishes (success or failure). Cmds wait on this. */
9
11
  private whenReady;
10
12
  private resolveReady;
11
13
  private rejectReady;
12
14
  constructor(post: PostFn);
13
- init(): Promise<void>;
15
+ private bindStores;
14
16
  private markReady;
15
17
  private failReady;
16
18
  private requireClient;