@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
@@ -6,66 +6,66 @@ import { ValStat } from "./valstat.ts";
6
6
  export declare const api: {
7
7
  readonly user: {
8
8
  readonly path: "/user";
9
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
9
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
10
10
  readonly name: APICallName.User;
11
11
  };
12
12
  readonly push: {
13
13
  readonly path: "/push";
14
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
14
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
15
15
  readonly name: APICallName.Push;
16
16
  };
17
17
  readonly peek: {
18
18
  readonly path: "/peek";
19
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
19
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
20
20
  readonly name: APICallName.Peek;
21
21
  };
22
22
  readonly pull: {
23
23
  readonly path: "/pull";
24
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
24
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
25
25
  readonly name: APICallName.Pull;
26
26
  };
27
27
  };
28
28
  export declare const apiCalls: {
29
29
  readonly 0: {
30
30
  readonly path: "/user";
31
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
31
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
32
32
  readonly name: APICallName.User;
33
33
  };
34
34
  readonly 2: {
35
35
  readonly path: "/push";
36
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
36
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
37
37
  readonly name: APICallName.Push;
38
38
  };
39
39
  readonly 1: {
40
40
  readonly path: "/peek";
41
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
41
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
42
42
  readonly name: APICallName.Peek;
43
43
  };
44
44
  readonly 3: {
45
45
  readonly path: "/pull";
46
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
46
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
47
47
  readonly name: APICallName.Pull;
48
48
  };
49
49
  };
50
50
  export declare const callPaths: {
51
51
  readonly "/user": {
52
52
  readonly path: "/user";
53
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
53
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
54
54
  readonly name: APICallName.User;
55
55
  };
56
56
  readonly "/push": {
57
57
  readonly path: "/push";
58
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
58
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
59
59
  readonly name: APICallName.Push;
60
60
  };
61
61
  readonly "/peek": {
62
62
  readonly path: "/peek";
63
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
63
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
64
64
  readonly name: APICallName.Peek;
65
65
  };
66
66
  readonly "/pull": {
67
67
  readonly path: "/pull";
68
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
68
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
69
69
  readonly name: APICallName.Pull;
70
70
  };
71
71
  };
@@ -1,10 +1,10 @@
1
1
  import { type IStorage } from "../types.ts";
2
2
  interface IMemoryStorage extends IStorage {
3
3
  users: Set<string>;
4
- bag: Map<string, Map<number, {
4
+ bag: Map<string, Map<string, Map<number, {
5
5
  headCph: Uint8Array;
6
6
  bodyCph: Uint8Array;
7
- }>>;
7
+ }>>>;
8
8
  }
9
9
  /** Fresh in-memory host storage (isolated bag/user maps). */
10
10
  export declare function createMemoryStorage(): IMemoryStorage;
@@ -1,9 +1,11 @@
1
1
  import { IBagPeekItem } from "./codecs/peekItem.ts";
2
+ import type { IKDM } from "./codecs/kdm.ts";
3
+ import { type HostRlm } from "./crypto/derivation.ts";
2
4
  import { Enclave } from "./crypto/enclave.ts";
3
- import { ICrypto, PublicKey } from "./types.ts";
5
+ import { ICrypto } from "./types.ts";
4
6
  import { ValStat } from "./valstat.ts";
5
7
  export interface IDecryptedBagPeekItem {
6
8
  kdm: Uint8Array;
7
9
  headEnc: Uint8Array;
8
10
  }
9
- export declare function decryptPeekItem(item: IBagPeekItem, pubKey: PublicKey, enclave: Enclave, crypto: ICrypto): Promise<ValStat<IDecryptedBagPeekItem>>;
11
+ export declare function decryptPeekItem(item: IBagPeekItem, verifyKey: CryptoKey, enclave: Enclave, crypto: ICrypto, rlm: HostRlm, realm?: IKDM): Promise<ValStat<IDecryptedBagPeekItem>>;
@@ -4,6 +4,7 @@ import { IAuthTimestamp } from "./codecs/authTimestamp.ts";
4
4
  import type { IBagPeekItem } from "./codecs/peekItem.ts";
