@tinycloud/share-sdk 1.2.0-beta.0 → 1.2.0-beta.2

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.
@@ -0,0 +1,478 @@
1
+ import { CompactUcanAuthorization } from '@tinycloud/share-envelope';
2
+ import { C as CreateOwnerDelegationParams, r as OwnerDelegationReceipt, A as AddressedOwnerRootInput, i as AddressedOwnerRootReceipt, D as DelegatedShareKey, l as AddressedPublishAuthority } from './addressed-publish-CsUS7-SI.cjs';
3
+
4
+ /**
5
+ * The fields of an owner-signed SIWE CACAO that bound its authority. Read
6
+ * from the exact bytes the Node imported; nothing here is taken from the
7
+ * SDK's own echo of the request.
8
+ */
9
+ interface DecodedOwnerRootCacao {
10
+ /** CIDv1 (raw, BLAKE3) of the exact CACAO bytes, as the Node computes it. */
11
+ readonly cid: string;
12
+ readonly issuer: string;
13
+ readonly audience: string;
14
+ readonly issuedAt: string;
15
+ readonly expiresAt?: string;
16
+ readonly notBefore?: string;
17
+ /** Every SIWE resource, in signed order. */
18
+ readonly resources: readonly string[];
19
+ /** The ReCap `att` of the last resource; null-prototype maps. */
20
+ readonly attenuation: Readonly<Record<string, Readonly<Record<string, readonly unknown[]>>>>;
21
+ /** The ReCap `prf` list (parent capabilities); a root has none. */
22
+ readonly reCapProofs: readonly unknown[];
23
+ }
24
+ /** CIDv1 (raw, BLAKE3) of exact CACAO bytes, as the Node computes a delegation CID. */
25
+ declare function ownerRootCacaoCid(bytes: Uint8Array): string;
26
+ /**
27
+ * Decode the exact bytes of an owner-signed SIWE CACAO. Checks size, CBOR
28
+ * strictness, the envelope shape (eip4361 payload, 65-byte eip191 signature)
29
+ * and, when given, that the bytes hash to `expectedCid`.
30
+ *
31
+ * It does not verify the wallet signature: the Node verifies it when it
32
+ * imports the delegation and is the authority on it. This decoder exists so
33
+ * a caller can check what was signed (scope, audience, lifetime) instead of
34
+ * trusting the request it made.
35
+ */
36
+ declare function decodeOwnerRootCacao(bytes: Uint8Array, expectedCid?: string): DecodedOwnerRootCacao;
37
+
38
+ /** KV prefix every share lives under; the root never reaches outside it. */
39
+ declare const SHARE_ROOT_PREFIX = "xyz.tinycloud.share/shares/";
40
+ /** Longest lifetime of a Share (browser device or CLI profile) root. */
41
+ declare const SHARE_ROOT_MAX_LIFETIME_MS: number;
42
+ /** Longest lifetime of an agent root (the OpenKey device-grant cap). */
43
+ declare const AGENT_SHARE_ROOT_MAX_LIFETIME_MS: number;
44
+ /** Product cap on a bearer link or policy root signed under a root. */
45
+ declare const SHARE_ROOT_LINK_MAX_LIFETIME_MS: number;
46
+ /**
47
+ * Signer clock skew tolerated on a signed root's `exp - iat` (only there:
48
+ * `exp - now` stays strict), so an approval is not wasted when the signer
49
+ * sets its own issue time.
50
+ */
51
+ declare const SHARE_ROOT_CLOCK_SKEW_MS: number;
52
+ /** `ensureShareRoot` asks for the cap minus this margin, so a clamping or slow signer stays inside the cap. */
53
+ declare const SHARE_ROOT_REQUEST_MARGIN_MS: number;
54
+ /**
55
+ * NODE-B2 (§9 "Advertised mode"): a Node lists these in the `features` of
56
+ * its public `GET /info` (sdk-core `checkNodeInfo` → `NodeInfo.features`):
57
+ * the capability marker plus exactly one active mode. Read in one place,
58
+ * {@link readPolicyOwnerAuthorityMode}; the Node version is never consulted.
59
+ */
60
+ declare const POLICY_OWNER_AUTHORITY_FEATURES: {
61
+ readonly marker: "policy-owner-authority-v1";
62
+ readonly record: "policy-owner-authority-record";
63
+ readonly enforce: "policy-owner-authority-enforce";
64
+ };
65
+ /** How long a known mode is trusted before the Node is asked again (NODE-B2: at most 5 minutes). */
66
+ declare const POLICY_OWNER_AUTHORITY_PROBE_TTL_MS: number;
67
+ /** `share`: Share/CLI root in `applications`. `agent`: `default` space, bearer only. */
68
+ type ShareRootKind = "share" | "agent";
69
+ /**
70
+ * What the owner signed. `kv`: get + metadata on the share prefix only.
71
+ * `kv+share-decrypt`: also decrypt on the owner's `:share` network, which a
72
+ * policy owner needs; minted only while the Node advertises `enforce` and
73
+ * `shareRootPolicyRoots` is on.
74
+ */
75
+ type ShareRootScope = "kv" | "kv+share-decrypt";
76
+ type ShareRootErrorCode = "invalid-request" | "invalid-key" | "key-cleared" | "lifetime-exceeds-cap" | "expired" | "malformed-root" | "issuer-mismatch" | "audience-mismatch" | "resource-mismatch" | "ability-mismatch" | "expiry-mismatch" | "reroot-same-key" | "link-out-of-scope" | "policy-roots-disabled" | "policy-roots-not-enforced-by-node" | "root-not-policy-capable";
77
+ interface ShareRootErrorDetails {
78
+ /** The delegation CID the Node imported (the receipt's), when the owner already signed. */
79
+ readonly rootCid?: string;
80
+ /** CID of the signed bytes, when it differs from `rootCid`. */
81
+ readonly signedCid?: string;
82
+ /** The imported root may grant more, or longer, than requested: the owner must revoke `rootCid`. */
83
+ readonly mustRevoke?: boolean;
84
+ }
85
+ declare class ShareRootError extends Error {
86
+ readonly code: ShareRootErrorCode;
87
+ readonly rootCid?: string;
88
+ readonly signedCid?: string;
89
+ readonly mustRevoke: boolean;
90
+ constructor(code: ShareRootErrorCode, message: string, details?: ShareRootErrorDetails);
91
+ }
92
+ /** What a signed-in owner session provides: TinyCloudNode / web-sdk `createOwnerDelegation`. */
93
+ interface ShareRootOwnerAuthority {
94
+ /** `did:pkh:eip155:<chain>:<address>` of the owner wallet. */
95
+ readonly ownerDid: string;
96
+ /** Sign one CACAO with exactly `permissions` (one wallet approval) and import it into the Node. */
97
+ createOwnerDelegation(params: CreateOwnerDelegationParams): Promise<OwnerDelegationReceipt>;
98
+ }
99
+ interface ShareRootOptions {
100
+ readonly kind?: ShareRootKind;
101
+ /**
102
+ * Feature flag `shareRootPolicyRoots`, off by default. A root gains `:share`
103
+ * decrypt, and can sign policy roots through {@link ShareRoot.policyRootSigner},
104
+ * only while this is on and the root's Node advertises owner-authority
105
+ * mode `enforce`.
106
+ */
107
+ readonly shareRootPolicyRoots?: boolean;
108
+ /** Defaults to {@link defaultPolicyOwnerModeProbe}. */
109
+ readonly policyOwnerModeProbe?: PolicyOwnerModeProbe;
110
+ readonly now?: () => number;
111
+ }
112
+ /** Persistable root metadata. Holds no key material: the key lives in its own store. */
113
+ interface ShareRootRecord {
114
+ readonly version: 1;
115
+ readonly kind: ShareRootKind;
116
+ readonly scope: ShareRootScope;
117
+ /** The Node the root was created against; its advertised mode gates policy signing. */
118
+ readonly nodeOrigin: string;
119
+ readonly cid: string;
120
+ /** Base64url of the exact owner-signed CACAO bytes. */
121
+ readonly authorization: string;
122
+ readonly spaceId: string;
123
+ readonly ownerDid: string;
124
+ readonly keyDid: string;
125
+ readonly expiresAt: string;
126
+ }
127
+ interface ShareRootLink {
128
+ readonly rootCid: string;
129
+ readonly linkDid: string;
130
+ readonly path: string;
131
+ readonly expiresAt: Date;
132
+ /** Compact UCAN for `POST /delegate`, then the link's bearer token. */
133
+ readonly delegation: CompactUcanAuthorization;
134
+ }
135
+ /**
136
+ * Policy/v3 owner signing for a `kv+share-decrypt` root. Shaped like
137
+ * `AddressedPublishAuthority` without `registerPolicy`. Every call re-checks
138
+ * the whole gate (flag, the Node's advertised mode within the probe TTL, root
139
+ * live, key present), so a signer kept past a mode change stops working.
140
+ */
141
+ interface ShareRootPolicySigner {
142
+ /** The share key DID: the `ownerDid` of the policy roots. */
143
+ readonly ownerDid: string;
144
+ readonly rootCid: string;
145
+ /** Interim rule: no policy root may outlive the share root. */
146
+ readonly notAfter: Date;
147
+ /** Build and sign one proofless policy root; its expiry must be within `notAfter` and 31 days. */
148
+ createOwnerRoot(input: AddressedOwnerRootInput): Promise<AddressedOwnerRootReceipt>;
149
+ /** Sign a 32-byte digest (policy or envelope); nothing else. */
150
+ sign(digest: Uint8Array): Promise<Uint8Array>;
151
+ }
152
+ /**
153
+ * The single adapter over the Node's advertisement. Takes the `features`
154
+ * list of `GET /info` and returns `"enforce"` only for the marker plus the
155
+ * `-enforce` mode and no `-record`; `"record"` for the marker plus
156
+ * `-record` only; `undefined` for anything else (no marker, as on every
157
+ * Node up to 1.21.0, both modes, or a malformed list). Only `"enforce"`
158
+ * enables policy-capable roots.
159
+ */
160
+ declare function readPolicyOwnerAuthorityMode(features: unknown): "enforce" | "record" | undefined;
161
+ /** Per-Node cache of "does this Node enforce owner-authority expiry". */
162
+ interface PolicyOwnerModeProbe {
163
+ /** True only when the Node currently advertises `enforce`. Never throws. */
164
+ isEnforced(nodeOrigin: string): Promise<boolean>;
165
+ /**
166
+ * Record the `features` a sign-in just read from `GET /info`
167
+ * (`NodeInfo.features`), so each sign-in refreshes the answer without a
168
+ * second fetch.
169
+ */
170
+ observe(nodeOrigin: string, features: readonly string[]): void;
171
+ }
172
+ /**
173
+ * Keep each Node's answer in memory for `ttlMs` (default and ceiling 5
174
+ * minutes), then read `GET /info` again, so a Node that stops advertising
175
+ * `enforce` turns the gate off within one TTL. Only `https:` origins (and
176
+ * `http:` on loopback) are probed. A failure, a non-JSON or oversized
177
+ * (64 KiB) answer, or a malformed list counts as not enforcing and is cached
178
+ * for the same TTL.
179
+ */
180
+ declare function createPolicyOwnerModeProbe(options?: {
181
+ readonly fetch?: (input: URL, init: RequestInit) => Promise<Response>;
182
+ readonly ttlMs?: number;
183
+ readonly now?: () => number;
184
+ }): PolicyOwnerModeProbe;
185
+ /** Process-wide default; sign-in code should feed it `NodeInfo.features` through `observe`. */
186
+ declare const defaultPolicyOwnerModeProbe: PolicyOwnerModeProbe;
187
+ /**
188
+ * A wallet-signed, read-only root delegated to one non-extractable share key,
189
+ * so shares outlive the owner's login session (TC-1423 D3, option B').
190
+ *
191
+ * - Scope: `kv/get` + `kv/metadata` on the share prefix. `:share` decrypt is
192
+ * added (scope `kv+share-decrypt`) only when the root is created while
193
+ * `shareRootPolicyRoots` is on and its Node advertises owner-authority mode
194
+ * `enforce`; a `kv` root holds no `:share` decrypt, so its key cannot own a
195
+ * policy over `:share`-encrypted content (the Node answers
196
+ * `policy-owner-not-authorized`). Never put, del, list, `capabilities/read`,
197
+ * `network.create` or `:default`.
198
+ * - Created only through `createOwnerDelegation({ permissions })`; the signed
199
+ * bytes are decoded and checked here.
200
+ * - Lifetime: at most 37 days (`agent`: 30). One key per root.
201
+ * - Key custody: `create` generates the non-extractable key itself and never
202
+ * exposes it; `clear()` drops the only handle. Browser persistence of a
203
+ * share key requires the composer to be on its own origin first (REVIEW-D3
204
+ * V2-2); this package provides none. CLI profiles may keep a key in a 0600
205
+ * file and rebuild with `restore`.
206
+ * - The client flag and `policyRootSigner` gate only this API: whoever holds
207
+ * the key can sign through other APIs. What bounds that is the scope of the
208
+ * root (no decrypt before `enforce`) and the Node.
209
+ */
210
+ declare class ShareRoot {
211
+ #private;
212
+ readonly kind: ShareRootKind;
213
+ readonly scope: ShareRootScope;
214
+ readonly nodeOrigin: string;
215
+ readonly cid: string;
216
+ readonly ownerDid: string;
217
+ readonly spaceId: string;
218
+ readonly keyDid: string;
219
+ readonly issuedAt: Date;
220
+ readonly expiresAt: Date;
221
+ private constructor();
222
+ /**
223
+ * Ask the owner for a new root (one approval) for a fresh share key. The
224
+ * scope is chosen now: `kv+share-decrypt` only for a `share` root with the
225
+ * flag on and `nodeOrigin` advertising `enforce`, otherwise `kv`. All request
226
+ * checks run before anything is signed. If the signed result is rejected,
227
+ * the key is cleared and the error carries the imported `rootCid` (and
228
+ * `mustRevoke` when the root may be wider than requested).
229
+ *
230
+ * `keyFactory` defaults to a fresh non-extractable WebCrypto key that only
231
+ * this root holds. A custom factory must not persist the key before
232
+ * `create` resolves.
233
+ */
234
+ static create(input: {
235
+ readonly owner: ShareRootOwnerAuthority;
236
+ readonly spaceId: string;
237
+ readonly nodeOrigin: string;
238
+ readonly expiresAt: Date;
239
+ readonly keyFactory?: () => Promise<DelegatedShareKey>;
240
+ readonly options?: ShareRootOptions;
241
+ }): Promise<ShareRoot>;
242
+ /** Rebuild a stored root with its key (e.g. a CLI 0600 key file); the signed bytes are checked again. */
243
+ static restore(input: {
244
+ readonly record: ShareRootRecord;
245
+ readonly key: DelegatedShareKey;
246
+ readonly options?: ShareRootOptions;
247
+ }): Promise<ShareRoot>;
248
+ /** The `Authorization` value the Node knows this root by (base64url CACAO). */
249
+ get authorization(): string;
250
+ /** True when the root holds `:share` decrypt and may act as a policy owner (still gated per call). */
251
+ get policyCapable(): boolean;
252
+ toRecord(): ShareRootRecord;
253
+ /** True while the root is live, its key is held, and it lasts at least until `expiresAt`. Revocation is not visible here. */
254
+ covers(expiresAt: Date, now?: number): boolean;
255
+ /**
256
+ * Sign a bearer link: `kv/get` on one exact key under the prefix, to the
257
+ * link's own key, with this root as its only proof. It never outlives the
258
+ * root (the Node refuses that too) or 30 days. Zero approvals.
259
+ */
260
+ signBearerLink(input: {
261
+ readonly linkDid: string;
262
+ readonly path: string;
263
+ readonly expiresAt: Date;
264
+ }): Promise<ShareRootLink>;
265
+ /**
266
+ * The only ShareRoot API that signs Policy/v3 (email/domain) owner material.
267
+ * Needs a `kv+share-decrypt` root, the `shareRootPolicyRoots` flag, a live
268
+ * root and key, and the root's Node advertising `enforce`; the returned
269
+ * signer re-checks all of it on every call. Until then addressed shares use
270
+ * per-share owner grants. Agent roots are bearer-only.
271
+ */
272
+ policyRootSigner(): Promise<ShareRootPolicySigner>;
273
+ /** Drop this root's key handle. It does not revoke the root: only the owner does that. */
274
+ clear(): void;
275
+ }
276
+ /**
277
+ * Re-root only when needed. `purpose: "bearer"` (default) keeps any live root
278
+ * of the same kind, space and Node that covers `expiresAt`. `purpose:
279
+ * "policy"` additionally needs a `kv+share-decrypt` root: it throws unless the
280
+ * flag is on and the Node enforces, and re-roots when the current root is
281
+ * `kv`; it never hands back a `kv` root. A re-root costs one approval, uses a
282
+ * new key and requests the kind's cap minus {@link SHARE_ROOT_REQUEST_MARGIN_MS}.
283
+ *
284
+ * - Links and policies signed under the old root stay valid until their own
285
+ * expiry; keep the old root (and its key) to revoke them (REVIEW-D3 V2-5).
286
+ * - Concurrent calls each re-root (two approvals, and one orphaned root if
287
+ * both write the same store slot): callers serialize, e.g. with a lock.
288
+ * - A revoked root still "covers" here: re-root when `/delegate` answers
289
+ * `delegation-revoked`.
290
+ */
291
+ declare function ensureShareRoot(input: {
292
+ readonly current?: ShareRoot;
293
+ readonly expiresAt: Date;
294
+ readonly purpose?: "bearer" | "policy";
295
+ readonly owner: ShareRootOwnerAuthority;
296
+ readonly spaceId: string;
297
+ readonly nodeOrigin: string;
298
+ readonly keyFactory?: () => Promise<DelegatedShareKey>;
299
+ readonly options?: ShareRootOptions;
300
+ }): Promise<{
301
+ readonly root: ShareRoot;
302
+ readonly rerooted: boolean;
303
+ }>;
304
+
305
+ /**
306
+ * Link signing outside WASM. The SDK's WASM delegation builder signs with a
307
+ * raw session JWK; a share key must never exist as raw bytes in a browser.
308
+ * These helpers build the same compact UCAN the Node accepts and hand only
309
+ * the exact signing input to the key's `sign`, so the key can be a
310
+ * non-extractable WebCrypto Ed25519 handle (browser: kept in IndexedDB;
311
+ * Node/CLI: imported non-extractable from its own 0600 key file).
312
+ */
313
+ type ShareKeySigner = Pick<DelegatedShareKey, "did" | "sign">;
314
+ /**
315
+ * Throw unless `key` is a non-extractable Ed25519 WebCrypto private key whose
316
+ * public half is `key.did`. The binding is checked by signing a fixed probe
317
+ * and verifying it against the DID, so a root is never requested for a key
318
+ * this process cannot actually use.
319
+ */
320
+ declare function assertNonExtractableShareKey(key: DelegatedShareKey): Promise<void>;
321
+ interface ShareKeyDelegationInput {
322
+ readonly key: ShareKeySigner;
323
+ readonly audienceDid: string;
324
+ /** Resource -> ability -> caveats; the caller bounds it (see `ShareRoot.signBearerLink`). */
325
+ readonly attenuation: Readonly<Record<string, Readonly<Record<string, readonly Readonly<Record<string, unknown>>[]>>>>;
326
+ readonly proofs: readonly string[];
327
+ /** Exactly one fact object, as the Node's compact UCAN requires; defaults to `{}`. */
328
+ readonly facts?: readonly [Readonly<Record<string, unknown>>];
329
+ /** Unix seconds. */
330
+ readonly notBefore: number;
331
+ /** Unix seconds. */
332
+ readonly expiresAt: number;
333
+ readonly nonce?: string;
334
+ }
335
+ /**
336
+ * Sign a compact UCAN delegation (JCS header and payload, EdDSA) with a share
337
+ * key. Unlike share-envelope's invocation signer it is not limited to 60 s:
338
+ * lifetime limits belong to the caller. The result is re-verified (signature,
339
+ * issuer binding, canonical JSON) before it is returned.
340
+ */
341
+ declare function signShareKeyDelegation(input: ShareKeyDelegationInput): Promise<CompactUcanAuthorization>;
342
+
343
+ /** `view`: kv get + metadata. `edit`: also kv put. Both on one exact key. */
344
+ type ShareGrantAccess = "view" | "edit";
345
+ /** Persistable grant metadata. Holds no key material. */
346
+ interface ShareGrantRecord {
347
+ readonly version: 1;
348
+ readonly cid: string;
349
+ /** Base64url of the exact owner-signed CACAO bytes. */
350
+ readonly authorization: string;
351
+ readonly spaceId: string;
352
+ readonly ownerDid: string;
353
+ readonly keyDid: string;
354
+ readonly nodeOrigin: string;
355
+ /** The one exact KV key under `xyz.tinycloud.share/shares/`. */
356
+ readonly path: string;
357
+ readonly access: ShareGrantAccess;
358
+ readonly expiresAt: string;
359
+ }
360
+ /**
361
+ * A per-share owner grant (TC-1423 D3, the interim path for addressed shares
362
+ * while the Node does not enforce owner-authority binding).
363
+ *
364
+ * The owner signs one CACAO (one approval per share) to a FRESH per-share
365
+ * key, never the share-root key:
366
+ * - kv `get` + `metadata` (+ `put` for `edit`) on exactly one KV key under
367
+ * the share prefix, in the `applications` space;
368
+ * - `decrypt` on the owner's `:share` network, which a Policy/v3 owner must
369
+ * hold (every v3 policy's capability ceiling includes decrypt on the
370
+ * source's network; without it the Node answers
371
+ * `policy-owner-not-authorized`);
372
+ * - at most 30 days, and exactly the requested expiry.
373
+ * The per-share key then owns that one share's policy: `publishAuthority`
374
+ * signs its two policy roots (bounded by the grant's expiry and exact path)
375
+ * and its 32-byte policy and envelope digests.
376
+ *
377
+ * Revoking the grant (one owner SIWE `POST /revoke` on `cid`) cuts the
378
+ * per-share key's own reads and its decrypt, for this share only. Until the
379
+ * Node binds policy registrations to the owner delegation (NODE-B2), an
380
+ * already-registered policy keeps admitting recipients until its own expiry,
381
+ * which never exceeds the grant's.
382
+ *
383
+ * Key custody: `create` generates a non-extractable key and never exposes
384
+ * it. Keep the grant (in memory, or a CLI 0600 key file via `restore`) until
385
+ * the share expires, to sign `RootRevocation` later. No browser persistence:
386
+ * that needs the composer on its own origin first (REVIEW-D3 V2-2).
387
+ */
388
+ declare class ShareGrant {
389
+ #private;
390
+ readonly cid: string;
391
+ readonly ownerDid: string;
392
+ readonly spaceId: string;
393
+ readonly keyDid: string;
394
+ readonly nodeOrigin: string;
395
+ readonly path: string;
396
+ readonly access: ShareGrantAccess;
397
+ readonly issuedAt: Date;
398
+ readonly expiresAt: Date;
399
+ private constructor();
400
+ /**
401
+ * Ask the owner for one per-share grant (one approval). Path, access,
402
+ * expiry, space and Node origin are checked before the wallet is asked; the
403
+ * signed CACAO is decoded and must match exactly, or the key is cleared and
404
+ * the error carries the imported CID (`mustRevoke` when it may be wider).
405
+ */
406
+ static create(input: {
407
+ readonly owner: ShareRootOwnerAuthority;
408
+ readonly spaceId: string;
409
+ readonly nodeOrigin: string;
410
+ readonly path: string;
411
+ readonly access: ShareGrantAccess;
412
+ readonly expiresAt: Date;
413
+ readonly keyFactory?: () => Promise<DelegatedShareKey>;
414
+ readonly now?: () => number;
415
+ }): Promise<ShareGrant>;
416
+ /** Rebuild a stored grant with its key (e.g. a CLI 0600 key file); the signed bytes are checked again. */
417
+ static restore(input: {
418
+ readonly record: ShareGrantRecord;
419
+ readonly key: DelegatedShareKey;
420
+ readonly now?: () => number;
421
+ }): Promise<ShareGrant>;
422
+ /** The `Authorization` value the Node knows this grant by (base64url CACAO). */
423
+ get authorization(): string;
424
+ /** The exact KV resource this grant covers. */
425
+ get resource(): string;
426
+ toRecord(): ShareGrantRecord;
427
+ /**
428
+ * Policy/v3 owner signing for this one share. Every call checks the key is
429
+ * held and the grant is live. Policy roots must be owned by the per-share
430
+ * key, expire no later than the grant, and name only this grant's exact
431
+ * KV resource (with no action the grant lacks) and decrypt on `:share`.
432
+ */
433
+ policySigner(): ShareRootPolicySigner;
434
+ /** `publishAddressedShare`'s `authority` for this share: the policy signer plus the caller's `registerPolicy`. */
435
+ publishAuthority(registerPolicy: AddressedPublishAuthority["registerPolicy"]): AddressedPublishAuthority;
436
+ /** Drop the per-share key. It does not revoke the grant: only the owner does that. */
437
+ clear(): void;
438
+ }
439
+
440
+ interface ShareNetworkResult {
441
+ /** `urn:tinycloud:encryption:<owner did:pkh>:share`. */
442
+ readonly networkId: string;
443
+ /** Owner wallet approvals this call used: 0 when the network already existed, else 1. */
444
+ readonly approvals: 0 | 1;
445
+ }
446
+ /**
447
+ * The owner's `:share` network URN, `urn:tinycloud:encryption:<owner
448
+ * did:pkh>:share`: where Share sources are encrypted, and the network a
449
+ * per-share grant or a `kv+share-decrypt` root may decrypt. The Node compares
450
+ * the did:pkh address case-insensitively.
451
+ */
452
+ declare function shareNetworkIdFor(ownerDid: string): string;
453
+ type FetchFn = (input: URL, init?: RequestInit) => Promise<Response>;
454
+ /**
455
+ * Make sure the owner's dedicated `:share` encryption network exists (D3
456
+ * addendum §1, review B1). Per owner: `urn:tinycloud:encryption:<owner
457
+ * did:pkh>:share`. The owner owns it, never a share key or per-share key: a
458
+ * network whose owner is the key would be root authority for that key
459
+ * (tinycloud-node `delegation.rs:792-809`), so revoking its grant would not
460
+ * cut decrypt.
461
+ *
462
+ * Idempotent: when the Node already has it, nothing is signed (0 approvals).
463
+ * Otherwise the owner signs one short-lived CACAO (one approval, once per
464
+ * owner) granting only `network.create` on that URN to a throwaway
465
+ * non-extractable key, which creates the network with the owner as
466
+ * `ownerDid` and is then cleared. A 409 from a concurrent creator counts as
467
+ * created. Share sources encrypt to it; vault and secrets stay on `:default`.
468
+ */
469
+ declare function ensureShareNetwork(input: {
470
+ readonly owner: ShareRootOwnerAuthority;
471
+ readonly spaceId: string;
472
+ readonly nodeOrigin: string;
473
+ readonly fetch?: FetchFn;
474
+ readonly keyFactory?: () => Promise<DelegatedShareKey>;
475
+ readonly now?: () => number;
476
+ }): Promise<ShareNetworkResult>;
477
+
478
+ export { AGENT_SHARE_ROOT_MAX_LIFETIME_MS, type DecodedOwnerRootCacao, POLICY_OWNER_AUTHORITY_FEATURES, POLICY_OWNER_AUTHORITY_PROBE_TTL_MS, type PolicyOwnerModeProbe, SHARE_ROOT_CLOCK_SKEW_MS, SHARE_ROOT_LINK_MAX_LIFETIME_MS, SHARE_ROOT_MAX_LIFETIME_MS, SHARE_ROOT_PREFIX, SHARE_ROOT_REQUEST_MARGIN_MS, ShareGrant, type ShareGrantAccess, type ShareGrantRecord, type ShareKeyDelegationInput, type ShareKeySigner, type ShareNetworkResult, ShareRoot, ShareRootError, type ShareRootErrorCode, type ShareRootErrorDetails, type ShareRootKind, type ShareRootLink, type ShareRootOptions, type ShareRootOwnerAuthority, type ShareRootPolicySigner, type ShareRootRecord, type ShareRootScope, assertNonExtractableShareKey, createPolicyOwnerModeProbe, decodeOwnerRootCacao, defaultPolicyOwnerModeProbe, ensureShareNetwork, ensureShareRoot, ownerRootCacaoCid, readPolicyOwnerAuthorityMode, shareNetworkIdFor, signShareKeyDelegation };