@serfab/cadre-host 0.8.1 → 0.9.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/dist/auth/trust-circle.d.ts +5 -5
- package/dist/auth/trust-circle.js +10 -10
- package/dist/auth/trust-circle.js.map +1 -1
- package/dist/auth/types.d.ts +2 -2
- package/dist/bin/host.js +255 -54
- package/dist/bin/host.js.map +1 -1
- package/dist/donation/donation-service.d.ts +136 -0
- package/dist/donation/donation-service.js +306 -0
- package/dist/donation/donation-service.js.map +1 -0
- package/dist/donation/donation-store.d.ts +42 -0
- package/dist/donation/donation-store.js +141 -0
- package/dist/donation/donation-store.js.map +1 -0
- package/dist/donation/grant-service.d.ts +71 -0
- package/dist/donation/grant-service.js +163 -0
- package/dist/donation/grant-service.js.map +1 -0
- package/dist/donation/grant-store.d.ts +38 -0
- package/dist/donation/grant-store.js +135 -0
- package/dist/donation/grant-store.js.map +1 -0
- package/dist/donation/index.d.ts +18 -0
- package/dist/donation/index.js +16 -0
- package/dist/donation/index.js.map +1 -0
- package/dist/donation/types.d.ts +175 -0
- package/dist/donation/types.js +40 -0
- package/dist/donation/types.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/installer/config.d.ts +26 -0
- package/dist/installer/config.js +13 -0
- package/dist/installer/config.js.map +1 -1
- package/dist/installer/index.d.ts +2 -0
- package/dist/installer/index.js +3 -0
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/wizard.d.ts +4 -0
- package/dist/installer/wizard.js +5 -1
- package/dist/installer/wizard.js.map +1 -1
- package/dist/nat/nat-service.d.ts +5 -5
- package/dist/nat/nat-service.js +9 -9
- package/dist/nat/nat-service.js.map +1 -1
- package/dist/nat/types.d.ts +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +35 -27
- package/dist/orchestrator/host-process-orchestrator.js +79 -53
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/orchestrator/index.d.ts +3 -3
- package/dist/orchestrator/index.js +1 -1
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/state-store.d.ts +5 -5
- package/dist/orchestrator/state-store.js +2 -2
- package/dist/orchestrator/state-store.js.map +1 -1
- package/dist/orchestrator/types.d.ts +8 -8
- package/dist/owner/index.d.ts +11 -0
- package/dist/owner/index.js +11 -0
- package/dist/owner/index.js.map +1 -0
- package/dist/{authority/authority-node-client.d.ts → owner/owner-node-client.d.ts} +32 -14
- package/dist/{authority/authority-node-client.js → owner/owner-node-client.js} +39 -15
- package/dist/owner/owner-node-client.js.map +1 -0
- package/dist/server/error-handler.d.ts +15 -0
- package/dist/server/error-handler.js +41 -0
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/index.d.ts +26 -2
- package/dist/server/index.js +37 -16
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/grants-admin.d.ts +17 -0
- package/dist/server/routes/grants-admin.js +32 -0
- package/dist/server/routes/grants-admin.js.map +1 -0
- package/dist/server/routes/grants.d.ts +28 -0
- package/dist/server/routes/grants.js +163 -0
- package/dist/server/routes/grants.js.map +1 -0
- package/dist/server/routes/nodes.d.ts +5 -4
- package/dist/server/routes/nodes.js +19 -18
- package/dist/server/routes/nodes.js.map +1 -1
- package/dist/server/routes/settings.d.ts +6 -1
- package/dist/server/routes/settings.js +5 -2
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/status.d.ts +8 -4
- package/dist/server/routes/status.js +9 -4
- package/dist/server/routes/status.js.map +1 -1
- package/dist/update/release-key.js +7 -5
- package/dist/update/release-key.js.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/{host-authority.smoke.test.ts → host-owner.smoke.test.ts} +7 -7
- package/src/__tests__/{orchestrator-authority.test.ts → orchestrator-owner.test.ts} +33 -33
- package/src/__tests__/orchestrator-pin-keys.test.ts +153 -0
- package/src/__tests__/orchestrator-push.test.ts +10 -10
- package/src/auth/__tests__/trust-circle-integration.test.ts +11 -11
- package/src/auth/__tests__/trust-circle.test.ts +10 -10
- package/src/auth/trust-circle.ts +10 -10
- package/src/auth/types.ts +2 -2
- package/src/bin/host.ts +273 -53
- package/src/donation/__tests__/donation-service.test.ts +290 -0
- package/src/donation/__tests__/grant-service.test.ts +213 -0
- package/src/donation/__tests__/grant-store.test.ts +113 -0
- package/src/donation/donation-service.ts +392 -0
- package/src/donation/donation-store.ts +164 -0
- package/src/donation/grant-service.ts +200 -0
- package/src/donation/grant-store.ts +152 -0
- package/src/donation/index.ts +49 -0
- package/src/donation/types.ts +220 -0
- package/src/index.ts +37 -5
- package/src/installer/__tests__/config.test.ts +27 -1
- package/src/installer/__tests__/installer.smoke.test.ts +31 -1
- package/src/installer/__tests__/wizard.test.ts +5 -1
- package/src/installer/config.ts +34 -0
- package/src/installer/index.ts +5 -0
- package/src/installer/wizard.ts +12 -1
- package/src/nat/__tests__/nat-service.test.ts +5 -5
- package/src/nat/nat-service.ts +10 -10
- package/src/nat/types.ts +1 -1
- package/src/orchestrator/host-process-orchestrator.ts +88 -60
- package/src/orchestrator/index.ts +3 -3
- package/src/orchestrator/state-store.ts +7 -7
- package/src/orchestrator/types.ts +8 -8
- package/src/{authority/__tests__/authority-node-client.test.ts → owner/__tests__/owner-node-client.test.ts} +45 -17
- package/src/owner/index.ts +12 -0
- package/src/{authority/authority-node-client.ts → owner/owner-node-client.ts} +55 -21
- package/src/server/__tests__/error-handler.test.ts +22 -0
- package/src/server/__tests__/grants-admin-route.test.ts +73 -0
- package/src/server/__tests__/grants-route.test.ts +189 -0
- package/src/server/__tests__/nodes-route.test.ts +25 -25
- package/src/server/__tests__/server.smoke.test.ts +75 -0
- package/src/server/__tests__/settings-route.test.ts +17 -0
- package/src/server/__tests__/status-route.test.ts +21 -0
- package/src/server/error-handler.ts +43 -0
- package/src/server/index.ts +62 -17
- package/src/server/routes/grants-admin.ts +41 -0
- package/src/server/routes/grants.ts +186 -0
- package/src/server/routes/nodes.ts +19 -18
- package/src/server/routes/settings.ts +11 -3
- package/src/server/routes/status.ts +18 -8
- package/src/update/__tests__/release-key.test.ts +16 -3
- package/src/update/release-key.ts +7 -5
- package/dist/authority/authority-node-client.js.map +0 -1
- package/dist/authority/index.d.ts +0 -11
- package/dist/authority/index.js +0 -11
- package/dist/authority/index.js.map +0 -1
- package/src/authority/index.ts +0 -12
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Donation grant-token types for cadre-host.
|
|
3
|
+
*
|
|
4
|
+
* A **grant token** is a high-entropy base64url secret the host admin issues,
|
|
5
|
+
* out-of-band (QR / copy-paste), to one *grantee* — a friend or family member
|
|
6
|
+
* whose cadre authority (their phone) may then ask this host to spawn donated
|
|
7
|
+
* nodes. The grantee presents the token as `Authorization: Bearer <grant-token>`
|
|
8
|
+
* on every donation request (the grantee-facing surface lands in the
|
|
9
|
+
* `2-donation-service` ticket).
|
|
10
|
+
*
|
|
11
|
+
* This module owns the grant's identity, expiry, and per-grantee quota. The
|
|
12
|
+
* *live-node tally* it checks the quota against is owned by the donation
|
|
13
|
+
* service, not by the grant layer — see `GrantValidator.validateForProvision`.
|
|
14
|
+
*
|
|
15
|
+
* **Grant ≠ trust-circle membership.** A trust-circle invite (`auth/`)
|
|
16
|
+
* authorises a device to join *the host's own* cadre. A donation grant
|
|
17
|
+
* authorises an external cadre authority to ask the host to spawn a node that
|
|
18
|
+
* joins *the grantee's* cadre. The two token flows are deliberately separate
|
|
19
|
+
* modules; this one reuses the *shape* of the trust-circle store (atomic
|
|
20
|
+
* write-then-rename JSON, token-keyed rows) but with grant — not invite —
|
|
21
|
+
* semantics: a grant is long-lived and reusable up to a quota, never
|
|
22
|
+
* one-time-redeemed.
|
|
23
|
+
*/
|
|
24
|
+
/** A grant the host admin issued to one grantee (friend/family). */
|
|
25
|
+
export interface Grant {
|
|
26
|
+
/** base64url secret; also the bearer credential. The store key. */
|
|
27
|
+
token: string;
|
|
28
|
+
/** Human label chosen by the admin, e.g. "Alice's cadre". Display-only. */
|
|
29
|
+
label: string;
|
|
30
|
+
/** Max concurrently-live donated nodes this grant may hold. */
|
|
31
|
+
maxNodes: number;
|
|
32
|
+
/** ISO timestamp when the grant was issued. */
|
|
33
|
+
createdAt: string;
|
|
34
|
+
/** ISO expiry; absent = no expiry. */
|
|
35
|
+
expiresAt?: string;
|
|
36
|
+
/** Set when the admin revokes; a revoked grant validates as denied. */
|
|
37
|
+
revokedAt?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Why a presented grant token was denied. */
|
|
40
|
+
export type GrantDenyReason = 'unknown_token' | 'expired' | 'revoked' | 'quota_exceeded';
|
|
41
|
+
/** Result of validating a presented bearer token. */
|
|
42
|
+
export interface GrantValidation {
|
|
43
|
+
ok: boolean;
|
|
44
|
+
/** The matched grant, when the token names one (present even on some denials). */
|
|
45
|
+
grant?: Grant;
|
|
46
|
+
/** Set when `ok` is false. */
|
|
47
|
+
reason?: GrantDenyReason;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The slice `2-donation-service` depends on. Keeps that ticket decoupled from
|
|
51
|
+
* the store implementation: it holds a `GrantValidator`, not a `GrantStore`.
|
|
52
|
+
*
|
|
53
|
+
* Both methods are pure functions of the store state (and, for provision, the
|
|
54
|
+
* caller-supplied count) — they never throw for a bad token, they return a
|
|
55
|
+
* denial. Issuance/revocation (which mutate) live on `GrantService`.
|
|
56
|
+
*/
|
|
57
|
+
export interface GrantValidator {
|
|
58
|
+
/**
|
|
59
|
+
* Validate a presented bearer token for a *new* provision request.
|
|
60
|
+
*
|
|
61
|
+
* `liveNodeCount(token)` is supplied by the donation service — the grant
|
|
62
|
+
* layer owns identity/expiry/revocation; the donation service owns the
|
|
63
|
+
* authoritative live-node tally (it holds the grant→node records). The count
|
|
64
|
+
* is only consulted once identity/expiry/revocation have passed, so an
|
|
65
|
+
* unknown or dead token never invokes it.
|
|
66
|
+
*/
|
|
67
|
+
validateForProvision(token: string, liveNodeCount: (token: string) => number): GrantValidation;
|
|
68
|
+
/**
|
|
69
|
+
* Validate for a non-provisioning op (peer/seed/terminate): identity + not
|
|
70
|
+
* expired/revoked. No quota check.
|
|
71
|
+
*/
|
|
72
|
+
validate(token: string): GrantValidation;
|
|
73
|
+
}
|
|
74
|
+
/** On-disk shape of `grants.json`. */
|
|
75
|
+
export interface GrantFile {
|
|
76
|
+
version: 1;
|
|
77
|
+
/** keyed by token. */
|
|
78
|
+
grants: Record<string, Omit<Grant, 'token'>>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Typed handlers exposed to the loopback management server for the **admin**
|
|
82
|
+
* grant surface (`/grants-admin`). Distinct from the grantee-facing `/grants`
|
|
83
|
+
* provisioning surface (`2-donation-service`): the admin surface is loopback,
|
|
84
|
+
* no bearer — same-machine admin, matching cadre-host's local-UI "no login"
|
|
85
|
+
* posture.
|
|
86
|
+
*
|
|
87
|
+
* Handlers throw a `GrantError` whose `.code` the server maps to an HTTP
|
|
88
|
+
* status (see `server/error-handler.ts`).
|
|
89
|
+
*/
|
|
90
|
+
export interface GrantAdminHandlers {
|
|
91
|
+
postGrant(body: {
|
|
92
|
+
label: string;
|
|
93
|
+
maxNodes?: number;
|
|
94
|
+
ttlMs?: number;
|
|
95
|
+
}): Promise<{
|
|
96
|
+
grant: Grant;
|
|
97
|
+
}>;
|
|
98
|
+
listGrants(): Promise<{
|
|
99
|
+
grants: Grant[];
|
|
100
|
+
}>;
|
|
101
|
+
deleteGrant(token: string): Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Lifecycle of one donated node:
|
|
105
|
+
* provisioning → the child process is being spawned.
|
|
106
|
+
* awaiting_seed → spawned + reachable; waiting for the requester to present
|
|
107
|
+
* its phone-signed seed (`PUT /grants/:id/seed`).
|
|
108
|
+
* seeded → the seed was applied; the node has joined the requester's cadre.
|
|
109
|
+
* error → provisioning failed (orchestrator resources reclaimed).
|
|
110
|
+
* terminated → stopped + removed (kept in the store for audit).
|
|
111
|
+
*
|
|
112
|
+
* A donation is "live" (counts against a grant's `maxNodes` quota) while it is
|
|
113
|
+
* `provisioning`, `awaiting_seed`, or `seeded` — see `DonationStore.liveNodeCount`.
|
|
114
|
+
*/
|
|
115
|
+
export type DonationStatus = 'provisioning' | 'awaiting_seed' | 'seeded' | 'error' | 'terminated';
|
|
116
|
+
/**
|
|
117
|
+
* One donated node, tracked host-side and persisted to `donations.json`.
|
|
118
|
+
*
|
|
119
|
+
* The host contributes capacity only: `partyId` is the REQUESTER's cadre (a
|
|
120
|
+
* foreign party), and `seedToken` gates the node's own `POST /seed` — it is
|
|
121
|
+
* minted host-side, persisted here (so a host restart in the request→seed gap
|
|
122
|
+
* can still present the seed), and NEVER returned to the grantee.
|
|
123
|
+
*/
|
|
124
|
+
export interface Donation {
|
|
125
|
+
/** "grn_<nanoid>" — also the donated node's orchestrator containerId. */
|
|
126
|
+
id: string;
|
|
127
|
+
/** The grant token that authorized this donation (the quota key). */
|
|
128
|
+
grantToken: string;
|
|
129
|
+
/** The REQUESTER's cadre (a foreign party this host merely hosts a node for). */
|
|
130
|
+
partyId: string;
|
|
131
|
+
/** Node profile. Defaults to `storage` so the node participates and is dialable. */
|
|
132
|
+
profile: 'storage' | 'transaction';
|
|
133
|
+
status: DonationStatus;
|
|
134
|
+
/** Orchestrator handle (opaque `pid:token`), set once the child is spawned. */
|
|
135
|
+
dockerId?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Reserved: a donation's live peer identity is read fresh from the node's
|
|
138
|
+
* `/status` on each `getPeer` call and is NOT persisted here — this field is
|
|
139
|
+
* currently never written. Kept for a future cache if `/status` fan-out ever
|
|
140
|
+
* shows up as hot.
|
|
141
|
+
*/
|
|
142
|
+
peerId?: string;
|
|
143
|
+
/** The node's loopback `POST /seed` URL. Host-internal — stripped from the wire view. */
|
|
144
|
+
seedEndpoint?: string;
|
|
145
|
+
/** Host↔node bearer gating `POST /seed`. Persisted; NEVER leaves the host. */
|
|
146
|
+
seedToken?: string;
|
|
147
|
+
createdAt: string;
|
|
148
|
+
updatedAt: string;
|
|
149
|
+
/** Failure detail when `status === 'error'`. */
|
|
150
|
+
error?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Redacted wire shape returned to the grantee: the host-only secrets
|
|
154
|
+
* (`seedToken`) and host-internal loopback URL (`seedEndpoint`) are stripped.
|
|
155
|
+
*/
|
|
156
|
+
export type DonationView = Omit<Donation, 'seedToken' | 'seedEndpoint'>;
|
|
157
|
+
/** On-disk shape of `donations.json`. Keyed by donation id. */
|
|
158
|
+
export interface DonationFile {
|
|
159
|
+
version: 1;
|
|
160
|
+
donations: Record<string, Omit<Donation, 'id'>>;
|
|
161
|
+
}
|
|
162
|
+
/** Error codes thrown by the donation service / grantee-facing routes. */
|
|
163
|
+
export type DonationErrorCode = 'unauthorized' | 'forbidden' | 'quota_exceeded' | 'invalid_request' | 'not_found' | 'invalid_state' | 'seed_failed' | 'peer_unavailable' | 'orchestrator_error' | 'storage_error';
|
|
164
|
+
/** Typed donation error carrying a stable `code` for HTTP mapping. */
|
|
165
|
+
export declare class DonationError extends Error {
|
|
166
|
+
readonly code: DonationErrorCode;
|
|
167
|
+
constructor(code: DonationErrorCode, message: string);
|
|
168
|
+
}
|
|
169
|
+
/** Error codes thrown by GrantStore / GrantService. */
|
|
170
|
+
export type GrantErrorCode = 'not_found' | 'invalid_label' | 'invalid_max_nodes' | 'invalid_ttl' | 'storage_error';
|
|
171
|
+
/** Typed error carrying a stable `code` for HTTP mapping. */
|
|
172
|
+
export declare class GrantError extends Error {
|
|
173
|
+
readonly code: GrantErrorCode;
|
|
174
|
+
constructor(code: GrantErrorCode, message: string);
|
|
175
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Donation grant-token types for cadre-host.
|
|
3
|
+
*
|
|
4
|
+
* A **grant token** is a high-entropy base64url secret the host admin issues,
|
|
5
|
+
* out-of-band (QR / copy-paste), to one *grantee* — a friend or family member
|
|
6
|
+
* whose cadre authority (their phone) may then ask this host to spawn donated
|
|
7
|
+
* nodes. The grantee presents the token as `Authorization: Bearer <grant-token>`
|
|
8
|
+
* on every donation request (the grantee-facing surface lands in the
|
|
9
|
+
* `2-donation-service` ticket).
|
|
10
|
+
*
|
|
11
|
+
* This module owns the grant's identity, expiry, and per-grantee quota. The
|
|
12
|
+
* *live-node tally* it checks the quota against is owned by the donation
|
|
13
|
+
* service, not by the grant layer — see `GrantValidator.validateForProvision`.
|
|
14
|
+
*
|
|
15
|
+
* **Grant ≠ trust-circle membership.** A trust-circle invite (`auth/`)
|
|
16
|
+
* authorises a device to join *the host's own* cadre. A donation grant
|
|
17
|
+
* authorises an external cadre authority to ask the host to spawn a node that
|
|
18
|
+
* joins *the grantee's* cadre. The two token flows are deliberately separate
|
|
19
|
+
* modules; this one reuses the *shape* of the trust-circle store (atomic
|
|
20
|
+
* write-then-rename JSON, token-keyed rows) but with grant — not invite —
|
|
21
|
+
* semantics: a grant is long-lived and reusable up to a quota, never
|
|
22
|
+
* one-time-redeemed.
|
|
23
|
+
*/
|
|
24
|
+
/** Typed donation error carrying a stable `code` for HTTP mapping. */
|
|
25
|
+
export class DonationError extends Error {
|
|
26
|
+
constructor(code, message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'DonationError';
|
|
29
|
+
this.code = code;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Typed error carrying a stable `code` for HTTP mapping. */
|
|
33
|
+
export class GrantError extends Error {
|
|
34
|
+
constructor(code, message) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'GrantError';
|
|
37
|
+
this.code = code;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/donation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAyKH,sEAAsE;AACtE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,IAAuB,EAAE,OAAe;QAClD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAUD,6DAA6D;AAC7D,MAAM,OAAO,UAAW,SAAQ,KAAK;IAGnC,YAAY,IAAoB,EAAE,OAAe;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,12 +18,14 @@
|
|
|
18
18
|
* - cadre-host-local-ui
|
|
19
19
|
*/
|
|
20
20
|
export type { Orchestrator, OrchestratorCreateRequest, OrchestratorCreateResult, OrchestratorStats, ContainerStatus, ContainerResources, } from '@serfab/cadre-provider';
|
|
21
|
-
export { HostProcessOrchestrator,
|
|
22
|
-
export type { HostProcessConfig, PersistedHandle, ManagedNodeInfo, NodeStateListener, NodePorts,
|
|
23
|
-
export {
|
|
24
|
-
export type {
|
|
21
|
+
export { HostProcessOrchestrator, OWNER_CONTAINER_ID } from './orchestrator/index.js';
|
|
22
|
+
export type { HostProcessConfig, PersistedHandle, ManagedNodeInfo, NodeStateListener, NodePorts, OwnerAdminEndpoint, OwnerSpawnConfig, } from './orchestrator/index.js';
|
|
23
|
+
export { OwnerNodeClient, OwnerNodeUnavailableError } from './owner/index.js';
|
|
24
|
+
export type { OwnerNodeClientOptions } from './owner/index.js';
|
|
25
25
|
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
26
26
|
export type { TrustCircleServiceOptions, CadreNodeLike, TrustCircleMember, PendingInvite, TrustCircleFile, TrustCircleSnapshot, TrustCircleHandlers, TrustCircleErrorCode, } from './auth/index.js';
|
|
27
|
+
export { GrantStore, GrantService, createGrantAdminHandlers, GrantError, DEFAULT_MAX_NODES, DonationStore, DonationService, DonationError, } from './donation/index.js';
|
|
28
|
+
export type { Grant, GrantDenyReason, GrantValidation, GrantValidator, GrantFile, GrantAdminHandlers, GrantErrorCode, GrantServiceOptions, Donation, DonationView, DonationStatus, DonationFile, DonationErrorCode, DonationProvisionRequest, DonationSeedResult, DonationPeerInfo, DonationServiceOptions, } from './donation/index.js';
|
|
27
29
|
export { Installer, readHostConfig, updateHostConfig, writeHostConfig } from './installer/index.js';
|
|
28
30
|
export type { InstallOptions, InstallResult, UninstallOptions, InstallerOptions, HostConfigFile, PushSettings, WizardAnswers, WizardDefaults, ServiceHost, ServiceHostContext, ServiceHostStatus, } from './installer/index.js';
|
|
29
31
|
export { resolvePushCredentials, setFcmSecret, setApnsSecret, clearPushSecret, pushAccount, pushStatus, } from './push/index.js';
|
package/dist/index.js
CHANGED
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
* - cadre-host-installer
|
|
18
18
|
* - cadre-host-local-ui
|
|
19
19
|
*/
|
|
20
|
-
export { HostProcessOrchestrator,
|
|
21
|
-
export {
|
|
20
|
+
export { HostProcessOrchestrator, OWNER_CONTAINER_ID } from './orchestrator/index.js';
|
|
21
|
+
export { OwnerNodeClient, OwnerNodeUnavailableError } from './owner/index.js';
|
|
22
22
|
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
23
|
+
/* ──────────────── donation grant tokens ──────────────── */
|
|
24
|
+
export { GrantStore, GrantService, createGrantAdminHandlers, GrantError, DEFAULT_MAX_NODES, DonationStore, DonationService, DonationError, } from './donation/index.js';
|
|
23
25
|
export { Installer, readHostConfig, updateHostConfig, writeHostConfig } from './installer/index.js';
|
|
24
26
|
/* ──────────────── push credentials (FCM/APNs) ──────────────── */
|
|
25
27
|
export { resolvePushCredentials, setFcmSecret, setApnsSecret, clearPushSecret, pushAccount, pushStatus, } from './push/index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,OAAO,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAWtF,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAYzB,6DAA6D;AAE7D,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,qBAAqB,CAAC;AAqB7B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAepG,mEAAmE;AAEnE,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,GACX,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAe3B,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GACd,MAAM,gBAAgB,CAAC;AA+BxB,+DAA+D;AAE/D,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
@@ -16,6 +16,20 @@ export interface UpdatesConfig {
|
|
|
16
16
|
/** Optional override for the manifest URL (env var still wins). */
|
|
17
17
|
manifestUrl?: string;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Whether this host also runs its own personal cadre (the opt-in "founder"
|
|
21
|
+
* persona), on top of the always-on node-donor role.
|
|
22
|
+
*
|
|
23
|
+
* Default (absent or `enabled: false`) is donor-only: `cadre-host start` brings
|
|
24
|
+
* up the donation surface but spawns **no** owner node, so the trust-circle and
|
|
25
|
+
* NAT surfaces stay inactive. Set `enabled: true` (install-time choice) to also
|
|
26
|
+
* spawn the host's own owner node and enable `/auth` + `/nat`. See
|
|
27
|
+
* docs/cadre-host.md § Two roles: donor and founder.
|
|
28
|
+
*/
|
|
29
|
+
export interface OwnCadreConfig {
|
|
30
|
+
/** When true, `start` spawns the host-owned owner node + trust-circle + NAT. */
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
}
|
|
19
33
|
/**
|
|
20
34
|
* Non-secret push (FCM/APNs) settings. The actual private keys (and the FCM
|
|
21
35
|
* service-account / APNs key identifiers) live in the secret store — see
|
|
@@ -55,6 +69,12 @@ export interface HostConfigFile {
|
|
|
55
69
|
installerVersion: string;
|
|
56
70
|
/** Update-flow settings; defaults: { autoApply: false }. */
|
|
57
71
|
updates: UpdatesConfig;
|
|
72
|
+
/**
|
|
73
|
+
* Host-own-cadre (founder persona) opt-in. Optional — absent is treated as
|
|
74
|
+
* `{ enabled: false }` (donor-only). Written by the installer; read via
|
|
75
|
+
* `hostOwnsCadre()`. Not editable through /api/settings (install-time only).
|
|
76
|
+
*/
|
|
77
|
+
ownCadre?: OwnCadreConfig;
|
|
58
78
|
/**
|
|
59
79
|
* Non-secret push settings (bundle id, sandbox/prod toggle, cooldown/debounce).
|
|
60
80
|
* Optional — absent when push is not configured. Private keys never live here;
|
|
@@ -62,6 +82,12 @@ export interface HostConfigFile {
|
|
|
62
82
|
*/
|
|
63
83
|
push?: PushSettings;
|
|
64
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Whether this host runs its own personal cadre (founder persona). Absent
|
|
87
|
+
* `ownCadre` ⇒ donor-only (false). The single source of truth for the
|
|
88
|
+
* founder/donor gate in `bin/host.ts start`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function hostOwnsCadre(cfg: HostConfigFile): boolean;
|
|
65
91
|
export declare function writeHostConfig(filePath: string, cfg: HostConfigFile): void;
|
|
66
92
|
/** Apply a partial patch to the persisted config (read-modify-write). */
|
|
67
93
|
export declare function updateHostConfig(filePath: string, patch: Partial<Omit<HostConfigFile, 'version'>>): HostConfigFile;
|
package/dist/installer/config.js
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
14
|
import { dirname } from 'node:path';
|
|
15
|
+
/**
|
|
16
|
+
* Whether this host runs its own personal cadre (founder persona). Absent
|
|
17
|
+
* `ownCadre` ⇒ donor-only (false). The single source of truth for the
|
|
18
|
+
* founder/donor gate in `bin/host.ts start`.
|
|
19
|
+
*/
|
|
20
|
+
export function hostOwnsCadre(cfg) {
|
|
21
|
+
return cfg.ownCadre?.enabled === true;
|
|
22
|
+
}
|
|
15
23
|
const CURRENT_VERSION = 2;
|
|
16
24
|
export function writeHostConfig(filePath, cfg) {
|
|
17
25
|
if (cfg.version !== CURRENT_VERSION) {
|
|
@@ -108,6 +116,11 @@ function isHostConfigShape(v) {
|
|
|
108
116
|
return false;
|
|
109
117
|
if (updates.manifestUrl !== undefined && typeof updates.manifestUrl !== 'string')
|
|
110
118
|
return false;
|
|
119
|
+
if (o.ownCadre !== undefined) {
|
|
120
|
+
const own = o.ownCadre;
|
|
121
|
+
if (!own || typeof own !== 'object' || typeof own.enabled !== 'boolean')
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
111
124
|
return true;
|
|
112
125
|
}
|
|
113
126
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/installer/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/installer/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,8 @@ export interface InstallOptions {
|
|
|
26
26
|
libp2pPort?: number;
|
|
27
27
|
/** Disable UPnP probing on first run. */
|
|
28
28
|
noUpnp?: boolean;
|
|
29
|
+
/** Also run the host's own personal cadre here (founder persona). Default false. */
|
|
30
|
+
ownCadre?: boolean;
|
|
29
31
|
/** Open browser at end (default true; suppressed by --no-browser or non-TTY). */
|
|
30
32
|
openBrowser?: boolean;
|
|
31
33
|
/** Skip the enrollment-invite step (no QR printed). */
|
package/dist/installer/index.js
CHANGED
|
@@ -56,6 +56,7 @@ export class Installer {
|
|
|
56
56
|
installedAt: new Date().toISOString(),
|
|
57
57
|
installerVersion: this.installerVersion,
|
|
58
58
|
updates: { autoApply: false },
|
|
59
|
+
ownCadre: { enabled: answers.ownCadre },
|
|
59
60
|
};
|
|
60
61
|
const cfgPath = configPath(answers.dataDir);
|
|
61
62
|
writeHostConfig(cfgPath, cfg);
|
|
@@ -129,6 +130,7 @@ export class Installer {
|
|
|
129
130
|
libp2pPort: opts.libp2pPort ?? defaults.libp2pPort,
|
|
130
131
|
upnpEnabled: opts.noUpnp ? false : defaults.upnpEnabled,
|
|
131
132
|
configureDdns: false,
|
|
133
|
+
ownCadre: opts.ownCadre ?? defaults.ownCadre,
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
async resolveAnswers(opts) {
|
|
@@ -146,6 +148,7 @@ export class Installer {
|
|
|
146
148
|
uiPort: opts.uiPort ?? platformDefaults.uiPort,
|
|
147
149
|
libp2pPort: opts.libp2pPort ?? platformDefaults.libp2pPort,
|
|
148
150
|
upnpEnabled: opts.noUpnp ? false : platformDefaults.upnpEnabled,
|
|
151
|
+
ownCadre: opts.ownCadre ?? platformDefaults.ownCadre,
|
|
149
152
|
};
|
|
150
153
|
const wizard = opts.wizard ?? runWizard;
|
|
151
154
|
return await wizard(defaults);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAuB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,GAEf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAA6C,MAAM,yBAAyB,CAAC;AACvG,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,eAAe,EACf,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAIhF,MAAM,GAAG,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ export interface WizardDefaults {
|
|
|
11
11
|
uiPort: number;
|
|
12
12
|
libp2pPort: number;
|
|
13
13
|
upnpEnabled: boolean;
|
|
14
|
+
/** Also run the host's own personal cadre here (founder persona). Default false. */
|
|
15
|
+
ownCadre: boolean;
|
|
14
16
|
}
|
|
15
17
|
export interface WizardAnswers {
|
|
16
18
|
dataDir: string;
|
|
@@ -18,6 +20,8 @@ export interface WizardAnswers {
|
|
|
18
20
|
libp2pPort: number;
|
|
19
21
|
upnpEnabled: boolean;
|
|
20
22
|
configureDdns: boolean;
|
|
23
|
+
/** Also run the host's own personal cadre here (founder persona). */
|
|
24
|
+
ownCadre: boolean;
|
|
21
25
|
}
|
|
22
26
|
export declare const DEFAULT_UI_PORT = 8765;
|
|
23
27
|
export declare const DEFAULT_LIBP2P_PORT = 4001;
|
package/dist/installer/wizard.js
CHANGED
|
@@ -15,6 +15,7 @@ export function defaultsForPlatform(platform) {
|
|
|
15
15
|
uiPort: DEFAULT_UI_PORT,
|
|
16
16
|
libp2pPort: DEFAULT_LIBP2P_PORT,
|
|
17
17
|
upnpEnabled: true,
|
|
18
|
+
ownCadre: false,
|
|
18
19
|
};
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
@@ -27,7 +28,10 @@ export async function runWizardWith(defaults, ask) {
|
|
|
27
28
|
const libp2pPort = parsePort(await ask('Cadre libp2p port', String(defaults.libp2pPort)), defaults.libp2pPort);
|
|
28
29
|
const upnpEnabled = parseBool(await ask('Attempt UPnP port mapping on this network? [Y/n]', defaults.upnpEnabled ? 'Y' : 'n'), defaults.upnpEnabled);
|
|
29
30
|
const configureDdns = parseBool(await ask('Configure DDNS now? [y/N]', 'N'), false);
|
|
30
|
-
|
|
31
|
+
// Founder persona (opt-in). Most installs just donate nodes to friends and
|
|
32
|
+
// answer no — a no leaves cadre-host donor-only (no owner node, no /auth+/nat).
|
|
33
|
+
const ownCadre = parseBool(await ask('Also run your own personal cadre on this machine? (most people just donating nodes to friends say no) [y/N]', defaults.ownCadre ? 'Y' : 'N'), defaults.ownCadre);
|
|
34
|
+
return { dataDir, uiPort, libp2pPort, upnpEnabled, configureDdns, ownCadre };
|
|
31
35
|
}
|
|
32
36
|
/** Production entrypoint — drives the wizard over stdin/stdout. */
|
|
33
37
|
export async function runWizard(defaults) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/installer/wizard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAuC,MAAM,eAAe,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/installer/wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { type SecretsStore } from './secrets/index.js';
|
|
|
8
8
|
* so tests can inject a mock without a real libp2p stack. Mirrors
|
|
9
9
|
* `CadreNodeLike` in `auth/trust-circle.ts`.
|
|
10
10
|
*
|
|
11
|
-
* Both methods are async: in production they round-trip over the
|
|
11
|
+
* Both methods are async: in production they round-trip over the owner
|
|
12
12
|
* node's loopback admin channel (`GET /admin/identity`, `GET /admin/multiaddrs`).
|
|
13
13
|
* Synchronous test mocks can return a value directly (it's awaited).
|
|
14
14
|
*/
|
|
@@ -88,27 +88,27 @@ export declare class NatService {
|
|
|
88
88
|
testReachability(): Promise<NatStatusSnapshot>;
|
|
89
89
|
/**
|
|
90
90
|
* Build the multiaddrs to embed in invites. The peer ID and libp2p
|
|
91
|
-
* fallback addresses are fetched over the
|
|
91
|
+
* fallback addresses are fetched over the owner node's admin channel; a
|
|
92
92
|
* node-unavailable failure surfaces as `NatError('node_unavailable')`.
|
|
93
93
|
*/
|
|
94
94
|
getInviteAddresses(): Promise<string[]>;
|
|
95
95
|
/**
|
|
96
96
|
* Register a listener fired when the invite addresses may have changed
|
|
97
97
|
* (after `start`, `putSettings`, and `testReachability`). `cadre-host start`
|
|
98
|
-
* wires this to `
|
|
98
|
+
* wires this to `OwnerNodeClient.pushInviteAddresses`. Returns an
|
|
99
99
|
* unsubscribe fn.
|
|
100
100
|
*/
|
|
101
101
|
onAddressesChanged(listener: AddressesChangedListener): () => void;
|
|
102
102
|
/**
|
|
103
103
|
* Recompute invite addresses and notify listeners. Best-effort: when the
|
|
104
|
-
*
|
|
104
|
+
* owner node is unreachable (or the build fails), the notification is
|
|
105
105
|
* skipped — the push is retried on the next NAT event.
|
|
106
106
|
*/
|
|
107
107
|
private fireAddressesChanged;
|
|
108
108
|
/** Deliver an address set to every registered listener (errors are logged, not thrown). */
|
|
109
109
|
private notifyAddressListeners;
|
|
110
110
|
/**
|
|
111
|
-
* Initial invite-address push. The
|
|
111
|
+
* Initial invite-address push. The owner node's admin channel is a freshly
|
|
112
112
|
* spawned detached child that may not be bound yet (and may not have a libp2p
|
|
113
113
|
* peer ID yet), so a single attempt races readiness and silently drops the first
|
|
114
114
|
* NAT-resolved address set. Retry on `node_unavailable` until the node accepts it
|
package/dist/nat/nat-service.js
CHANGED
|
@@ -8,7 +8,7 @@ import { DdnsUpdater } from './ddns/updater.js';
|
|
|
8
8
|
import { getProvider, listProviders } from './ddns/index.js';
|
|
9
9
|
import { buildInviteAddresses, } from './address-resolver.js';
|
|
10
10
|
import { createSecretsStore, ddnsAccount } from './secrets/index.js';
|
|
11
|
-
import {
|
|
11
|
+
import { OwnerNodeUnavailableError } from '../owner/owner-node-client.js';
|
|
12
12
|
const log = debug('cadre:host:nat-service');
|
|
13
13
|
/** Sleep helper for the initial-push retry loop; unref'd so it never holds the process open. */
|
|
14
14
|
function sleep(ms) {
|
|
@@ -78,7 +78,7 @@ export class NatService {
|
|
|
78
78
|
});
|
|
79
79
|
await this.ddnsUpdater.start();
|
|
80
80
|
// Initial invite-address push. Retries on `node_unavailable` until the
|
|
81
|
-
// freshly spawned
|
|
81
|
+
// freshly spawned owner node accepts it (bounded; best-effort after).
|
|
82
82
|
await this.pushInitialAddresses();
|
|
83
83
|
}
|
|
84
84
|
/** Release the port mapping and clear timers. Idempotent. */
|
|
@@ -147,7 +147,7 @@ export class NatService {
|
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Build the multiaddrs to embed in invites. The peer ID and libp2p
|
|
150
|
-
* fallback addresses are fetched over the
|
|
150
|
+
* fallback addresses are fetched over the owner node's admin channel; a
|
|
151
151
|
* node-unavailable failure surfaces as `NatError('node_unavailable')`.
|
|
152
152
|
*/
|
|
153
153
|
async getInviteAddresses() {
|
|
@@ -158,8 +158,8 @@ export class NatService {
|
|
|
158
158
|
libp2pAddrs = await this.cadreNode.getMultiaddrs();
|
|
159
159
|
}
|
|
160
160
|
catch (err) {
|
|
161
|
-
if (err instanceof
|
|
162
|
-
throw new NatError('node_unavailable', `
|
|
161
|
+
if (err instanceof OwnerNodeUnavailableError) {
|
|
162
|
+
throw new NatError('node_unavailable', `Owner node unavailable: ${err.message}`);
|
|
163
163
|
}
|
|
164
164
|
throw err;
|
|
165
165
|
}
|
|
@@ -167,7 +167,7 @@ export class NatService {
|
|
|
167
167
|
// an empty peerId. Building addresses now would mint malformed `…/p2p/`
|
|
168
168
|
// suffixes (and push them to the node), so treat it as not-ready.
|
|
169
169
|
if (!peerId) {
|
|
170
|
-
throw new NatError('node_unavailable', '
|
|
170
|
+
throw new NatError('node_unavailable', 'Owner node has no peer ID yet (not ready)');
|
|
171
171
|
}
|
|
172
172
|
const status = this.getStatus();
|
|
173
173
|
const input = {
|
|
@@ -183,7 +183,7 @@ export class NatService {
|
|
|
183
183
|
/**
|
|
184
184
|
* Register a listener fired when the invite addresses may have changed
|
|
185
185
|
* (after `start`, `putSettings`, and `testReachability`). `cadre-host start`
|
|
186
|
-
* wires this to `
|
|
186
|
+
* wires this to `OwnerNodeClient.pushInviteAddresses`. Returns an
|
|
187
187
|
* unsubscribe fn.
|
|
188
188
|
*/
|
|
189
189
|
onAddressesChanged(listener) {
|
|
@@ -192,7 +192,7 @@ export class NatService {
|
|
|
192
192
|
}
|
|
193
193
|
/**
|
|
194
194
|
* Recompute invite addresses and notify listeners. Best-effort: when the
|
|
195
|
-
*
|
|
195
|
+
* owner node is unreachable (or the build fails), the notification is
|
|
196
196
|
* skipped — the push is retried on the next NAT event.
|
|
197
197
|
*/
|
|
198
198
|
async fireAddressesChanged() {
|
|
@@ -220,7 +220,7 @@ export class NatService {
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
/**
|
|
223
|
-
* Initial invite-address push. The
|
|
223
|
+
* Initial invite-address push. The owner node's admin channel is a freshly
|
|
224
224
|
* spawned detached child that may not be bound yet (and may not have a libp2p
|
|
225
225
|
* peer ID yet), so a single attempt races readiness and silently drops the first
|
|
226
226
|
* NAT-resolved address set. Retry on `node_unavailable` until the node accepts it
|