5
5
  import { IUsageQuota } from "./codecs/usageQuota.ts";
6
6
  import { APICallName, Status } from "./consts.ts";
7
+ import type { HostRlm } from "./crypto/derivation.ts";
7
8
  import type { ValStat } from "./valstat.ts";
8
9
  /** Identity seed brands — defined in seed.ts; re-exported for convenience. */
9
10
  export type { MasterSeed, SealedMasterKey } from "./seed.ts";
@@ -75,27 +76,35 @@ export type IDeleteParams = {
75
76
  eid: EntityID;
76
77
  force?: boolean;
77
78
  };
79
+ /** One setBags outcome. Success carries the host seq in that bag's rlm. */
80
+ export type ISetBagResult = {
81
+ status: Status.Success;
82
+ seq: number;
83
+ } | {
84
+ status: Exclude<Status, Status.Success>;
85
+ };
78
86
  export interface IStorage {
79
87
  addUser: (pubKey: PublicKey) => Promise<ValStat<void>>;
80
88
  hasUser: (pubKey: PublicKey) => Promise<ValStat<boolean>>;
81
89
  subMeta: (pubKey: PublicKey) => Promise<ValStat<ISubscriptionMetadata>>;
82
90
  /**
83
- * Store bags for a user. Returns host seq for each bag in order.
84
- * Empty list succeeds with []. Implementations must assign contiguous
85
- * seqs atomically (transaction / single batch) so concurrent writers
86
- * cannot claim the same seq.
91
+ * Store bags for a user. One result per input bag, same order.
92
+ * An invalid rlm is InvalidParam for that bag; the others are still stored.
93
+ * Seqs are contiguous per rlm among stored bags, assigned atomically so
94
+ * concurrent writers cannot claim the same seq in the same rlm.
95
+ * Empty list succeeds with []. A storage failure fails the call.
87
96
  */
88
- setBags: (pubKey: PublicKey, bags: IBag[]) => Promise<ValStat<number[]>>;
97
+ setBags: (pubKey: PublicKey, bags: IBag[]) => Promise<ValStat<ISetBagResult[]>>;
89
98
  /**
90
- * Fetch ciphertext bodies for the given host seqs.
91
- * Returns only seqs that exist (missing seqs are omitted, not an error).
92
- * Empty `seqs` succeeds with [].
99
+ * Fetch ciphertext bodies for `seqs` in `rlm`.
100
+ * Missing seqs are omitted. Empty `seqs` succeeds with [].
93
101
  */
94
- getBodies: (pubKey: PublicKey, seqs: number[]) => Promise<ValStat<{
102
+ getBodies: (pubKey: PublicKey, rlm: HostRlm, seqs: number[]) => Promise<ValStat<{
95
103
  seq: number;
96
104
  bodyCph: Uint8Array;
97
105
  }[]>>;
98
- listHeads: (pubKey: PublicKey, minSeq: number) => Promise<ValStat<IBagPeekItem[]>>;
106
+ /** Heads in `rlm` with seq greater than minSeq, ordered by seq. */
107
+ listHeads: (pubKey: PublicKey, rlm: HostRlm, minSeq: number) => Promise<ValStat<IBagPeekItem[]>>;
99
108
  }
100
109
  export interface KeyPair {
101
110
  keyType: "ed25519";
@@ -123,7 +132,8 @@ export type Hash = Uint8Array & {
123
132
  readonly [hashSymbol]: true;
124
133
  };
125
134
  export interface IHostCrypto {
126
- checkSigEd25519: (sig: Uint8Array, message: Uint8Array | string, pubKey: PublicKey) => Promise<boolean>;
135
+ importVerifyKey: (pubKey: PublicKey) => Promise<CryptoKey>;
136
+ checkSigEd25519: (sig: Uint8Array, message: Uint8Array | string, verifyKey: CryptoKey) => Promise<boolean>;
127
137
  }
128
138
  /** BLAKE3 hash / MAC / KDF (noble: `key` XOR `context`, not both). */
129
139
  export type Blake3Opts = {
@@ -168,6 +178,9 @@ export interface IPushListener {
168
178
  disconnect(): void;
169
179
  }
170
180
  export interface IBagHeader {
181
+ /** HostRLM. Covered by sig, with headCph. */
182
+ rlm: HostRlm;
183
+ /** Ed25519 over rlm ‖ headCph. First field on the wire. */
171
184
  sig: Uint8Array;
172
185
  kdm: Uint8Array;
173
186
  }
@@ -29,6 +29,14 @@ export type PrfEvalOpts = PrfRp & {
29
29
  /** One id, or every bound id so a spare key can assert in one get(). */
30
30
  credId?: Uint8Array | readonly Uint8Array[];
31
31
  salt?: Uint8Array;
32
+ /**
33
+ * Salt for each cred when accounts do not share one.
34
+ * Sent as evalByCredential so the passkey the user picks evals its own.
35
+ */
36
+ salts?: readonly {
37
+ credId: Uint8Array;
38
+ salt: Uint8Array;
39
+ }[];
32
40
  };
33
41
  /** Best-effort: client advertises PRF extension. */
34
42
  export declare function prfCapable(): Promise<boolean>;
@@ -0,0 +1,30 @@
1
+ import type { IKDM } from "../shared/codecs/kdm";
2
+ import type { HostSeqsUpdate } from "../types";
3
+ import type { IRealm } from "./realm";
4
+ /** One host-realm cursor. The realm KDM plus the newest bag seq. */
5
+ export interface RealmCursor extends IKDM {
6
+ lastSeq: number;
7
+ }
8
+ declare const downloadKeySymbol: unique symbol;
9
+ /** Key of one queued download: host label, realm, and seq. */
10
+ export type DownloadKey = string & {
11
+ readonly [downloadKeySymbol]: true;
12
+ };
13
+ type CursorRow = {
14
+ lastSeq: number;
15
+ seqs?: RealmCursor[];
16
+ };
17
+ export declare function isDefaultRealm(realm?: IKDM): boolean;
18
+ export declare function sameRealm(a: IKDM, b: IKDM): boolean;
19
+ export declare function realmKey(realm: IKDM): string;
20
+ export declare function cursorOf(row: CursorRow, realm?: IKDM): number;
21
+ export declare function realmKDMs(rows: readonly IRealm[]): IKDM[];
22
+ export declare function realmKDM(label: string | undefined, rows: readonly IRealm[]): IKDM;
23
+ export declare function storedRealm(realm: IKDM): IKDM | undefined;
24
+ export declare function downloadKey(host: string, seq: number, realm?: IKDM): DownloadKey;
25
+ export declare function nextCursor(cur: number, u: HostSeqsUpdate): number | undefined;
26
+ export declare function projectCursors(cursors: readonly RealmCursor[]): {
27
+ lastSeq: number;
28
+ seqs?: RealmCursor[];
29
+ };
30
+ export {};
@@ -0,0 +1,58 @@
1
+ import { Status } from "../../shared/consts";
2
+ import { Enclave } from "../../shared/crypto/enclave";
3
+ import type { ICrypto } from "../../shared/types";
4
+ import { type ValStat } from "../../shared/valstat";
5
+ import type { PrfRp } from "../../shared/webauthn/prf";
6
+ import type { IAccountStore, SetSeedOpts } from "../../types";
7
+ import { type Keyring, PrfSeedStore, type PrfSeedStoreOpts } from "../../passkey/prf-store";
8
+ import { type KeyTag } from "../keyTag";
9
+ /**
10
+ * One account: its label, catalog id, database names, key tag, and the
11
+ * binding that unseals its key.
12
+ */
13
+ export type Account = {
14
+ label: string;
15
+ /** Stable id. Database names are derived from this. */
16
+ acct?: string;
17
+ /** Protocol database name. */
18
+ data?: string;
19
+ /** EntDB name. Absent until EntDB is opened. */
20
+ ents?: string;
21
+ keyTag?: KeyTag;
22
+ keyring?: Keyring;
23
+ };
24
+ export declare function decodeAccount(raw: unknown): Account | undefined;
25
+ export declare class IDBAccountStore implements IAccountStore {
26
+ #private;
27
+ db: IDBDatabase;
28
+ constructor(db: IDBDatabase, crypto: ICrypto);
29
+ setCloser(close: () => void): void;
30
+ /**
31
+ * Mint an account key with {@link Enclave.fromRandom} and store its key tag.
32
+ * A blank label is "". A label that already names a key is unchanged.
33
+ * An existing keyring on that row is kept. musec is wiped.
34
+ */
35
+ create(label: string, musec: Uint8Array): Promise<ValStat<Enclave>>;
36
+ /**
37
+ * Record the key tag for `opts.label`. Does not open the account.
38
+ * Durable identity is the account keyring
39
+ * ({@link openPrfStore} / {@link persistKeyring}), never plain seed.
40
+ * The row is created on the first save. A later save must match that
41
+ * account's key tag. `opts.persist` is ignored (kept for API compatibility).
42
+ *
43
+ * TODO(passphrase): when PRF is missing, seal under a passphrase KDF
44
+ * and store that ciphertext on this account row.
45
+ */
46
+ save(enclave: Enclave, opts?: SetSeedOpts): Promise<ValStat<Enclave>>;
47
+ dataName(label: string): Promise<string | undefined>;
48
+ ensureEnts(label: string): Promise<string>;
49
+ wipe(): Promise<void>;
50
+ loadKeyring(label?: string): Promise<Keyring | undefined>;
51
+ persistKeyring(ring: Keyring | undefined, label?: string): Promise<Status>;
52
+ hasKeyring(label?: string): Promise<boolean>;
53
+ unlock(opts: PrfRp): Promise<ValStat<{
54
+ enclave: Enclave;
55
+ label: string;
56
+ }>>;
57
+ openPrfStore(opts: Omit<PrfSeedStoreOpts, "persistKeyring" | "keyring" | "unlockAccount">, label?: string): Promise<ValStat<PrfSeedStore>>;
58
+ }
@@ -0,0 +1 @@
1
+ export declare function entsNameFor(label: string): Promise<string>;
@@ -1,9 +1,10 @@
1
+ import type { IKDM } from "../../shared/codecs/kdm";
1
2
  import { IDownloadMessage, IDownloadQueue } from "../../types";
2
3
  export declare class IDBDownloadQueue implements IDownloadQueue {
3
- db: IDBDatabase;
4
+ private db;
4
5
  constructor(db: IDBDatabase);
5
6
  enq(msgs: Iterable<IDownloadMessage>): Promise<void>;
6
- deq(host: string, seqs: Iterable<number>): Promise<void>;
7
+ deq(host: string, seqs: Iterable<number>, realm?: IKDM): Promise<void>;
7
8
  list(): Promise<IDownloadMessage[]>;
8
9
  count(): Promise<number>;
9
10
  wipe(): Promise<void>;
@@ -1,20 +1,21 @@
1
+ import type { IKDM } from "../../shared/codecs/kdm";
1
2
  import { Status } from "../../shared/consts";
2
3
  import { IHostConnectionInfo, IHostMetadata } from "../../shared/types";
3
- import type { HostStatsUpdate, IHostRow, IHostStore } from "../../types";
4
+ import type { HostSeqsUpdate, IHostRow, IHostStore } from "../../types";
4
5
  export declare class IDBHostStore implements IHostStore<URL> {
5
- db: IDBDatabase;
6
+ private db;
6
7
  constructor(db: IDBDatabase);
7
8
  /**
8
- * Upsert connection info. Same label + same handle/idx keeps lastSeq and
9
- * host meta (safe re-link). Changing handle/idx resets the peek cursor.
9
+ * Upsert connection info. Same label + same handle/idx keeps cursors and
10
+ * host meta (safe re-link). Changing handle/idx clears host_seqs.
10
11
  */
11
12
  add(info: IHostConnectionInfo<URL>): Promise<void>;
12
- private put;
13
- touch(label: string, seq: number): Promise<void>;
14
- recordStats(label: string, u: HostStatsUpdate): Promise<void>;
13
+ touch(label: string, seq: number, realm?: IKDM): Promise<void>;
14
+ recordSeqs(label: string, u: HostSeqsUpdate, realm?: IKDM): Promise<void>;
15
15
  get(label: string): Promise<IHostRow<URL> | undefined>;
16
16
  set(label: string, meta: IHostMetadata): Promise<Status.Success | Status.NotFound | Status.DatabaseError>;
17
17
  del(label: string): Promise<void>;
18
18
  list(): Promise<IHostRow<URL>[]>;
19
19
  wipe(): Promise<void>;
20
+ private put;
20
21
  }
@@ -0,0 +1,2 @@
1
+ export declare function deleteDatabase(name: string): Promise<void>;
2
+ export declare function openAt(name: string, version: number, upgrade: (db: IDBDatabase, tx: IDBTransaction) => void): Promise<IDBDatabase>;
@@ -0,0 +1,2 @@
1
+ export declare function openMetaDB(): Promise<IDBDatabase>;
2
+ export declare function openDataDB(name: string): Promise<IDBDatabase>;
@@ -3,8 +3,8 @@ import { ICrypto } from "../../shared/types";
3
3
  import { EntityID, Hash } from "../../shared/types";
4
4
  import { ApldState, IMessageStore, IStorableMessage, IStoredMessage, ListMsgsOpts } from "../../types";
5
5
  export declare class IDBMessageStore implements IMessageStore {
6
+ private db;
6
7
  private crypto;
7
- db: IDBDatabase;
8
8
  constructor(db: IDBDatabase, crypto: ICrypto);
9
9
  add(messages: IStorableMessage[]): Promise<Status[]>;
10
10
  del(keys: Iterable<Hash>): Promise<void>;
@@ -0,0 +1,13 @@
1
+ /** Account catalog. Unlock reads only this database. */
2
+ export declare const META_DB_NAME = "meta";
3
+ export declare const META_DB_VERSION = 1;
4
+ /** Protocol database: archive, queues, hosts, realm counters, host cursors. */
5
+ export declare const DATA_DB_VERSION = 9;
6
+ export declare function mintAcct(): string;
7
+ export declare function dataDbName(acct: string): string;
8
+ export declare function entsDbName(acct: string): string;
9
+ export declare function placeAccount(acct: string | undefined, data: string | undefined): {
10
+ acct: string;
11
+ data: string;
12
+ };
13
+ export declare function assignEnts(acct: string, current: string | undefined): string;
@@ -0,0 +1,11 @@
1
+ import { Status } from "../../shared/consts";
2
+ import { type IRealm, type IRealmStore } from "../realm";
3
+ /** Realm counters for the open account. The database is that account. */
4
+ export declare class IDBRealmStore implements IRealmStore {
5
+ private db;
6
+ constructor(db: IDBDatabase);
7
+ list(): Promise<IRealm[]>;
8
+ get(label: string): Promise<IRealm | undefined>;
9
+ put(label: string, index: number): Promise<Status>;
10
+ wipe(): Promise<void>;
11
+ }
@@ -1,12 +1,12 @@
1
+ import { Status } from "../../shared/consts";
1
2
  import { ICrypto } from "../../shared/types";
2
- import { IStore } from "../../types";
3
- import { IDBDownloadQueue } from "./dnlds";
4
- import { IDBHostStore } from "./hosts";
5
- import { IDBMessageStore } from "./msgs";
6
- import { IDBSeedStore } from "./seed";
7
- import { IDBUploadQueue } from "./uplds";
8
- export declare const SEED_META_TABLE = "seedMeta";
3
+ import { type ValStat } from "../../shared/valstat";
4
+ import { IAccountStore, IDownloadQueue, IHostStore, IMessageStore, IStore, IUploadQueue } from "../../types";
5
+ import type { IRealmStore } from "../realm";
6
+ export declare const ACCOUNTS_TABLE = "accounts";
9
7
  export declare const HOSTS_TABLE = "hosts";
8
+ /** Host-realm cursors. Key is host, realm label, realm index. */
9
+ export declare const HOST_SEQS_TABLE = "host_seqs";
10
10
  export declare const UPLOAD_QUEUE_TABLE = "uploadQueue";
11
11
  export declare const DOWNLOAD_QUEUE_TABLE = "downloadQueue";
12
12
  export declare const MESSAGES_TABLE = "messages";
@@ -16,22 +16,29 @@ export declare const MESSAGES_TABLE = "messages";
16
16
  * strings keep keys compact.
17
17
  */
18
18
  export declare const MESSAGES_APLD_INDEX = "apld";
19
- /** Schema version: v3 adds messages.apld index for the apply queue. */
20
- export declare const DIPLOMATIC_STORE_DB_VERSION = 3;
21
- export declare const DIPLOMATIC_STORE_DB_NAME = "diplomatic-store-db";
19
+ /** Realm label. Default-realm rows omit rlm and are not in this index. */
20
+ export declare const MESSAGES_RLM_INDEX = "rlm";
21
+ export declare const REALMS_TABLE = "realms";
22
22
  export declare class IDBStore implements IStore<URL> {
23
- seed: IDBSeedStore;
24
- hosts: IDBHostStore;
25
- uploads: IDBUploadQueue;
26
- downloads: IDBDownloadQueue;
27
- messages: IDBMessageStore;
28
- db: IDBDatabase;
29
- constructor(db: IDBDatabase, crypto: ICrypto);
23
+ #private;
24
+ account: IAccountStore;
25
+ realms: IRealmStore;
26
+ hosts: IHostStore<URL>;
27
+ uploads: IUploadQueue;
28
+ downloads: IDownloadQueue;
29
+ messages: IMessageStore;
30
+ constructor(account: IAccountStore, crypto: ICrypto, lookup?: (label: string) => Promise<string | undefined>, db?: IDBDatabase);
31
+ bind(label: string): Promise<Status>;
32
+ prepareWorker(label: string): Promise<ValStat<{
33
+ data: string;
34
+ ents: string;
35
+ }>>;
36
+ close(): void;
30
37
  /**
31
38
  * Clear protocol tables only (not seed). Seed is wiped only via
32
- * {@link ISeedStore.wipe} when client.wipe({ seed: true }).
39
+ * {@link IAccountStore.wipe} when client.wipe({ seed: true }).
33
40
  */
34
41
  wipe(): Promise<void>;
35
42
  }
36
- export declare function openIDBStoreDB(): Promise<IDBDatabase>;
37
43
  export declare function openIDBStore(crypto: ICrypto): Promise<IDBStore>;
44
+ export declare function openBoundStore(crypto: ICrypto, data: string): Promise<IDBStore>;
@@ -1,7 +1,7 @@
1
1
  import { Hash } from "../../shared/types";
2
2
  import { IUploadQueue } from "../../types";
3
3
  export declare class IDBUploadQueue implements IUploadQueue {
4
- db: IDBDatabase;
4
+ private db;
5
5
  constructor(db: IDBDatabase);
6
6
  enq(host: string, hshs: Iterable<Hash>): Promise<void>;
7
7
  deq(host: string, hshs: Iterable<Hash>): Promise<void>;
@@ -0,0 +1,14 @@
1
+ import { type PDK } from "../shared/crypto/derivation";
2
+ import type { Enclave } from "../shared/crypto/enclave";
3
+ import type { ICrypto } from "../shared/types";
4
+ import { type ValStat } from "../shared/valstat";
5
+ /** Nonce plus the fingerprint child that names the master. */
6
+ export type KeyTag = {
7
+ n: Uint8Array;
8
+ h: PDK["Fingerprint"];
9
+ };
10
+ export declare function keyTagDigest(enclave: Enclave, nonce: Uint8Array): Promise<ValStat<PDK["Fingerprint"]>>;
11
+ export declare function makeKeyTag(crypto: ICrypto, enclave: Enclave): Promise<ValStat<KeyTag>>;
12
+ export declare function keyTagMatches(enclave: Enclave, tag: KeyTag): Promise<boolean>;
13
+ export declare function decodeKeyTag(raw: unknown): KeyTag | undefined;
14
+ export declare function cloneKeyTag(tag: KeyTag): KeyTag;
@@ -0,0 +1,3 @@
1
+ import { type ValStat } from "../shared/valstat";
2
+ export declare function accountLabel(raw: string | undefined): ValStat<string>;
3
+ export declare function singleAccountLabel(current: string | undefined, raw: string | undefined, occupied: boolean): ValStat<string>;
@@ -0,0 +1,14 @@
1
+ import type { Enclave } from "../../shared/crypto/enclave";
2
+ import type { ICrypto } from "../../shared/types";
3
+ import { type ValStat } from "../../shared/valstat";
4
+ import type { IAccountStore, SetSeedOpts } from "../../types";
5
+ import { type KeyTag } from "../keyTag";
6
+ /** Account list in memory. One slot per label. The client holds the open account. */
7
+ export declare class MemoryAccountStore implements IAccountStore {
8
+ #private;
9
+ constructor(crypto: ICrypto);
10
+ save(enclave: Enclave, opts?: SetSeedOpts): Promise<ValStat<Enclave>>;
11
+ wipe(): Promise<void>;
12
+ /** Test helper: snapshot of one account's key tag. Omitted label is "". */
13
+ peekKeyTag(label?: string): KeyTag | undefined;
14
+ }
@@ -1,8 +1,10 @@
1
+ import type { IKDM } from "../../shared/codecs/kdm";
1
2
  import { IDownloadMessage, IDownloadQueue } from "../../types";
3
+ import { type DownloadKey } from "../cursor";
2
4
  export declare class MemoryDownloadQueue implements IDownloadQueue {
3
- queue: Map<string, IDownloadMessage>;
5
+ queue: Map<DownloadKey, IDownloadMessage>;
4
6
  enq(msgs: Iterable<IDownloadMessage>): Promise<void>;
5
- deq(host: string, seqs: Iterable<number>): Promise<void>;
7
+ deq(host: string, seqs: Iterable<number>, realm?: IKDM): Promise<void>;
6
8
  list(): Promise<IDownloadMessage[]>;
7
9
  count(): Promise<number>;
8
10
  wipe(): Promise<void>;
@@ -1,18 +1,20 @@
1
+ import type { IKDM } from "../../shared/codecs/kdm";
1
2
  import { Status } from "../../shared/consts";
2
3
  import { HostHandle, IHostConnectionInfo, IHostMetadata } from "../../shared/types";
3
- import type { HostStatsUpdate, IHostRow, IHostStore } from "../../types";
4
+ import type { HostSeqsUpdate, IHostRow, IHostStore } from "../../types";
4
5
  export declare class MemoryHostStore<Handle extends HostHandle> implements IHostStore<Handle> {
6
+ #private;
5
7
  hosts: Map<string, IHostRow<Handle>>;
6
8
  /**
7
- * Upsert connection info. Same label + same handle/idx keeps lastSeq and
8
- * host meta (safe re-link). Changing handle/idx resets the peek cursor.
9
+ * Upsert connection info. Same label + same handle/idx keeps cursors and
10
+ * host meta (safe re-link). Changing handle/idx clears cursors.
9
11
  */
10
12
  add(info: IHostConnectionInfo<Handle>): Promise<void>;
11
- touch(label: string, seq: number): Promise<void>;
12
- recordStats(label: string, u: HostStatsUpdate): Promise<void>;
13
+ touch(label: string, seq: number, realm?: IKDM): Promise<void>;
14
+ recordSeqs(label: string, u: HostSeqsUpdate, realm?: IKDM): Promise<void>;
13
15
  get(label: string): Promise<IHostRow<Handle> | undefined>;
14
16
  set(label: string, meta: IHostMetadata): Promise<Status.Success | Status.NotFound>;
15
17
  del(label: string): Promise<void>;
16
- list(): Promise<MapIterator<IHostRow<Handle>>>;
18
+ list(): Promise<IHostRow<Handle>[]>;
17
19
  wipe(): Promise<void>;
18
20
  }
@@ -0,0 +1,10 @@
1
+ import { Status } from "../../shared/consts";
2
+ import { type IRealm, type IRealmStore } from "../realm";
3
+ /** Realm counters in memory. One store is one account. */
4
+ export declare class MemoryRealmStore implements IRealmStore {
5
+ #private;
6
+ list(): Promise<IRealm[]>;
7
+ get(label: string): Promise<IRealm | undefined>;
8
+ put(label: string, index: number): Promise<Status>;
9
+ wipe(): Promise<void>;
10
+ }
@@ -1,16 +1,20 @@
1
+ import { Status } from "../../shared/consts";
1
2
  import { HostHandle, ICrypto } from "../../shared/types";
2
3
  import { IStore } from "../../types";
3
4
  import { MemoryDownloadQueue } from "./dnlds";
4
5
  import { MemoryHostStore } from "./hosts";
5
6
  import { MemoryMessageStore } from "./msgs";
6
- import { MemorySeedStore } from "./seed";
7
+ import { MemoryAccountStore } from "./account";
8
+ import { MemoryRealmStore } from "./realms";
7
9
  import { MemoryUploadQueue } from "./uplds";
8
10
  export declare class MemoryStore<Handle extends HostHandle> implements IStore<Handle> {
9
- seed: MemorySeedStore;
11
+ account: MemoryAccountStore;
12
+ realms: MemoryRealmStore;
10
13
  hosts: MemoryHostStore<Handle>;
11
14
  uploads: MemoryUploadQueue;
12
15
  downloads: MemoryDownloadQueue;
13
16
  messages: MemoryMessageStore;
14
17
  constructor(crypto: ICrypto);
18
+ bind(): Promise<Status>;
15
19
  wipe(): Promise<void>;
16
20
  }
@@ -0,0 +1,35 @@
1
+ import { Status } from "../shared/consts";
2
+ import { type ValStat } from "../shared/valstat";
3
+ declare const entRlmSymbol: unique symbol;
4
+ /** Non-empty realm label on an ent or archived message. */
5
+ export type EntRlm = string & {
6
+ readonly [entRlmSymbol]: true;
7
+ };
8
+ /** One realm. `index` is the current KDM counter; `prior` are older ones. */
9
+ export interface IRealm {
10
+ label: string;
11
+ index: number;
12
+ /** Counters older than `index` whose bags may still exist. */
13
+ prior?: number[];
14
+ }
15
+ /** Realm label for a row. The default realm ("" or missing) is omitted. */
16
+ export declare function realmLabel(raw: unknown): EntRlm | undefined;
17
+ /** Drops `rlm` when this row is in the default realm. */
18
+ export declare function omitDefaultRealm<T extends {
19
+ rlm?: EntRlm | string;
20
+ }>(row: T): T;
21
+ export declare function decodeRealm(raw: unknown): IRealm | undefined;
22
+ export declare function advanceRealm(label: string, prev: IRealm | undefined, index: number): ValStat<IRealm>;
23
+ /** Realm counters for one account. The store is that account. */
24
+ export interface IRealmStore {
25
+ list(): Promise<IRealm[]>;
26
+ /** One realm, or undefined when this account has no row for the label. */
27
+ get(label: string): Promise<IRealm | undefined>;
28
+ /**
29
+ * Set the current index.
30
+ * A higher index keeps the previous one in `prior`.
31
+ */
32
+ put(label: string, index: number): Promise<Status>;
33
+ wipe(): Promise<void>;
34
+ }
35
+ export {};