@mdbase-dev/sdk 0.1.0-beta.168 → 0.1.0-beta.173
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 +91 -3
- package/dist/app-host/account-key-host.d.ts +128 -0
- package/dist/app-host/account-key-host.js +449 -0
- package/dist/app-host/account-key-host.js.map +1 -0
- package/dist/app-host/app-environment.d.ts +3 -4
- package/dist/app-host/app-environment.js +6 -6
- package/dist/app-host/app-environment.js.map +1 -1
- package/dist/app-host/app-origin.d.ts +5 -2
- package/dist/app-host/app-origin.js +10 -6
- package/dist/app-host/app-origin.js.map +1 -1
- package/dist/app-host/cloud-copy-bootstrap.js +2 -2
- package/dist/app-host/cloud-copy-bootstrap.js.map +1 -1
- package/dist/app-host/cloud-copy-host.d.ts +69 -5
- package/dist/app-host/cloud-copy-host.js +289 -20
- package/dist/app-host/cloud-copy-host.js.map +1 -1
- package/dist/app-host/cloud-copy-persistence-idb.d.ts +0 -2
- package/dist/app-host/cloud-copy-persistence-idb.js +2 -2
- package/dist/app-host/cloud-copy-persistence-idb.js.map +1 -1
- package/dist/app-host/cp-authority.js +2 -2
- package/dist/app-host/cp-authority.js.map +1 -1
- package/dist/app-host/cp-people.js +2 -2
- package/dist/app-host/cp-people.js.map +1 -1
- package/dist/app-host/device-key-idb.d.ts +0 -2
- package/dist/app-host/device-key-idb.js +1 -1
- package/dist/app-host/device-key-idb.js.map +1 -1
- package/dist/app-host/device-key-provider.d.ts +0 -3
- package/dist/app-host/device-key-provider.js +1 -1
- package/dist/app-host/device-key-provider.js.map +1 -1
- package/dist/app-host/device-registration.js +2 -2
- package/dist/app-host/device-registration.js.map +1 -1
- package/dist/app-host/http-log.js +2 -2
- package/dist/app-host/http-log.js.map +1 -1
- package/dist/app-host/index.d.ts +4 -2
- package/dist/app-host/index.js +2 -1
- package/dist/app-host/index.js.map +1 -1
- package/dist/app-host/installation-sign-in.d.ts +16 -1
- package/dist/app-host/installation-sign-in.js +134 -27
- package/dist/app-host/installation-sign-in.js.map +1 -1
- package/dist/app-host/installation-store.d.ts +0 -2
- package/dist/app-host/installation-store.js +4 -4
- package/dist/app-host/installation-store.js.map +1 -1
- package/dist/app-host/log-push.js +2 -2
- package/dist/app-host/log-push.js.map +1 -1
- package/dist/app-host/noise-idb.d.ts +0 -3
- package/dist/app-host/noise-idb.js +1 -1
- package/dist/app-host/noise-idb.js.map +1 -1
- package/dist/app-host/private-bootstrap.js +2 -2
- package/dist/app-host/private-bootstrap.js.map +1 -1
- package/dist/app-host/private-persistence-idb.d.ts +0 -2
- package/dist/app-host/private-persistence-idb.js +1 -1
- package/dist/app-host/private-persistence-idb.js.map +1 -1
- package/dist/app-host/private-persistence.js +2 -2
- package/dist/app-host/private-persistence.js.map +1 -1
- package/dist/app-host/scoped-sign-in-session.d.ts +4 -0
- package/dist/app-host/scoped-sign-in-session.js +9 -1
- package/dist/app-host/scoped-sign-in-session.js.map +1 -1
- package/dist/app-host/unsynced-collection.js +8 -3
- package/dist/app-host/unsynced-collection.js.map +1 -1
- package/dist/app-host/wasm-runtime.d.ts +14 -0
- package/dist/app-host/wasm-runtime.js +45 -0
- package/dist/app-host/wasm-runtime.js.map +1 -1
- package/dist/app-host/web-collection.d.ts +4 -1
- package/dist/app-host/web-collection.js +214 -125
- package/dist/app-host/web-collection.js.map +1 -1
- package/dist/app-host/web-sign-in-problem.js +6 -1
- package/dist/app-host/web-sign-in-problem.js.map +1 -1
- package/dist/app-host/web-sign-in-session.d.ts +46 -4
- package/dist/app-host/web-sign-in-session.js +88 -15
- package/dist/app-host/web-sign-in-session.js.map +1 -1
- package/dist/application/asset-loader.d.ts +0 -1
- package/dist/application/asset-loader.js +2 -2
- package/dist/application/asset-loader.js.map +1 -1
- package/dist/application/asset-pins.json +4 -4
- package/dist/application/browser-selection.js +1 -1
- package/dist/application/browser-selection.js.map +1 -1
- package/dist/application/collection-selection.js +11 -6
- package/dist/application/collection-selection.js.map +1 -1
- package/dist/application/declaration.js +2 -2
- package/dist/application/declaration.js.map +1 -1
- package/dist/application/entry.d.ts +19 -0
- package/dist/application/entry.js +81 -38
- package/dist/application/entry.js.map +1 -1
- package/dist/application/front-door.d.ts +6 -1
- package/dist/application/front-door.js +5 -0
- package/dist/application/front-door.js.map +1 -1
- package/dist/application/local-build.d.ts +4 -2
- package/dist/application/local-build.js +4 -2
- package/dist/application/local-build.js.map +1 -1
- package/dist/application/manifest.d.ts +1 -0
- package/dist/application/manifest.js +8 -3
- package/dist/application/manifest.js.map +1 -1
- package/dist/application/native-assets.js +3 -4
- package/dist/application/native-assets.js.map +1 -1
- package/dist/application/packaged-assets.d.ts +1 -1
- package/dist/application/packaged-assets.js +6 -3
- package/dist/application/packaged-assets.js.map +1 -1
- package/dist/application/phase.d.ts +18 -1
- package/dist/application/phase.js +9 -1
- package/dist/application/phase.js.map +1 -1
- package/dist/application/portal-reservation.js +2 -2
- package/dist/application/portal-reservation.js.map +1 -1
- package/dist/application/registration.d.ts +3 -0
- package/dist/application/registration.js +7 -4
- package/dist/application/registration.js.map +1 -1
- package/dist/application/return-url.d.ts +1 -1
- package/dist/application/return-url.js +6 -7
- package/dist/application/return-url.js.map +1 -1
- package/dist/application/runtime.d.ts +7 -1
- package/dist/application/runtime.js +53 -4
- package/dist/application/runtime.js.map +1 -1
- package/dist/application/startup-timing.d.ts +20 -0
- package/dist/application/startup-timing.js +58 -0
- package/dist/application/startup-timing.js.map +1 -0
- package/dist/application/ui-connections.js +17 -4
- package/dist/application/ui-connections.js.map +1 -1
- package/dist/application/worker-client.d.ts +3 -0
- package/dist/application/worker-client.js +22 -2
- package/dist/application/worker-client.js.map +1 -1
- package/dist/application/worker-host.js +51 -3
- package/dist/application/worker-host.js.map +1 -1
- package/dist/application/worker-protocol.d.ts +7 -2
- package/dist/application/worker-protocol.js +10 -1
- package/dist/application/worker-protocol.js.map +1 -1
- package/dist/application/worker-session.d.ts +1 -1
- package/dist/application/worker-session.js +5 -1
- package/dist/application/worker-session.js.map +1 -1
- package/dist/application/worker.js +8394 -2001
- package/dist/application/worker.js.map +1 -1
- package/dist/browser/mdbase-sdk.js +8064 -3633
- package/dist/browser/mdbase-sdk.min.js +78 -78
- package/dist/describe-error.d.ts +2 -2
- package/dist/describe-error.js +9 -2
- package/dist/describe-error.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/local-build.d.ts +7 -4
- package/dist/local-build.js +7 -4
- package/dist/local-build.js.map +1 -1
- package/dist/native/provenance.json +5 -5
- package/dist/native/runtime.wasm +0 -0
- package/dist/private-account.js +13 -18
- package/dist/private-account.js.map +1 -1
- package/dist/testing/application.d.ts +3 -1
- package/dist/testing/application.js +8 -1
- package/dist/testing/application.js.map +1 -1
- package/dist/testing/test-app.d.ts +9 -0
- package/dist/testing/test-app.js +13 -0
- package/dist/testing/test-app.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -375,6 +375,72 @@ Not covered yet for Private collections:
|
|
|
375
375
|
report it: older servers, or an account whose access needs renewing. Gate
|
|
376
376
|
owner actions on `role === "owner"`; Connect still checks each action.
|
|
377
377
|
|
|
378
|
+
## Private collections on the app's own replica
|
|
379
|
+
|
|
380
|
+
An app that hosts its own replica through `MdbaseApplication` (`createMdbase`)
|
|
381
|
+
can open an existing Private collection with that replica, as a device of the
|
|
382
|
+
collection, instead of through the relay. The person unlocks it once with the
|
|
383
|
+
account's encryption password or recovery key. Connect only offers this to
|
|
384
|
+
apps it allows to hold a Private key.
|
|
385
|
+
|
|
386
|
+
- **Ask for it.** List `offline.replica` in the declaration's capabilities,
|
|
387
|
+
under `requirements.capabilities.optional` or `required`. Prefer `optional`:
|
|
388
|
+
the app then still signs in and syncs cloud copies where device access is not
|
|
389
|
+
offered, and consent for an app grant on a current account refuses an app
|
|
390
|
+
that lists it as required. The sign-in request asks for device access
|
|
391
|
+
(`requested_private_device`), and the person chooses which Private
|
|
392
|
+
collections to share. A server that does not know the request is asked again
|
|
393
|
+
without it, and one that does not offer device access to this app answers
|
|
394
|
+
with no Private collections; both leave an ordinary cloud-copy sign-in. An
|
|
395
|
+
installation paired before this needs to ask for access again.
|
|
396
|
+
- **List.** Entries in `snapshot.collections` carry `mode: "private"`; absent
|
|
397
|
+
means a cloud copy. A server from before this feature (after a rollback)
|
|
398
|
+
answers the list without modes; the SDK then asks once more with the earlier
|
|
399
|
+
request, so file actions are kept and no Private entry is listed.
|
|
400
|
+
- **Open.** `select(id)` as usual. An approval that shares only Private
|
|
401
|
+
collections names no selected collection, so the app arrives in its chooser;
|
|
402
|
+
when exactly one collection is approved the application opens it by itself,
|
|
403
|
+
as it does a sole cloud copy. A device that already holds the key goes
|
|
404
|
+
straight to `ready`. One that doesn't reads
|
|
405
|
+
`{kind: "needs_unlock", collectionId, displayName, mode, unlocking, problem}`.
|
|
406
|
+
There is no `connection` while locked.
|
|
407
|
+
- **Unlock.** For `mode: "password"`, call
|
|
408
|
+
`mdbase.unlock(collectionId, {password})` or `{recoveryKey}` with what the
|
|
409
|
+
person typed, and keep no copy. It resolves when the attempt has settled: the
|
|
410
|
+
collection continues to `ready` (or `needs_setup`) without a reload, or the
|
|
411
|
+
phase is still `needs_unlock` with `problem` set. `problem` is an
|
|
412
|
+
`MdbaseProblem` with its copy already described; its `key` is one of
|
|
413
|
+
`wrong_secret`, `invalid_recovery_key`, `rate_limited`, `unavailable`,
|
|
414
|
+
`unlock_unavailable` or `unlock_failed`. `mode: "strict"`
|
|
415
|
+
and `mode: "none"` cannot be unlocked here: explain that this collection has
|
|
416
|
+
to be opened on a computer running the mdbase app.
|
|
417
|
+
- **Retries.** Connect limits how often an account's sealed key can be fetched
|
|
418
|
+
(10 an hour, shared by all of the account's devices; `rate_limited` carries
|
|
419
|
+
the wait). A mistyped recovery key (`invalid_recovery_key`) and a password
|
|
420
|
+
shorter than the 12-character minimum (`wrong_secret`) are refused in the
|
|
421
|
+
Worker without any request. After a wrong secret the Worker keeps the sealed
|
|
422
|
+
bundle in memory for the next attempt on the same locked collection, and
|
|
423
|
+
uses it only while Connect's status still reports the same account key
|
|
424
|
+
version; it is dropped when the collection unlocks or closes.
|
|
425
|
+
- **Afterwards.** Once the unlock has applied, reopening needs no secret. A
|
|
426
|
+
restart before it applied returns to `needs_unlock`.
|
|
427
|
+
|
|
428
|
+
The password or recovery key is sent to the Worker as bytes that are wiped in
|
|
429
|
+
the tab as soon as they are posted and in the Worker when the call settles. The
|
|
430
|
+
key it unlocks is used once and wiped; neither is stored. One installation can
|
|
431
|
+
be a device of one Private collection (`private_device_limit` for a second),
|
|
432
|
+
and People is not available for these collections yet: `connection.people`
|
|
433
|
+
is present, and its reads reject with `upgrade_required`
|
|
434
|
+
(`people_unsupported`).
|
|
435
|
+
|
|
436
|
+
To fetch the sealed account key, the app runtime signs one fixed request: the
|
|
437
|
+
account-key fetch proof for its own connector and device, over the server's
|
|
438
|
+
challenge and the signed-in account. It signs nothing else for the account key
|
|
439
|
+
(no change, no strict approval, no caller-chosen digest), and the fetched
|
|
440
|
+
bundle is still sealed under the person's password or recovery key, which both
|
|
441
|
+
kinds of unlock need. An older app runtime without this signer answers
|
|
442
|
+
`unlock_unavailable`, and the collection stays `needs_unlock`.
|
|
443
|
+
|
|
378
444
|
## Managed application build environments
|
|
379
445
|
|
|
380
446
|
Application declarations support explicit `lab`, `staging` and `production`
|
|
@@ -383,9 +449,31 @@ trust handoff for that exact environment; changing an app build variable cannot
|
|
|
383
449
|
retarget a LAB archive. Staging packaging pins Connect to
|
|
384
450
|
`https://connect-staging.mdbase.dev`, production to `https://connect.mdbase.dev`.
|
|
385
451
|
CP/log origins and release trust still come only from the verified build context;
|
|
386
|
-
missing, expired or crossed trust refuses without a fallback.
|
|
387
|
-
|
|
388
|
-
|
|
452
|
+
missing, expired or crossed trust refuses without a fallback. Isolated `local`
|
|
453
|
+
builds remain separate and refuse all managed environments.
|
|
454
|
+
|
|
455
|
+
### Developing on localhost
|
|
456
|
+
|
|
457
|
+
In every managed environment the app's own `origin` may be a loopback HTTP
|
|
458
|
+
origin (`http://localhost:<port>`, `http://127.0.0.1:<port>` or
|
|
459
|
+
`http://[::1]:<port>`), so an app is developed against production with the
|
|
460
|
+
published package:
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
createMdbase({ id, name, origin: "http://localhost:5173", environment: "production", manifest: devManifest });
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
The manifest's `homepage` and `redirect_uris` use that same origin. Connect
|
|
467
|
+
registers it as its own application, apart from the one published at the HTTPS
|
|
468
|
+
origin: approvals and device storage belong to the exact origin and are not
|
|
469
|
+
shared between the two. The approval screen calls it "an app running on this
|
|
470
|
+
computer" and says its identity is unverified, as it does for a native app.
|
|
471
|
+
Connect's own origins (control plane, log) stay HTTPS outside LAB; no other
|
|
472
|
+
plain-HTTP app origin is accepted.
|
|
473
|
+
|
|
474
|
+
`vite dev` and `vite build` both work with Vite's default configuration: the
|
|
475
|
+
SDK's worker and WebAssembly files are served from `node_modules` in
|
|
476
|
+
development and emitted as assets in a build.
|
|
389
477
|
|
|
390
478
|
The app manifest must declare the installation origin under
|
|
391
479
|
`installation_origins.staging` for staging pairing, just as for other environments.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { type Argon2idRunner } from "../account-key.js";
|
|
2
|
+
import { type AccountKeyControlPort, type AccountKeyMode, type PrivateAccountRequestOptions } from "../private-account.js";
|
|
3
|
+
import { type AppAccountKeyState } from "./wasm-runtime.js";
|
|
4
|
+
/** What the person typed. Strings cannot be wiped in JavaScript: callers drop
|
|
5
|
+
* their references at once and never log, store or publish them. */
|
|
6
|
+
export type AppAccountKeySecret = Readonly<{
|
|
7
|
+
password: string;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
recoveryKey: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Why an unlock ended without a keyed device. The collection stays locked and
|
|
12
|
+
* usable for another attempt; each code has plain copy in `describeError`. */
|
|
13
|
+
export type AppAccountKeyUnlockProblem =
|
|
14
|
+
/** Wrong encryption password, or a recovery key of another account key. */
|
|
15
|
+
"wrong_secret"
|
|
16
|
+
/** The typed recovery key is not well formed. */
|
|
17
|
+
| "invalid_recovery_key"
|
|
18
|
+
/** The account has no account key: nothing to unlock with. */
|
|
19
|
+
| "no_account_key"
|
|
20
|
+
/** The account uses strict device approval: no password unlock exists. */
|
|
21
|
+
| "unlock_strict" | "rate_limited"
|
|
22
|
+
/** The account key service or the log could not be reached, or answered badly. */
|
|
23
|
+
| "unavailable"
|
|
24
|
+
/** This app runtime predates the account-key fetch proof signer. */
|
|
25
|
+
| "unlock_unavailable"
|
|
26
|
+
/** The secret is right, but this collection refused the grant (`detail`). */
|
|
27
|
+
| "unlock_failed";
|
|
28
|
+
export declare class AppAccountKeyUnlockError extends Error {
|
|
29
|
+
readonly reason: AppAccountKeyUnlockProblem;
|
|
30
|
+
readonly detail?: string | undefined;
|
|
31
|
+
readonly retryAfterMs?: number | undefined;
|
|
32
|
+
constructor(reason: AppAccountKeyUnlockProblem, detail?: string | undefined, retryAfterMs?: number | undefined);
|
|
33
|
+
}
|
|
34
|
+
/** The authenticated installation session of the adopted Private device. */
|
|
35
|
+
export interface AppAccountKeySession {
|
|
36
|
+
readonly accountId: string;
|
|
37
|
+
readonly connectorId: string;
|
|
38
|
+
readonly deviceId: string;
|
|
39
|
+
readonly collection: string;
|
|
40
|
+
readonly cpOrigin: string;
|
|
41
|
+
isCurrent(): boolean;
|
|
42
|
+
connectorBearer(options: {
|
|
43
|
+
signal: AbortSignal;
|
|
44
|
+
}): Promise<string>;
|
|
45
|
+
}
|
|
46
|
+
/** The native device, narrowed to what an unlock may do. */
|
|
47
|
+
export interface AppAccountKeyNative {
|
|
48
|
+
/** False when the pinned runtime has no account-key fetch signer. */
|
|
49
|
+
supportsFetchProof(): boolean;
|
|
50
|
+
/** The fixed `mdbase/v1/account-key-fetch` proof over a server challenge. */
|
|
51
|
+
signFetch(challenge: Uint8Array): Uint8Array;
|
|
52
|
+
/** Consumes and wipes the 32-byte loan on every path. */
|
|
53
|
+
unlockConsuming(secret: Uint8Array): AppAccountKeyState;
|
|
54
|
+
status(): AppAccountKeyState;
|
|
55
|
+
/** One foreground log turn. */
|
|
56
|
+
drive(options: {
|
|
57
|
+
signal: AbortSignal;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
/** The log head the replica knows; 0 until a log turn has succeeded. */
|
|
60
|
+
headKnown(): number;
|
|
61
|
+
}
|
|
62
|
+
export interface AppAccountKeyHostOptions {
|
|
63
|
+
readonly fetch?: typeof fetch;
|
|
64
|
+
readonly now?: () => number;
|
|
65
|
+
readonly allowLoopbackHttp?: boolean;
|
|
66
|
+
/** Off-thread Argon2id; the default runs in this Worker. */
|
|
67
|
+
readonly argon2id?: Argon2idRunner;
|
|
68
|
+
/** How long a started self-grant may stay pending before the call gives up
|
|
69
|
+
* (the grant itself is not withdrawn). */
|
|
70
|
+
readonly settleMs?: number;
|
|
71
|
+
}
|
|
72
|
+
/** The sealed account-key bundle that ONE locked Private collection keeps
|
|
73
|
+
* between unlock attempts, so a mistyped password or a recovery key of another
|
|
74
|
+
* account key does not spend the account-wide fetch budget (10 per hour, shared
|
|
75
|
+
* with the person's other devices) again. It is the ciphertext Connect already
|
|
76
|
+
* gave this device, held in RAM only: never persisted, published or returned
|
|
77
|
+
* to the app. A held answer is used only while the budget-free status route,
|
|
78
|
+
* which applies the same account and installation scope checks on every
|
|
79
|
+
* attempt, still reports the same account-key version and key id for the same
|
|
80
|
+
* account, connector and device. Anything else drops it and fetches afresh.
|
|
81
|
+
* `unlockPrivateDevice` drops it on every outcome but a wrong secret; the
|
|
82
|
+
* owner clears it when the collection closes (which is also sign-out). */
|
|
83
|
+
export declare class AppAccountKeySealedBundle {
|
|
84
|
+
private held;
|
|
85
|
+
/** True while a sealed bundle is held. */
|
|
86
|
+
get holding(): boolean;
|
|
87
|
+
clear(): void;
|
|
88
|
+
}
|
|
89
|
+
/** `AccountKeyControlPort` over the installation bearer: status, challenge and
|
|
90
|
+
* fetch only. One fixed request each, no retry, bounded decoded bodies. */
|
|
91
|
+
export declare class AppCpAccountKeyControl implements AccountKeyControlPort {
|
|
92
|
+
private readonly session;
|
|
93
|
+
private readonly sign;
|
|
94
|
+
readonly accountId: string;
|
|
95
|
+
private readonly lifetime;
|
|
96
|
+
private readonly origin;
|
|
97
|
+
private readonly deviceId;
|
|
98
|
+
private readonly fetchImpl;
|
|
99
|
+
private readonly now;
|
|
100
|
+
constructor(session: AppAccountKeySession, sign: (challenge: Uint8Array) => Uint8Array, options?: AppAccountKeyHostOptions);
|
|
101
|
+
private check;
|
|
102
|
+
private request;
|
|
103
|
+
status(options: PrivateAccountRequestOptions): Promise<unknown>;
|
|
104
|
+
challenge(options: PrivateAccountRequestOptions): Promise<unknown>;
|
|
105
|
+
/** A fresh single-use challenge, the native fetch proof over it, then the
|
|
106
|
+
* bundle. The challenge and signature are wiped here; the bundle is returned
|
|
107
|
+
* to PrivateAccount only. */
|
|
108
|
+
fetch(options: PrivateAccountRequestOptions): Promise<unknown>;
|
|
109
|
+
put(): Promise<unknown>;
|
|
110
|
+
strict(): Promise<unknown>;
|
|
111
|
+
enrolRecoveryDevice(): Promise<unknown>;
|
|
112
|
+
close(): void;
|
|
113
|
+
}
|
|
114
|
+
/** The account-key mode from the status route (no bundle, no proof, not on the
|
|
115
|
+
* fetch budget). A failed read rejects: the mode is never guessed. */
|
|
116
|
+
export declare function readAccountKeyMode(session: AppAccountKeySession, options: AppAccountKeyHostOptions & {
|
|
117
|
+
signal: AbortSignal;
|
|
118
|
+
}): Promise<AccountKeyMode>;
|
|
119
|
+
/** Unlock this device's ONE adopted Private collection with the account key.
|
|
120
|
+
* Resolves only once the native applied policy has this device keyed and
|
|
121
|
+
* trusted. A typed `AppAccountKeyUnlockError` leaves the collection locked and
|
|
122
|
+
* open for another attempt; anything else is a lost owner or cancelled call. */
|
|
123
|
+
export declare function unlockPrivateDevice(session: AppAccountKeySession, native: AppAccountKeyNative, secret: AppAccountKeySecret, options: AppAccountKeyHostOptions & {
|
|
124
|
+
signal: AbortSignal;
|
|
125
|
+
onMode?(mode: AccountKeyMode): void;
|
|
126
|
+
/** This locked collection's holder for the sealed bundle between attempts. Without one, every attempt fetches. */
|
|
127
|
+
sealed?: AppAccountKeySealedBundle;
|
|
128
|
+
}): Promise<void>;
|