@serfab/cadre-core 1.16.0 → 1.17.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.
- package/README.md +1 -1
- package/dist/bootstrap-peer-store-file.js +1 -1
- package/dist/bootstrap-peer-store.d.ts +1 -1
- package/dist/bootstrap-peer-store.js +4 -4
- package/dist/cadre-invite-protocol.d.ts +55 -138
- package/dist/cadre-invite-protocol.js +94 -449
- package/dist/cadre-invite-protocol.js.map +1 -1
- package/dist/cadre-join-request.d.ts +15 -2
- package/dist/cadre-join-request.js +22 -3
- package/dist/cadre-join-request.js.map +1 -1
- package/dist/cadre-node.d.ts +530 -247
- package/dist/cadre-node.js +1046 -525
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +36 -14
- package/dist/control-authorization.js +20 -3
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.d.ts +22 -23
- package/dist/control-cohort.js +24 -24
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +416 -136
- package/dist/control-database.js +757 -378
- package/dist/control-database.js.map +1 -1
- package/dist/control-protocol-guard.d.ts +5 -4
- package/dist/control-protocol-guard.js +6 -3
- package/dist/control-protocol-guard.js.map +1 -1
- package/dist/control-schema-version.d.ts +80 -0
- package/dist/control-schema-version.js +203 -0
- package/dist/control-schema-version.js.map +1 -0
- package/dist/control-schema.d.ts +45 -5
- package/dist/control-schema.js +254 -70
- package/dist/control-schema.js.map +1 -1
- package/dist/control-write-retry.d.ts +5 -5
- package/dist/control-write-retry.js +10 -8
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +13 -0
- package/dist/delegate-admission.js +27 -0
- package/dist/delegate-admission.js.map +1 -1
- package/dist/ed25519-key.d.ts +10 -7
- package/dist/ed25519-key.js +23 -20
- package/dist/ed25519-key.js.map +1 -1
- package/dist/edge-node/config.d.ts +122 -0
- package/dist/edge-node/config.js +199 -0
- package/dist/edge-node/config.js.map +1 -0
- package/dist/edge-node/dissolve.d.ts +95 -0
- package/dist/edge-node/dissolve.js +184 -0
- package/dist/edge-node/dissolve.js.map +1 -0
- package/dist/edge-node/edge-join.d.ts +44 -0
- package/dist/edge-node/edge-join.js +227 -0
- package/dist/edge-node/edge-join.js.map +1 -0
- package/dist/edge-node/edge-node.d.ts +295 -0
- package/dist/edge-node/edge-node.js +704 -0
- package/dist/edge-node/edge-node.js.map +1 -0
- package/dist/edge-node/index.d.ts +18 -0
- package/dist/edge-node/index.js +18 -0
- package/dist/edge-node/index.js.map +1 -0
- package/dist/edge-node/join-credential.d.ts +11 -0
- package/dist/edge-node/join-credential.js +11 -0
- package/dist/edge-node/join-credential.js.map +1 -0
- package/dist/edge-node/lazy-raw-storage.d.ts +40 -0
- package/dist/edge-node/lazy-raw-storage.js +134 -0
- package/dist/edge-node/lazy-raw-storage.js.map +1 -0
- package/dist/edge-node/node-local.d.ts +60 -0
- package/dist/edge-node/node-local.js +58 -0
- package/dist/edge-node/node-local.js.map +1 -0
- package/dist/edge-node/options.d.ts +83 -0
- package/dist/edge-node/options.js +110 -0
- package/dist/edge-node/options.js.map +1 -0
- package/dist/edge-node/owner-grant.d.ts +41 -0
- package/dist/edge-node/owner-grant.js +38 -0
- package/dist/edge-node/owner-grant.js.map +1 -0
- package/dist/edge-node/platform.d.ts +140 -0
- package/dist/edge-node/platform.js +12 -0
- package/dist/edge-node/platform.js.map +1 -0
- package/dist/edge-node/strand-move.d.ts +115 -0
- package/dist/edge-node/strand-move.js +223 -0
- package/dist/edge-node/strand-move.js.map +1 -0
- package/dist/edge-node/strands.d.ts +28 -0
- package/dist/edge-node/strands.js +60 -0
- package/dist/edge-node/strands.js.map +1 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.js +26 -7
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +3 -3
- package/dist/joined-strand-store.js +3 -3
- package/dist/joined-strand-store.js.map +1 -1
- package/dist/key-store.d.ts +9 -4
- package/dist/key-store.js +9 -4
- package/dist/key-store.js.map +1 -1
- package/dist/machine-removal.d.ts +19 -39
- package/dist/machine-removal.js +24 -98
- package/dist/machine-removal.js.map +1 -1
- package/dist/member-redemption.d.ts +250 -0
- package/dist/member-redemption.js +485 -0
- package/dist/member-redemption.js.map +1 -0
- package/dist/owner-anchor-sync.d.ts +4 -4
- package/dist/owner-anchor-sync.js +16 -15
- package/dist/owner-anchor-sync.js.map +1 -1
- package/dist/owner-grant-protocol.d.ts +247 -0
- package/dist/owner-grant-protocol.js +330 -0
- package/dist/owner-grant-protocol.js.map +1 -0
- package/dist/owner-key-export.d.ts +70 -0
- package/dist/owner-key-export.js +279 -0
- package/dist/owner-key-export.js.map +1 -0
- package/dist/owner-key-flows.d.ts +55 -0
- package/dist/owner-key-flows.js +60 -0
- package/dist/owner-key-flows.js.map +1 -0
- package/dist/owner-key-store.d.ts +31 -0
- package/dist/owner-key-store.js +81 -0
- package/dist/owner-key-store.js.map +1 -0
- package/dist/owner-keys.d.ts +78 -0
- package/dist/owner-keys.js +133 -0
- package/dist/owner-keys.js.map +1 -0
- package/dist/owner-signer.d.ts +54 -0
- package/dist/owner-signer.js +51 -0
- package/dist/owner-signer.js.map +1 -0
- package/dist/peer-authorization.d.ts +83 -18
- package/dist/peer-authorization.js +123 -53
- package/dist/peer-authorization.js.map +1 -1
- package/dist/provider/rent-node.js +1 -1
- package/dist/provider/rent-node.js.map +1 -1
- package/dist/seed-bootstrap.d.ts +131 -109
- package/dist/seed-bootstrap.js +260 -248
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/seed-trust-policy.js +4 -4
- package/dist/strand-addr-protocol.d.ts +4 -1
- package/dist/strand-addr-protocol.js +8 -2
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-cohort.d.ts +3 -0
- package/dist/strand-cohort.js.map +1 -1
- package/dist/strand-database.d.ts +1 -0
- package/dist/strand-database.js +3 -0
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +4 -3
- package/dist/strand-first-sync-gate.js +4 -3
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +1 -1
- package/dist/strand-membership-writer.d.ts +13 -2
- package/dist/strand-membership-writer.js +52 -16
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-move.d.ts +6 -5
- package/dist/strand-move.js +31 -30
- package/dist/strand-move.js.map +1 -1
- package/dist/strand-peer-redial.js +2 -3
- package/dist/strand-peer-redial.js.map +1 -1
- package/dist/types.d.ts +286 -103
- package/dist/types.js.map +1 -1
- package/package.json +11 -2
- package/src/bootstrap-peer-store-file.ts +44 -44
- package/src/bootstrap-peer-store.ts +214 -214
- package/src/cadre-invite-protocol.ts +652 -1052
- package/src/cadre-join-request.ts +24 -3
- package/src/cadre-node.ts +1166 -541
- package/src/control-authorization.ts +47 -14
- package/src/control-cohort.ts +127 -128
- package/src/control-database.ts +940 -456
- package/src/control-protocol-guard.ts +7 -4
- package/src/control-schema-version.ts +251 -0
- package/src/control-schema.ts +265 -70
- package/src/control-write-retry.ts +569 -567
- package/src/delegate-admission.ts +37 -0
- package/src/ed25519-key.ts +174 -171
- package/src/edge-node/config.ts +277 -0
- package/src/edge-node/dissolve.ts +251 -0
- package/src/edge-node/edge-join.ts +319 -0
- package/src/edge-node/edge-node.ts +1045 -0
- package/src/edge-node/index.ts +59 -0
- package/src/edge-node/join-credential.ts +16 -0
- package/src/edge-node/lazy-raw-storage.ts +178 -0
- package/src/edge-node/node-local.ts +84 -0
- package/src/edge-node/options.ts +179 -0
- package/src/edge-node/owner-grant.ts +63 -0
- package/src/edge-node/platform.ts +151 -0
- package/src/edge-node/strand-move.ts +270 -0
- package/src/edge-node/strands.ts +72 -0
- package/src/index.ts +886 -789
- package/src/joined-strand-store.ts +4 -4
- package/src/key-store.ts +10 -4
- package/src/machine-removal.ts +26 -111
- package/src/member-redemption.ts +642 -0
- package/src/owner-anchor-sync.ts +19 -18
- package/src/owner-grant-protocol.ts +532 -0
- package/src/owner-key-export.ts +348 -0
- package/src/owner-key-flows.ts +109 -0
- package/src/owner-key-store.ts +85 -0
- package/src/owner-keys.ts +178 -0
- package/src/owner-signer.ts +94 -0
- package/src/peer-authorization.ts +558 -488
- package/src/provider/rent-node.ts +1 -1
- package/src/seed-bootstrap.ts +301 -312
- package/src/seed-trust-policy.ts +4 -4
- package/src/strand-addr-protocol.ts +547 -538
- package/src/strand-cohort.ts +4 -0
- package/src/strand-database.ts +3 -0
- package/src/strand-first-sync-gate.ts +4 -3
- package/src/strand-instance-manager.ts +1 -1
- package/src/strand-membership-writer.ts +61 -16
- package/src/strand-move.ts +45 -36
- package/src/strand-peer-redial.ts +2 -3
- package/src/types.ts +304 -103
package/src/types.ts
CHANGED
|
@@ -17,8 +17,10 @@ import type { StrandNetworkStateStore } from './strand-network-state.js';
|
|
|
17
17
|
import type { EnrolledMachineStore } from './enrolled-machine-store.js';
|
|
18
18
|
import type { JoinedStrandStore } from './joined-strand-store.js';
|
|
19
19
|
import type { PushNotifier } from './push-notifier.js';
|
|
20
|
-
import type { CadreInviteSignedFields, RevocableTable } from './control-authorization.js';
|
|
21
|
-
import type { CadreInvitation
|
|
20
|
+
import type { CadreInviteSignedFields, OwnerGrantSignedFields, RevocableTable } from './control-authorization.js';
|
|
21
|
+
import type { CadreInvitation } from './cadre-invite-protocol.js';
|
|
22
|
+
import type { OwnerGrantBundle } from './owner-grant-protocol.js';
|
|
23
|
+
import type { RedemptionAddressOutcome } from './member-redemption.js';
|
|
22
24
|
import type { ControlRetryAbandonment } from './control-retry.js';
|
|
23
25
|
import type { FormationRejectionCode } from './strand-formation-rejection.js';
|
|
24
26
|
import type { ListenTransportOptions } from './relay-addrs.js';
|
|
@@ -776,11 +778,10 @@ export interface CadreNodeConfig {
|
|
|
776
778
|
* form). Mutually exclusive with {@link privateKey}. Absent ⇒ use `privateKey`
|
|
777
779
|
* when set, else libp2p generates an ephemeral key.
|
|
778
780
|
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
*
|
|
783
|
-
* built here.
|
|
781
|
+
* The node signs owner writes through whatever owner signer the embedder wires
|
|
782
|
+
* (`CadreNode.useOwnerSigner`). An owner key has its own slot
|
|
783
|
+
* (`owner-key-store.ts`), which may be in this same store; this identity is never
|
|
784
|
+
* an owner key.
|
|
784
785
|
*/
|
|
785
786
|
keyStore?: KeyStore;
|
|
786
787
|
|
|
@@ -972,7 +973,7 @@ export interface CadreNodeConfig {
|
|
|
972
973
|
*
|
|
973
974
|
* A node has exactly one cold-start trust source, so `claim` beside a non-empty
|
|
974
975
|
* `trustedOwners.pinnedKeys` or a `seedTrustPolicy` fails `start()` closed, and
|
|
975
|
-
* `
|
|
976
|
+
* `useOwnerSigner` (an owner key) refuses on such a node: a hosted node never
|
|
976
977
|
* holds an owner key. A claimed node restarted with this still set ignores it (its
|
|
977
978
|
* anchor is non-empty), so the operator need not remove it.
|
|
978
979
|
*
|
|
@@ -1025,7 +1026,7 @@ export interface CadreNodeConfig {
|
|
|
1025
1026
|
/**
|
|
1026
1027
|
* Provenance recorded for {@link pinnedKeys}. Default: 'operator'.
|
|
1027
1028
|
* ('genesis' is reserved for the node's own founding key, seeded
|
|
1028
|
-
* internally by `
|
|
1029
|
+
* internally by `useOwnerSigner`; 'chain' is written only by the
|
|
1029
1030
|
* anchor sync, `CadreNode.syncOwnerAnchor`.)
|
|
1030
1031
|
*/
|
|
1031
1032
|
pinnedSource?: Exclude<TrustSource, 'genesis' | 'chain'>;
|
|
@@ -1272,16 +1273,21 @@ export interface StrandRow {
|
|
|
1272
1273
|
MemberPrivateKey: string | null;
|
|
1273
1274
|
Type: 'o' | 'c';
|
|
1274
1275
|
/**
|
|
1275
|
-
* ed25519 (base64url) owner key
|
|
1276
|
-
*
|
|
1277
|
-
* the
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
* `null` on a consent-seated strand (the unsigned `FormationUsage` branch
|
|
1281
|
-
* records no trustworthy signer). Provenance, not content —
|
|
1282
|
-
* `strandRowMismatches` excludes it from the identical-content comparison.
|
|
1276
|
+
* ed25519 (base64url) owner key that signed the owner-signed `Strand` insert
|
|
1277
|
+
* (`== context.OwnerKey`, pinned by the schema's `AuthorizedInsert`). `null` on a
|
|
1278
|
+
* consent-seated strand (the unsigned `FormationUsage` branch records no
|
|
1279
|
+
* signer). Provenance, not content — `strandRowMismatches` excludes it from the
|
|
1280
|
+
* identical-content comparison.
|
|
1283
1281
|
*/
|
|
1284
1282
|
FounderOwnerKey: string | null;
|
|
1283
|
+
/**
|
|
1284
|
+
* Peer id of the machine that runs the founder bootstrap, named by the owner
|
|
1285
|
+
* signature on the insert (`CadreNode.publishStrand` writes its own). A launch
|
|
1286
|
+
* with no explicit `founder` flag founds iff this is its own peer id (see
|
|
1287
|
+
* `CadreNode.launchStrand`), so two machines holding one owner key never both
|
|
1288
|
+
* found. `null` on a consent-seated strand. Provenance, as {@link FounderOwnerKey}.
|
|
1289
|
+
*/
|
|
1290
|
+
FounderPeerId: string | null;
|
|
1285
1291
|
}
|
|
1286
1292
|
|
|
1287
1293
|
/**
|
|
@@ -1404,7 +1410,7 @@ export interface StrandConfig {
|
|
|
1404
1410
|
* unset and writes nothing — it receives those rows via Optimystic sync.
|
|
1405
1411
|
*
|
|
1406
1412
|
* When unset, founder-ness is DERIVED from the row: this node founds iff
|
|
1407
|
-
* {@link StrandRow.
|
|
1413
|
+
* {@link StrandRow.FounderPeerId} is its own peer id. An explicit
|
|
1408
1414
|
* `true`/`false` wins over the derivation — the formation/responder flows pass
|
|
1409
1415
|
* it deliberately, since a consent-seated row carries a null column.
|
|
1410
1416
|
*/
|
|
@@ -1492,6 +1498,37 @@ export interface FoundStrandResult {
|
|
|
1492
1498
|
founded: boolean;
|
|
1493
1499
|
}
|
|
1494
1500
|
|
|
1501
|
+
/**
|
|
1502
|
+
* Options for {@link CadreNode.foundStrand}. Passing them selects the form that returns once
|
|
1503
|
+
* the row is published ({@link FoundStrandBackgroundResult}), for a caller that needs only the
|
|
1504
|
+
* row: minting an invitation reads just its id and membership key.
|
|
1505
|
+
*
|
|
1506
|
+
* An invitation redeemed before the start finishes is refused, retryably: a closed host
|
|
1507
|
+
* strand answers `host-strand-unavailable` and leaves the token unspent. For an open host
|
|
1508
|
+
* strand the approval is sent, but carries no strand addresses, because the strand node does
|
|
1509
|
+
* not exist yet.
|
|
1510
|
+
*/
|
|
1511
|
+
export interface FoundStrandOptions {
|
|
1512
|
+
/** Return once the row is published; the start continues in {@link FoundStrandBackgroundResult.ready}. */
|
|
1513
|
+
background: true;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
/** What {@link CadreNode.foundStrand} returns with `{ background: true }`: the row is published; the local start continues. */
|
|
1517
|
+
export interface FoundStrandBackgroundResult {
|
|
1518
|
+
/** The live control-plane row: freshly published, or the one already there. Same as {@link FoundStrandResult.strandRow}. */
|
|
1519
|
+
strandRow: StrandRow;
|
|
1520
|
+
/** Same as {@link FoundStrandResult.founded}. */
|
|
1521
|
+
founded: boolean;
|
|
1522
|
+
/**
|
|
1523
|
+
* Settles when the local start does. Resolves with the instance `addStrand` returns.
|
|
1524
|
+
* Rejects with the start's own error. After a launch failure the strand stays published
|
|
1525
|
+
* and the strand watcher keeps retrying it. After a first-sync timeout (only an adopted,
|
|
1526
|
+
* not-founded row waits for one) the instance stays up and still syncing, so wait with
|
|
1527
|
+
* {@link CadreNode.whenStrandWritable}.
|
|
1528
|
+
*/
|
|
1529
|
+
ready: Promise<StrandInstance>;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1495
1532
|
/**
|
|
1496
1533
|
* Result of creating a new cadre peer
|
|
1497
1534
|
*/
|
|
@@ -1742,7 +1779,7 @@ export interface CadreNodeEvents {
|
|
|
1742
1779
|
* Also emitted for a strand this node joined from ANOTHER party, which no control
|
|
1743
1780
|
* row names: the node remembers every such join (see
|
|
1744
1781
|
* {@link CadreNodeConfig.joinedStrands}) and offers it here on each start, as a row
|
|
1745
|
-
* with
|
|
1782
|
+
* with null founder columns carrying the closed strand's `MemberPrivateKey`. That
|
|
1746
1783
|
* row is the product of the formation's consent, so claiming it needs no second one.
|
|
1747
1784
|
*
|
|
1748
1785
|
* **Fired once per strand per session, and it can fire before your listener is
|
|
@@ -1915,25 +1952,27 @@ export type CadrePeerVoucherFields = Pick<CadrePeerRow, 'peerId' | 'stampId' | '
|
|
|
1915
1952
|
|
|
1916
1953
|
/**
|
|
1917
1954
|
* One live `CadreControl.OwnerKey` row as `ControlDatabase.queryOwnerKeyRows` reads it: the
|
|
1918
|
-
* key and the persisted proof of how it was seated. The three proof shapes are the
|
|
1919
|
-
* (`OwnerKey.Authorized`): the founding row (all three null), an owner-signed add
|
|
1920
|
-
* and `vouchSig`, the signer's signature over `ownerKeyAddDigest(key, stampId)`), or an
|
|
1921
|
-
* owner
|
|
1922
|
-
* `
|
|
1923
|
-
* the stampless row the schema permits but no writer produces,
|
|
1924
|
-
* `stampId` is non-null here. The anchor sync (`deriveOwnerAnchor`)
|
|
1925
|
-
* the proof against the keys it already trusts, never against the table itself.
|
|
1955
|
+
* key, its label and the persisted proof of how it was seated. The three proof shapes are the
|
|
1956
|
+
* schema's (`OwnerKey.Authorized`): the founding row (all three null), an owner-signed add
|
|
1957
|
+
* (`vouchOwner` and `vouchSig`, the signer's signature over `ownerKeyAddDigest(key, label, stampId)`), or an
|
|
1958
|
+
* owner grant redeemed by consent (`vouchOwner` the issuer, `vouchSig` null, `vouchUsage` the
|
|
1959
|
+
* `OwnerGrantUsage` row). Rows whose stamp is
|
|
1960
|
+
* retired in `Revocation`, and the stampless row the schema permits but no writer produces,
|
|
1961
|
+
* never reach a reader, so `stampId` is non-null here. The anchor sync (`deriveOwnerAnchor`)
|
|
1962
|
+
* judges the proof against the keys it already trusts, never against the table itself.
|
|
1926
1963
|
*/
|
|
1927
1964
|
export interface OwnerKeyRow {
|
|
1928
1965
|
/** ed25519 public key (base64url) — the row key. */
|
|
1929
1966
|
key: string;
|
|
1967
|
+
/** The user's name for the key, bound into an owner-signed add or into the grant that seated it; null when none was given. */
|
|
1968
|
+
label: string | null;
|
|
1930
1969
|
/** Single-use anti-replay nonce the voucher signature, or the usage row, is bound to. */
|
|
1931
1970
|
stampId: string;
|
|
1932
|
-
/** The owner that signed the add, or that issued the
|
|
1971
|
+
/** The owner that signed the add, or that issued the grant that seated it; null on the founding row. */
|
|
1933
1972
|
vouchOwner: string | null;
|
|
1934
|
-
/** That owner's signature over the row's `'add'` digest, base64url; null on the founding row and on
|
|
1973
|
+
/** That owner's signature over the row's `'add'` digest, base64url; null on the founding row and on a consent-seated row. */
|
|
1935
1974
|
vouchSig: string | null;
|
|
1936
|
-
/** The `
|
|
1975
|
+
/** The `OwnerGrantUsage.UsageStampId` that seated this row; null otherwise. */
|
|
1937
1976
|
vouchUsage: string | null;
|
|
1938
1977
|
}
|
|
1939
1978
|
|
|
@@ -1967,10 +2006,8 @@ export interface CadreInviteUsageRow {
|
|
|
1967
2006
|
peerId: string;
|
|
1968
2007
|
/** The admitted device's ed25519 public key (base64url). */
|
|
1969
2008
|
peerKey: string;
|
|
1970
|
-
/** The `CadrePeer.StampId` this redemption seated
|
|
2009
|
+
/** The `CadrePeer.StampId` this redemption seated. */
|
|
1971
2010
|
peerStampId: string;
|
|
1972
|
-
/** The `OwnerKey.StampId` this redemption seated, when the invitation grants ownership; else null. */
|
|
1973
|
-
ownerStampId: string | null;
|
|
1974
2011
|
/** The invitation private key's signature over the `'redeem'` digest, base64url. */
|
|
1975
2012
|
inviteSig: string;
|
|
1976
2013
|
/** The device's signature over the `'consent'` digest, base64url. */
|
|
@@ -1978,11 +2015,9 @@ export interface CadreInviteUsageRow {
|
|
|
1978
2015
|
}
|
|
1979
2016
|
|
|
1980
2017
|
/**
|
|
1981
|
-
* The usage and invitation rows an invitation-admitted row is verified through
|
|
1982
|
-
* `
|
|
1983
|
-
*
|
|
1984
|
-
* `verifyInvitationOwnerAdmission` (`deriveOwnerAnchor`). Loaded once per membership refresh
|
|
1985
|
-
* (`CadreNode.loadInvitationChain`) and shared by both readers.
|
|
2018
|
+
* The usage and invitation rows an invitation-admitted `CadrePeer` row is verified through
|
|
2019
|
+
* (`verifyInvitationAdmission`, `CadreNode.listAuthorizedMembers`), keyed by `UsageStampId`
|
|
2020
|
+
* and `CadreInvite.Key`. Loaded once per membership refresh (`CadreNode.loadInvitationChain`).
|
|
1986
2021
|
*/
|
|
1987
2022
|
export interface InvitationChain {
|
|
1988
2023
|
usages: Map<string, CadreInviteUsageRow>;
|
|
@@ -1990,9 +2025,56 @@ export interface InvitationChain {
|
|
|
1990
2025
|
}
|
|
1991
2026
|
|
|
1992
2027
|
/**
|
|
1993
|
-
* One
|
|
1994
|
-
*
|
|
1995
|
-
*
|
|
2028
|
+
* One `CadreControl.OwnerGrant` row: an owner-signed grant of ownership to whoever holds its
|
|
2029
|
+
* private half, as `ControlDatabase.insertOwnerGrant` returns it and `queryOwnerGrant` reads
|
|
2030
|
+
* it. Every column is here because the row travels, as a {@link CadreInviteRow} does: the
|
|
2031
|
+
* holder carries it inside the grant bundle and a member re-seats it verbatim
|
|
2032
|
+
* (`seatOwnerGrant`), so `expiresAt` is the engine-canonical `datetime` string the row
|
|
2033
|
+
* stores. The signed subset is `OwnerGrantSignedFields` (`control-authorization.ts`); the
|
|
2034
|
+
* grant names no machine and no peer id.
|
|
2035
|
+
*/
|
|
2036
|
+
export interface OwnerGrantRow extends OwnerGrantSignedFields {
|
|
2037
|
+
/** The owner that signed the row (`IssuerKey`, base64url ed25519); a reader checks it against its anchor. */
|
|
2038
|
+
issuerKey: string;
|
|
2039
|
+
/** That owner's `'add'` signature over the row (`IssuerSig`, base64url). */
|
|
2040
|
+
issuerSig: string;
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
/**
|
|
2044
|
+
* One `CadreControl.OwnerGrantUsage` row: a redemption of an {@link OwnerGrantRow}, as
|
|
2045
|
+
* `ControlDatabase.queryOwnerGrantUsages` reads it. Both signatures are stored so any reader
|
|
2046
|
+
* can re-verify the chain grant → usage → `OwnerKey` row (`verifyOwnerGrantAdmission`).
|
|
2047
|
+
*/
|
|
2048
|
+
export interface OwnerGrantUsageRow {
|
|
2049
|
+
/** The redemption's single-use nonce (the row key), signed into both signatures. */
|
|
2050
|
+
usageStampId: string;
|
|
2051
|
+
/** The `OwnerGrant.Key` redeemed. */
|
|
2052
|
+
grantKey: string;
|
|
2053
|
+
/** The owner key seated (base64url ed25519): the holder's, fresh or already held. */
|
|
2054
|
+
seatedKey: string;
|
|
2055
|
+
/** The `OwnerKey.StampId` this redemption seated. */
|
|
2056
|
+
seatedStampId: string;
|
|
2057
|
+
/** The grant private key's signature over the `'redeem'` digest, base64url. */
|
|
2058
|
+
grantSig: string;
|
|
2059
|
+
/** The seated key's signature over the `'consent'` digest, base64url. */
|
|
2060
|
+
ownerSig: string;
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
/**
|
|
2064
|
+
* The usage and grant rows a grant-seated `OwnerKey` row is verified through, keyed by
|
|
2065
|
+
* `UsageStampId` and `OwnerGrant.Key` (`verifyOwnerGrantAdmission`, from `deriveOwnerAnchor`).
|
|
2066
|
+
* The grant twin of {@link InvitationChain}, loaded beside it by `CadreNode.syncOwnerAnchor`
|
|
2067
|
+
* when some owner row is consent-seated; a row's `vouchUsage` is looked up in this chain
|
|
2068
|
+
* first and in the invitation chain otherwise.
|
|
2069
|
+
*/
|
|
2070
|
+
export interface OwnerGrantChain {
|
|
2071
|
+
usages: Map<string, OwnerGrantUsageRow>;
|
|
2072
|
+
grants: Map<string, OwnerGrantRow>;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
/**
|
|
2076
|
+
* One machine of the cadre as `CadreNode.listMachines` reports it: a live `CadrePeer` row. An
|
|
2077
|
+
* owner key is not a machine; `CadreNode.listOwnerKeys` lists those.
|
|
1996
2078
|
*
|
|
1997
2079
|
* `profile` and `lastPublishedAt` are the machine's own claim only when the row's
|
|
1998
2080
|
* self-signature verifies; both are null otherwise, so an owner re-vouch that bumped
|
|
@@ -2001,58 +2083,108 @@ export interface InvitationChain {
|
|
|
2001
2083
|
*/
|
|
2002
2084
|
export interface CadreMachine {
|
|
2003
2085
|
peerId: string;
|
|
2004
|
-
/** ed25519
|
|
2086
|
+
/** The machine's ed25519 identity key (base64url) behind `peerId`; null when the id is not ed25519. Never an owner key (`listOwnerKeys` lists those). */
|
|
2005
2087
|
publicKey: string | null;
|
|
2006
2088
|
/** This node itself. */
|
|
2007
2089
|
isSelf: boolean;
|
|
2008
|
-
/** `publicKey` is a live `OwnerKey` here. */
|
|
2009
|
-
isOwner: boolean;
|
|
2010
|
-
/** Has a live `CadrePeer` row; false for an owner key with no machine row. */
|
|
2011
|
-
isMember: boolean;
|
|
2012
2090
|
/** Passes this node's authorized-membership predicate now (`CadreNode.listAuthorizedMembers`; always false for self, which that set excludes). */
|
|
2013
2091
|
trusted: boolean;
|
|
2014
2092
|
/** The machine's self-published node profile; null until it publishes, or when its signature does not verify. */
|
|
2015
2093
|
profile: NodeProfile | null;
|
|
2016
2094
|
/** `UpdatedAt` of its self-signed record, re-stamped while it runs; null on the same terms as `profile`. */
|
|
2017
2095
|
lastPublishedAt: number | null;
|
|
2018
|
-
/** `CadrePeer.VouchOwner
|
|
2096
|
+
/** `CadrePeer.VouchOwner`: the owner key that vouched it, or the issuer of the invitation that admitted it. */
|
|
2019
2097
|
vouchedBy: string | null;
|
|
2020
2098
|
}
|
|
2021
2099
|
|
|
2100
|
+
/** One live owner key as `CadreNode.listOwnerKeys` lists it, for an app's owner-key screen. */
|
|
2101
|
+
export interface CadreOwnerKey {
|
|
2102
|
+
/** ed25519 public key (base64url). */
|
|
2103
|
+
key: string;
|
|
2104
|
+
/** The user's name for the key ("phone", "paper backup"); null when none was given. */
|
|
2105
|
+
label: string | null;
|
|
2106
|
+
/** `OwnerKey.VouchOwner`: the owner that signed its add, or that issued the owner grant that seated it; null on the founding key. */
|
|
2107
|
+
vouchedBy: string | null;
|
|
2108
|
+
/** This node's owner signer holds it. */
|
|
2109
|
+
heldHere: boolean;
|
|
2110
|
+
/** In this node's trusted-owner anchor, so this node accepts what it signs. */
|
|
2111
|
+
trusted: boolean;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/** Why `CadreNode.addOwner` refuses by name (`OwnerKeyAddRefusedError.code`). */
|
|
2115
|
+
export type OwnerKeyAddRefusal =
|
|
2116
|
+
/** No control connection while the party has other members: the row would stay on this node, and nothing re-issues an `OwnerKey` add. */
|
|
2117
|
+
| 'alone';
|
|
2118
|
+
|
|
2022
2119
|
/** Why `CadreNode.removeMachine` refuses by name (`MachineRemovalRefusedError.code`). */
|
|
2023
2120
|
export type MachineRemovalRefusal =
|
|
2024
2121
|
/** This node holds no enrolled owner key, so it cannot sign the removal. */
|
|
2025
2122
|
| 'not-an-owner'
|
|
2026
|
-
/** The machine is this node:
|
|
2027
|
-
| 'self'
|
|
2028
|
-
/** The machine holds the only live owner key here (`MinOneOwner`). */
|
|
2029
|
-
| 'last-owner';
|
|
2123
|
+
/** The machine is this node: leaving a cadre is the embedder's flow (stop the node, delete its data), not a removal. */
|
|
2124
|
+
| 'self';
|
|
2030
2125
|
|
|
2031
2126
|
/**
|
|
2032
2127
|
* What `CadreNode.removeMachine` would do for one machine, read without writing
|
|
2033
|
-
* (`CadreNode.planMachineRemoval`), for an app's confirmation step.
|
|
2128
|
+
* (`CadreNode.planMachineRemoval`), for an app's confirmation step. A machine vouches nothing
|
|
2129
|
+
* (a `VouchOwner` is an owner key), so removing one strands no other row.
|
|
2034
2130
|
*/
|
|
2035
2131
|
export interface MachineRemovalPlan {
|
|
2036
2132
|
/** The machine as listed, or null when no live row names it here (already removed). */
|
|
2037
2133
|
machine: CadreMachine | null;
|
|
2038
2134
|
refusal: MachineRemovalRefusal | null;
|
|
2039
|
-
/** The machine's key is a live owner key, so the removal also retires it. */
|
|
2040
|
-
removesOwnerKey: boolean;
|
|
2041
|
-
/** Rows the machine's owner key vouched, which stop passing the membership predicate everywhere once it is removed unless re-vouched first. Empty unless `removesOwnerKey`. */
|
|
2042
|
-
dependents: {
|
|
2043
|
-
/** Live `OwnerKey` rows whose `VouchOwner` is the machine's key, this node's own excluded. */
|
|
2044
|
-
owners: string[];
|
|
2045
|
-
/** Live `CadrePeer` rows whose `VouchOwner` is the machine's key, the machine itself and this node excluded. */
|
|
2046
|
-
peers: string[];
|
|
2047
|
-
};
|
|
2048
2135
|
/** Live `CadreInvite` keys the machine could redeem to come back: targeted at it, or already redeemed by it with uses left. */
|
|
2049
2136
|
invitations: string[];
|
|
2050
|
-
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
/** What `CadreNode.removeMachine` wrote. All false and empty when no live row named the machine here. */
|
|
2140
|
+
export interface MachineRemovalResult {
|
|
2141
|
+
removedPeer: boolean;
|
|
2142
|
+
removedDeviceToken: boolean;
|
|
2143
|
+
/** `CadreInvite` keys whose withdrawal tombstone this call filed. */
|
|
2144
|
+
withdrawnInvitations: string[];
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
/** Why `CadreNode.removeOwner` refuses by name (`OwnerKeyRemovalRefusedError.code`). */
|
|
2148
|
+
export type OwnerKeyRemovalRefusal =
|
|
2149
|
+
/** This node holds no enrolled owner key, so it cannot sign the removal. */
|
|
2150
|
+
| 'not-an-owner'
|
|
2151
|
+
/** No live `OwnerKey` row names the key here (never an owner, or already removed). */
|
|
2152
|
+
| 'unknown'
|
|
2153
|
+
/** The key is the only live owner key (`MinOneOwner`); no owner can remove it. */
|
|
2154
|
+
| 'last-owner'
|
|
2155
|
+
/** The key is this node's own owner key: an owner cannot sign its own row's removal (`A.Key <> old.Key`), so ask another owner key. */
|
|
2156
|
+
| 'self'
|
|
2157
|
+
/** A re-vouch of an `OwnerKey` row was asked for while this node has no control connection and the party has other members: the re-added row has no re-issue path. Decided at call time, so never planned. */
|
|
2158
|
+
| 'alone';
|
|
2159
|
+
|
|
2160
|
+
/** The rows sharing the owner keys' voucher column that a removed owner key strands unless re-vouched first. */
|
|
2161
|
+
export interface OwnerKeyDependents {
|
|
2162
|
+
/** Live `OwnerKey` rows whose `VouchOwner` is the key, this node's own excluded. */
|
|
2163
|
+
owners: string[];
|
|
2164
|
+
/** Live `CadrePeer` rows (peer ids) whose `VouchOwner` is the key, this node's own excluded. */
|
|
2165
|
+
peers: string[];
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
/**
|
|
2169
|
+
* What `CadreNode.removeOwner` would do for one owner key, read without writing
|
|
2170
|
+
* (`CadreNode.planOwnerKeyRemoval`), for an app's confirmation step.
|
|
2171
|
+
*/
|
|
2172
|
+
export interface OwnerKeyRemovalPlan {
|
|
2173
|
+
/** The key as `CadreNode.listOwnerKeys` lists it, or null when no live row names it here. */
|
|
2174
|
+
ownerKey: CadreOwnerKey | null;
|
|
2175
|
+
refusal: Exclude<OwnerKeyRemovalRefusal, 'alone'> | null;
|
|
2176
|
+
/** Rows the key vouched, which stop passing the membership predicate on every machine once it is removed unless re-vouched first. */
|
|
2177
|
+
dependents: OwnerKeyDependents;
|
|
2178
|
+
/** This node's own `CadrePeer` row was vouched by the key, so `removeOwner` re-vouches it under this node's key first, unasked: left on the removed key, every other machine would drop this node. */
|
|
2179
|
+
revouchesOwnRow: boolean;
|
|
2180
|
+
/** This node's own `OwnerKey` row was vouched by the key. It cannot re-vouch that row (the re-add's delete would be its own removal); it keeps its place in every anchor that already derived it, and another owner can re-vouch it afterwards. */
|
|
2051
2181
|
ownDependency: boolean;
|
|
2182
|
+
/** Live owner grants the key issued, which stop being redeemable once it is removed (`OwnerGrantUsage.Authorized` wants a live issuer): an app says "the backup made with this key stops working". Withdrawn, expired and spent grants are not listed. */
|
|
2183
|
+
grants: OwnerGrantRow[];
|
|
2052
2184
|
}
|
|
2053
2185
|
|
|
2054
|
-
/** Options for `CadreNode.
|
|
2055
|
-
export interface
|
|
2186
|
+
/** Options for `CadreNode.removeOwner`. */
|
|
2187
|
+
export interface RemoveOwnerOptions {
|
|
2056
2188
|
/** Dependents to re-vouch under this node's key before the removal; each must appear in the plan's `dependents`. */
|
|
2057
2189
|
revouch?: {
|
|
2058
2190
|
owners?: readonly string[];
|
|
@@ -2060,18 +2192,12 @@ export interface RemoveMachineOptions {
|
|
|
2060
2192
|
};
|
|
2061
2193
|
}
|
|
2062
2194
|
|
|
2063
|
-
/** What `CadreNode.
|
|
2064
|
-
export interface
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
withdrawnInvitations: string[];
|
|
2070
|
-
/** Dependents re-vouched under this node's key before the removal. */
|
|
2071
|
-
revouched: {
|
|
2072
|
-
owners: string[];
|
|
2073
|
-
peers: string[];
|
|
2074
|
-
};
|
|
2195
|
+
/** What `CadreNode.removeOwner` wrote. */
|
|
2196
|
+
export interface OwnerKeyRemovalResult {
|
|
2197
|
+
/** The `OwnerKey` row and its tombstone were written; false only when another owner's removal reached this node between the plan and the write. */
|
|
2198
|
+
removed: boolean;
|
|
2199
|
+
/** Rows re-vouched under this node's key before the removal: the dependents asked for, and this node's own row when the plan's `revouchesOwnRow`. */
|
|
2200
|
+
revouched: OwnerKeyDependents;
|
|
2075
2201
|
}
|
|
2076
2202
|
|
|
2077
2203
|
/**
|
|
@@ -2105,14 +2231,36 @@ export interface CadreInviteStatus {
|
|
|
2105
2231
|
|
|
2106
2232
|
/**
|
|
2107
2233
|
* What `ControlDatabase.redeemCadreInvite` did. `alreadyMember` is the idempotent
|
|
2108
|
-
* retry after a dropped reply: the device's row
|
|
2109
|
-
*
|
|
2110
|
-
* no seat was spent. The stamps are the live rows' either way.
|
|
2234
|
+
* retry after a dropped reply: the device's row was already present, so nothing was
|
|
2235
|
+
* written and no seat was spent. The stamp is the live row's either way.
|
|
2111
2236
|
*/
|
|
2112
2237
|
export interface CadreInviteRedemptionResult {
|
|
2113
2238
|
alreadyMember: boolean;
|
|
2114
2239
|
peerStampId: string;
|
|
2115
|
-
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
/**
|
|
2243
|
+
* One {@link OwnerGrantRow} with its standing, as `ControlDatabase.listOwnerGrantStatuses`
|
|
2244
|
+
* reports it. `live` is the redemption's own test: not withdrawn, unexpired, uses left,
|
|
2245
|
+
* issuer still an owner here.
|
|
2246
|
+
*/
|
|
2247
|
+
export interface OwnerGrantStatus {
|
|
2248
|
+
grant: OwnerGrantRow;
|
|
2249
|
+
live: boolean;
|
|
2250
|
+
withdrawn: boolean;
|
|
2251
|
+
/** Redemptions this node holds for it (`OwnerGrantUsage` rows). */
|
|
2252
|
+
usesRecorded: number;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
/**
|
|
2256
|
+
* What `ControlDatabase.redeemOwnerGrant` did. `alreadyOwner` is the idempotent retry after
|
|
2257
|
+
* a dropped reply, and the case of a holder seating a key that is already an owner: the
|
|
2258
|
+
* key's live `OwnerKey` row was already present, so nothing was written and no use was
|
|
2259
|
+
* spent. `seatedStampId` is the live row's either way.
|
|
2260
|
+
*/
|
|
2261
|
+
export interface OwnerGrantRedemptionResult {
|
|
2262
|
+
alreadyOwner: boolean;
|
|
2263
|
+
seatedStampId: string;
|
|
2116
2264
|
}
|
|
2117
2265
|
|
|
2118
2266
|
/**
|
|
@@ -2329,7 +2477,7 @@ export interface ApnsCredentials {
|
|
|
2329
2477
|
// ============================================================================
|
|
2330
2478
|
|
|
2331
2479
|
/**
|
|
2332
|
-
* A peer entry in a control network seed.
|
|
2480
|
+
* A peer entry in a control network seed, or in a cadre invitation redemption reply.
|
|
2333
2481
|
* Contains connection information for a cadre peer.
|
|
2334
2482
|
*/
|
|
2335
2483
|
export interface SeedPeer {
|
|
@@ -2337,10 +2485,12 @@ export interface SeedPeer {
|
|
|
2337
2485
|
peerId: string;
|
|
2338
2486
|
/** Multiaddrs for connecting to this peer */
|
|
2339
2487
|
multiaddrs: string[];
|
|
2340
|
-
/**
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2488
|
+
/**
|
|
2489
|
+
* Dial this peer first: the machine that minted the seed (or answered the redemption) and
|
|
2490
|
+
* every always-on machine (`CadrePeer.Profile = 'storage'`). A dial hint only — it grants
|
|
2491
|
+
* nothing, and says nothing about owner keys (`projectSeedPeers`).
|
|
2492
|
+
*/
|
|
2493
|
+
preferred: boolean;
|
|
2344
2494
|
}
|
|
2345
2495
|
|
|
2346
2496
|
/**
|
|
@@ -2553,15 +2703,15 @@ export interface ApplySeedResult {
|
|
|
2553
2703
|
/** Machine-readable refusal cause, when the refusing trust policy supplied one. */
|
|
2554
2704
|
code?: SeedRefusalCode;
|
|
2555
2705
|
/**
|
|
2556
|
-
*
|
|
2557
|
-
* carried no
|
|
2706
|
+
* Preferred seed peers (`SeedPeer.preferred`) this apply attempted to dial. Zero when the
|
|
2707
|
+
* seed carried no preferred peer with an address, or when the seed was rejected before
|
|
2558
2708
|
* the dial loop ran.
|
|
2559
2709
|
*/
|
|
2560
|
-
|
|
2710
|
+
preferredDialsAttempted: number;
|
|
2561
2711
|
/**
|
|
2562
|
-
* How many of those dials threw. `
|
|
2563
|
-
* ===
|
|
2564
|
-
* accepted (`success: true`) but no
|
|
2712
|
+
* How many of those dials threw. `preferredDialsAttempted > 0 && preferredDialsFailed
|
|
2713
|
+
* === preferredDialsAttempted` means "seeded but stranded": the seed itself was
|
|
2714
|
+
* accepted (`success: true`) but no preferred peer could be reached, so this node has
|
|
2565
2715
|
* no connection to bootstrap its control database from. The node retries those
|
|
2566
2716
|
* addresses on every control-cohort reconcile pass (see
|
|
2567
2717
|
* `CadreNode.dialColdStartBootstrap`), so this is a signal, not a fatal error.
|
|
@@ -2573,7 +2723,7 @@ export interface ApplySeedResult {
|
|
|
2573
2723
|
* down. Treat a non-zero value as certain failure and zero as "no failure
|
|
2574
2724
|
* observed".
|
|
2575
2725
|
*/
|
|
2576
|
-
|
|
2726
|
+
preferredDialsFailed: number;
|
|
2577
2727
|
}
|
|
2578
2728
|
|
|
2579
2729
|
// ============================================================================
|
|
@@ -2587,18 +2737,13 @@ export type NodeTopology = 'public' | 'nat';
|
|
|
2587
2737
|
|
|
2588
2738
|
/**
|
|
2589
2739
|
* What an owner asks `CadreNode.createCadreInvitation` for. The invitation is a keypair the
|
|
2590
|
-
* node mints; whoever holds the returned bundle can redeem it at any member machine.
|
|
2740
|
+
* node mints; whoever holds the returned bundle can redeem it at any member machine. It admits
|
|
2741
|
+
* a machine and grants nothing else; ownership is an owner grant (`CreateOwnerGrantOptions`).
|
|
2591
2742
|
*/
|
|
2592
2743
|
export interface CreateCadreInvitationOptions {
|
|
2593
2744
|
/** The one device that may redeem it; omit for whoever redeems first. */
|
|
2594
2745
|
peerId?: string;
|
|
2595
|
-
/**
|
|
2596
|
-
grantsOwner: boolean;
|
|
2597
|
-
/**
|
|
2598
|
-
* Lifetime from now, in ms. Defaults to 15 minutes for an untargeted owner-granting
|
|
2599
|
-
* invitation — a bearer credential for admin rights — and 24 hours otherwise. A negative
|
|
2600
|
-
* value mints an already-expired invitation (tests).
|
|
2601
|
-
*/
|
|
2746
|
+
/** Lifetime from now, in ms; default 24 hours. A negative value mints an already-expired invitation (tests). */
|
|
2602
2747
|
expiresInMs?: number;
|
|
2603
2748
|
/** How many redemptions it allows; default 1. */
|
|
2604
2749
|
uses?: number;
|
|
@@ -2653,19 +2798,75 @@ export type CadreJoinProgress =
|
|
|
2653
2798
|
* least one member answered with a retryable refusal (issuer-unknown, busy, conflict, internal).
|
|
2654
2799
|
*/
|
|
2655
2800
|
reason: 'no-member-answered' | 'member-not-ready';
|
|
2656
|
-
outcomes: readonly
|
|
2801
|
+
outcomes: readonly RedemptionAddressOutcome[];
|
|
2657
2802
|
};
|
|
2658
2803
|
|
|
2659
2804
|
/** What `CadreNode.redeemCadreInvitation` returns once a member accepted. */
|
|
2660
2805
|
export interface RedeemCadreInvitationResult {
|
|
2661
2806
|
/** The member machine that admitted this device, when its address named one. */
|
|
2662
2807
|
peerId: string | null;
|
|
2663
|
-
/** Whether the invitation also seated this device's key as an owner. */
|
|
2664
|
-
grantsOwner: boolean;
|
|
2665
2808
|
/** When the member accepted, ISO 8601. */
|
|
2666
2809
|
redeemedAt: string;
|
|
2667
2810
|
}
|
|
2668
2811
|
|
|
2812
|
+
/**
|
|
2813
|
+
* What an owner asks `CadreNode.createOwnerGrant` for. The grant is a keypair the node mints;
|
|
2814
|
+
* whoever holds the returned bundle can become an owner of this cadre through any member
|
|
2815
|
+
* machine, so it is a bearer credential for admin rights.
|
|
2816
|
+
*/
|
|
2817
|
+
export interface CreateOwnerGrantOptions {
|
|
2818
|
+
/** The label every key the grant seats will carry; trimmed, at most 64 characters, blank meaning none. */
|
|
2819
|
+
label?: string;
|
|
2820
|
+
/**
|
|
2821
|
+
* Lifetime from now, in ms; default 15 minutes. `null` means NO expiry and must be passed
|
|
2822
|
+
* explicitly: a backup grant, kept as carefully as an owner key. A negative value mints an
|
|
2823
|
+
* already-expired grant (tests).
|
|
2824
|
+
*/
|
|
2825
|
+
expiresInMs?: number | null;
|
|
2826
|
+
/** How many redemptions it allows; default 1. */
|
|
2827
|
+
uses?: number;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
/** What `CadreNode.createOwnerGrant` returns: the bundle, the same encoded for sharing, and how far it reaches. */
|
|
2831
|
+
export interface CreateOwnerGrantResult {
|
|
2832
|
+
grant: OwnerGrantBundle;
|
|
2833
|
+
/** `encodeOwnerGrant(grant)`: `sereus-owner-grant:1.` and base64url JSON, for a QR code, a paste or a file. */
|
|
2834
|
+
encoded: string;
|
|
2835
|
+
/** Whether a holder could redeem it once the minting machine is gone; see {@link CadreInvitationReach}. */
|
|
2836
|
+
reach: CadreInvitationReach;
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
/** How `CadreNode.redeemOwnerGrant` and `joinWithOwnerGrant` dial the grant's members: the invitation's options, with the same meanings. */
|
|
2840
|
+
export type RedeemOwnerGrantOptions = RedeemCadreInvitationOptions;
|
|
2841
|
+
|
|
2842
|
+
/** What `CadreNode.redeemOwnerGrant` returns once the key is seated. */
|
|
2843
|
+
export interface RedeemOwnerGrantResult {
|
|
2844
|
+
/** The key seated as an owner: the signer's public key. */
|
|
2845
|
+
ownerKey: string;
|
|
2846
|
+
/** The key was already a live owner, so nothing was written and no use of the grant was spent. */
|
|
2847
|
+
alreadyOwner: boolean;
|
|
2848
|
+
/** The member machine that wrote the row, when the redemption went over the protocol and its address named one; null on the local path. */
|
|
2849
|
+
memberPeerId: string | null;
|
|
2850
|
+
}
|
|
2851
|
+
|
|
2852
|
+
/** What `CadreNode.joinWithOwnerGrant` returns once this node is a member and its key an owner. */
|
|
2853
|
+
export interface JoinWithOwnerGrantResult {
|
|
2854
|
+
/** The member machine that admitted this node, when its address named one. */
|
|
2855
|
+
peerId: string | null;
|
|
2856
|
+
/** When the member admitted this node, ISO 8601. */
|
|
2857
|
+
redeemedAt: string;
|
|
2858
|
+
/** The key seated as an owner: the signer's public key. */
|
|
2859
|
+
ownerKey: string;
|
|
2860
|
+
/** The key was already a live owner of the party, so the grant spent no use. */
|
|
2861
|
+
alreadyOwner: boolean;
|
|
2862
|
+
/**
|
|
2863
|
+
* The signer was wired as this node's owner signer, because its `OwnerKey` row reached this
|
|
2864
|
+
* node within the bound. False when the row had not synced in time: the node is a member and
|
|
2865
|
+
* the key an owner all the same, and `CadreNode.wireOwnKeyIfOwner(signer)` wires it later.
|
|
2866
|
+
*/
|
|
2867
|
+
ownerWired: boolean;
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2669
2870
|
/**
|
|
2670
2871
|
* Options for adding a drone via provider API.
|
|
2671
2872
|
*/
|