@tinycloud/node-sdk 3.3.0-beta.9 → 3.3.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/{TinyCloudNode-CcNh20QX.d.cts → TinyCloudNode-DeV-L_14.d.cts} +123 -46
- package/dist/{TinyCloudNode-CcNh20QX.d.ts → TinyCloudNode-DeV-L_14.d.ts} +123 -46
- package/dist/{authority-Cwotwza3.d.cts → authority-BO2VqGnD.d.cts} +1 -1
- package/dist/{authority-D_u9a7Wl.d.ts → authority-CtsxSAoP.d.ts} +1 -1
- package/dist/core.cjs +178 -93
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +189 -96
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +229 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +240 -100
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +2 -2
- package/dist/replication/authority.d.ts +2 -2
- package/package.json +5 -5
package/dist/core.cjs
CHANGED
|
@@ -517,6 +517,11 @@ var NodeUserAuthorization = class {
|
|
|
517
517
|
this.tinycloudHosts = config.tinycloudHosts;
|
|
518
518
|
this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
|
|
519
519
|
this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
|
|
520
|
+
this.registryPolicy = config.registryPolicy;
|
|
521
|
+
this.newUserHost = config.newUserHost;
|
|
522
|
+
this.registryChainId = config.registryChainId;
|
|
523
|
+
this.registrySequenceStore = config.registrySequenceStore ?? (0, import_sdk_core4.createInMemoryRegistrySequenceStore)();
|
|
524
|
+
this.onNodeNotFound = config.onNodeNotFound;
|
|
520
525
|
this.autoDiscoverLocalNode = config.autoDiscoverLocalNode;
|
|
521
526
|
this.localNodeUrl = config.localNodeUrl;
|
|
522
527
|
this.localLinkName = config.localLinkName;
|
|
@@ -628,6 +633,7 @@ var NodeUserAuthorization = class {
|
|
|
628
633
|
this._nodeFeaturesKnown = nodeFeatures !== void 0;
|
|
629
634
|
this._nodeInfoIdentity = void 0;
|
|
630
635
|
this.tinycloudHosts = hosts && hosts.length > 0 ? [...hosts] : void 0;
|
|
636
|
+
this.registryVerdict = void 0;
|
|
631
637
|
this._lastActivationSkippedSpaceIds = [];
|
|
632
638
|
this._lastActivationActivatedSpaceIds = [];
|
|
633
639
|
if (!session) {
|
|
@@ -678,6 +684,23 @@ var NodeUserAuthorization = class {
|
|
|
678
684
|
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
679
685
|
return;
|
|
680
686
|
}
|
|
687
|
+
if (this.registryPolicy === "fail-closed") {
|
|
688
|
+
const resolved2 = await (0, import_sdk_core4.resolveFailClosedTinyCloudHosts)(address, {
|
|
689
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
690
|
+
registryChainId: this.registryChainId,
|
|
691
|
+
newUserHost: this.newUserHost,
|
|
692
|
+
sequenceStore: this.registrySequenceStore,
|
|
693
|
+
onNodeNotFound: this.onNodeNotFound,
|
|
694
|
+
autoDiscoverLocalNode: this.autoDiscoverLocalNode,
|
|
695
|
+
localNodeUrl: this.localNodeUrl,
|
|
696
|
+
localLinkName: this.localLinkName,
|
|
697
|
+
expectedNodeDid: this.expectedNodeDid,
|
|
698
|
+
localNodeIdentityStore: this.localNodeIdentityStore
|
|
699
|
+
});
|
|
700
|
+
this.tinycloudHosts = resolved2.hosts;
|
|
701
|
+
this.registryVerdict = resolved2.verdict;
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
681
704
|
const subject = (0, import_sdk_core4.pkhDid)(address, chainId);
|
|
682
705
|
const resolved = await (0, import_sdk_core4.resolveTinyCloudHosts)(subject, {
|
|
683
706
|
registryUrl: this.tinycloudRegistryUrl,
|
|
@@ -690,6 +713,32 @@ var NodeUserAuthorization = class {
|
|
|
690
713
|
});
|
|
691
714
|
this.tinycloudHosts = resolved.hosts;
|
|
692
715
|
}
|
|
716
|
+
/**
|
|
717
|
+
* Space-creation guard (TC-1443). Under `registryPolicy: "fail-closed"`,
|
|
718
|
+
* throws unless the owner's registry verdict allows a space on the primary
|
|
719
|
+
* host: `NodeRegistryEntryExistsError` when the owner's record does not
|
|
720
|
+
* list it, `RegistryUnavailableError` when the registry gives no
|
|
721
|
+
* verdict. Reuses this session's sign-in verdict unless it was
|
|
722
|
+
* `unavailable`, else looks it up now (explicit-host apps). Under the
|
|
723
|
+
* default policy it returns at once and performs no lookup.
|
|
724
|
+
*/
|
|
725
|
+
async assertMayCreateSpace() {
|
|
726
|
+
if (this.registryPolicy !== "fail-closed") return;
|
|
727
|
+
if (this._address === void 0) {
|
|
728
|
+
throw new Error("Must be signed in to create a space");
|
|
729
|
+
}
|
|
730
|
+
await this.ensureTinyCloudHosts();
|
|
731
|
+
const subject = (0, import_sdk_core4.registryOwnerSubjectV1)(this._address, this.registryChainId);
|
|
732
|
+
let verdict = this.registryVerdict;
|
|
733
|
+
if (verdict?.subject !== subject || verdict.status === "unavailable") {
|
|
734
|
+
verdict = await (0, import_sdk_core4.lookupOwnerRegistryVerdict)(subject, {
|
|
735
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
736
|
+
sequenceStore: this.registrySequenceStore
|
|
737
|
+
});
|
|
738
|
+
this.registryVerdict = verdict;
|
|
739
|
+
}
|
|
740
|
+
(0, import_sdk_core4.assertSpaceCreationAllowed)(verdict, this.primaryTinyCloudHost);
|
|
741
|
+
}
|
|
693
742
|
requireTinyCloudHosts() {
|
|
694
743
|
if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
|
|
695
744
|
throw new Error("TinyCloud hosts have not been resolved. Call signIn() first.");
|
|
@@ -1138,6 +1187,7 @@ var NodeUserAuthorization = class {
|
|
|
1138
1187
|
if (!handler) {
|
|
1139
1188
|
return;
|
|
1140
1189
|
}
|
|
1190
|
+
await this.guardSpaceCreation(handler, creationContext);
|
|
1141
1191
|
const confirmed = await handler.confirmSpaceCreation(creationContext);
|
|
1142
1192
|
if (!confirmed) {
|
|
1143
1193
|
return;
|
|
@@ -1178,6 +1228,7 @@ var NodeUserAuthorization = class {
|
|
|
1178
1228
|
if (!handler) {
|
|
1179
1229
|
return;
|
|
1180
1230
|
}
|
|
1231
|
+
await this.guardSpaceCreation(handler, creationContext);
|
|
1181
1232
|
const confirmed = await handler.confirmSpaceCreation(creationContext);
|
|
1182
1233
|
if (!confirmed) {
|
|
1183
1234
|
return;
|
|
@@ -1219,6 +1270,16 @@ var NodeUserAuthorization = class {
|
|
|
1219
1270
|
{ cause: result }
|
|
1220
1271
|
);
|
|
1221
1272
|
}
|
|
1273
|
+
/** {@link assertMayCreateSpace}, reporting a refusal to the creation handler before rethrowing it. */
|
|
1274
|
+
async guardSpaceCreation(handler, context) {
|
|
1275
|
+
try {
|
|
1276
|
+
await this.assertMayCreateSpace();
|
|
1277
|
+
} catch (error) {
|
|
1278
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
1279
|
+
handler.onSpaceCreationFailed?.(context, failure);
|
|
1280
|
+
throw failure;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1222
1283
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
1223
1284
|
if (result.success) {
|
|
1224
1285
|
this._lastActivationSkippedSpaceIds = result.skipped ?? [];
|
|
@@ -2219,24 +2280,17 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
2219
2280
|
));
|
|
2220
2281
|
continue;
|
|
2221
2282
|
}
|
|
2222
|
-
const
|
|
2223
|
-
const policyMatch = /^tinycloud:\/\/([^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
|
|
2224
|
-
const match = nativeMatch ?? policyMatch;
|
|
2283
|
+
const match = /^(?:tinycloud:\/\/([^/]+)|(tinycloud:[^/]+))\/(kv|sql|duckdb|hooks)(?:\/|$)(.*)$/.exec(resource);
|
|
2225
2284
|
if (!match) {
|
|
2226
2285
|
throw new Error(
|
|
2227
2286
|
`Validated runtime delegation has an unsupported signed resource '${resource}'.`
|
|
2228
2287
|
);
|
|
2229
2288
|
}
|
|
2230
|
-
const [,
|
|
2289
|
+
const [, policySpace, nativeSpace, shortService, path] = match;
|
|
2231
2290
|
const service = SERVICE_BY_SHORT_NAME[shortService];
|
|
2232
|
-
if (service === void 0) {
|
|
2233
|
-
throw new Error(
|
|
2234
|
-
`Validated runtime delegation has an unsupported signed service '${shortService}'.`
|
|
2235
|
-
);
|
|
2236
|
-
}
|
|
2237
2291
|
permissions.push(...groupedSignedEntries(
|
|
2238
2292
|
service,
|
|
2239
|
-
|
|
2293
|
+
nativeSpace ?? policySpace,
|
|
2240
2294
|
path,
|
|
2241
2295
|
abilities
|
|
2242
2296
|
));
|
|
@@ -3265,6 +3319,12 @@ function describeHostFailure2(result) {
|
|
|
3265
3319
|
const text = result.error?.trim();
|
|
3266
3320
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
3267
3321
|
}
|
|
3322
|
+
function assertDelegationActivated(result, delegation, requireActivation) {
|
|
3323
|
+
const skipped = requireActivation ? (delegation.resources?.map((r) => r.space) ?? [delegation.spaceId]).filter((space) => result.skipped?.includes(space)) : [];
|
|
3324
|
+
if (result.success && skipped.length === 0) return;
|
|
3325
|
+
const detail = result.success ? `the node skipped ${[...new Set(skipped)].join(", ")} (space not hosted on the node)` : describeHostFailure2(result);
|
|
3326
|
+
throw Object.assign(new Error(`Failed to activate delegation with host: ${detail}`), { cause: result });
|
|
3327
|
+
}
|
|
3268
3328
|
function ownerDelegationPermissions(params) {
|
|
3269
3329
|
const hasPermissions = Object.prototype.hasOwnProperty.call(params, "permissions");
|
|
3270
3330
|
const hasLegacy = Object.prototype.hasOwnProperty.call(params, "path") || Object.prototype.hasOwnProperty.call(params, "actions");
|
|
@@ -3347,7 +3407,7 @@ function ownerPermissionsToAbilities(permissions) {
|
|
|
3347
3407
|
}
|
|
3348
3408
|
return { abilities, rawAbilities };
|
|
3349
3409
|
}
|
|
3350
|
-
var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation";
|
|
3410
|
+
var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation to a did:key (not did:pkh); use the session-key DID or drop the flag";
|
|
3351
3411
|
function base64UrlEncode(bytes) {
|
|
3352
3412
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
3353
3413
|
let output = "";
|
|
@@ -3661,7 +3721,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3661
3721
|
this.explicitHost = config.host;
|
|
3662
3722
|
this.config = {
|
|
3663
3723
|
...config,
|
|
3664
|
-
host: config.host ?? DEFAULT_HOST
|
|
3724
|
+
host: config.host ?? DEFAULT_HOST,
|
|
3725
|
+
// One store for every authorization this client creates.
|
|
3726
|
+
registrySequenceStore: config.registrySequenceStore ?? (0, import_sdk_core10.createInMemoryRegistrySequenceStore)()
|
|
3665
3727
|
};
|
|
3666
3728
|
if (this.config.replication?.enabled) {
|
|
3667
3729
|
const runtime = getNodeReplicationLoaders().runtime().then(({ ReplicationRuntime }) => {
|
|
@@ -3896,7 +3958,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3896
3958
|
if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
|
|
3897
3959
|
return this.wasmBindings.computeCid(data, codec);
|
|
3898
3960
|
},
|
|
3899
|
-
// delegationManager: undefined - not needed for receive()
|
|
3900
3961
|
createKVService: (config) => {
|
|
3901
3962
|
const prefix = config.pathPrefix?.replace(/\/$/, "");
|
|
3902
3963
|
const kvService = new import_sdk_core10.KVService({ prefix });
|
|
@@ -3904,7 +3965,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3904
3965
|
invoke: config.invoke,
|
|
3905
3966
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
3906
3967
|
hosts: config.hosts,
|
|
3907
|
-
telemetry: this.config.telemetry
|
|
3968
|
+
telemetry: this.config.telemetry,
|
|
3969
|
+
retryPolicy: this.config.retryPolicy
|
|
3908
3970
|
}));
|
|
3909
3971
|
kvContext.setSession(config.session);
|
|
3910
3972
|
kvService.initialize(kvContext);
|
|
@@ -3931,6 +3993,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3931
3993
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
3932
3994
|
tinycloudRegistryUrl: config.tinycloudRegistryUrl,
|
|
3933
3995
|
tinycloudFallbackHosts: config.tinycloudFallbackHosts,
|
|
3996
|
+
...this.registryPolicyConfig(),
|
|
3934
3997
|
autoDiscoverLocalNode: config.autoDiscoverLocalNode,
|
|
3935
3998
|
localNodeUrl: config.localNodeUrl,
|
|
3936
3999
|
localLinkName: config.localLinkName,
|
|
@@ -3954,7 +4017,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3954
4017
|
});
|
|
3955
4018
|
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
3956
4019
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
3957
|
-
telemetry: config.telemetry
|
|
4020
|
+
telemetry: config.telemetry,
|
|
4021
|
+
retryPolicy: config.retryPolicy
|
|
3958
4022
|
});
|
|
3959
4023
|
}
|
|
3960
4024
|
shouldUseBootstrapSignInRequest(config) {
|
|
@@ -4316,7 +4380,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4316
4380
|
this.auth = oldAuth;
|
|
4317
4381
|
this.tc = this.auth ? new import_sdk_core10.TinyCloud(this.auth, {
|
|
4318
4382
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
4319
|
-
telemetry: this.config.telemetry
|
|
4383
|
+
telemetry: this.config.telemetry,
|
|
4384
|
+
retryPolicy: this.config.retryPolicy
|
|
4320
4385
|
}) : null;
|
|
4321
4386
|
this._capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
4322
4387
|
this._keyProvider = new WasmKeyProvider({ sessionManager: this.sessionManager });
|
|
@@ -4636,6 +4701,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4636
4701
|
const primarySession = auth.tinyCloudSession;
|
|
4637
4702
|
const defaultSpaceId = this.ownedSpaceId("default");
|
|
4638
4703
|
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest === import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default;
|
|
4704
|
+
if (steps.some((step) => step.kind === "host")) {
|
|
4705
|
+
await this.assertMayCreateSpace();
|
|
4706
|
+
}
|
|
4639
4707
|
for (const step of steps) {
|
|
4640
4708
|
if (step.kind !== "session") continue;
|
|
4641
4709
|
graph.assertActive();
|
|
@@ -4964,7 +5032,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4964
5032
|
invokeAny: context.invokeAny,
|
|
4965
5033
|
fetch: context.fetch,
|
|
4966
5034
|
hosts: context.hosts,
|
|
4967
|
-
telemetry: this.config.telemetry
|
|
5035
|
+
telemetry: this.config.telemetry,
|
|
5036
|
+
retryPolicy: this.config.retryPolicy
|
|
4968
5037
|
}));
|
|
4969
5038
|
scoped.setOperationAbortSignal(signal);
|
|
4970
5039
|
scoped.setSession({ ...session, spaceId });
|
|
@@ -5011,6 +5080,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5011
5080
|
return;
|
|
5012
5081
|
}
|
|
5013
5082
|
if (!this.currentSessionCoversAccountRegistry()) {
|
|
5083
|
+
if (!_TinyCloudNode.accountRegistrySkipLogged) {
|
|
5084
|
+
_TinyCloudNode.accountRegistrySkipLogged = true;
|
|
5085
|
+
import_sdk_services2.tinyCloudDebugLogger.log("registry.skip");
|
|
5086
|
+
}
|
|
5014
5087
|
return;
|
|
5015
5088
|
}
|
|
5016
5089
|
const controller = new AbortController();
|
|
@@ -5026,7 +5099,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5026
5099
|
invokeAny: sharedContext.invokeAny,
|
|
5027
5100
|
fetch: sharedContext.fetch,
|
|
5028
5101
|
hosts: sharedContext.hosts,
|
|
5029
|
-
telemetry: this.config.telemetry
|
|
5102
|
+
telemetry: this.config.telemetry,
|
|
5103
|
+
retryPolicy: this.config.retryPolicy
|
|
5030
5104
|
}));
|
|
5031
5105
|
context.setOperationAbortSignal(controller.signal);
|
|
5032
5106
|
const current = this.currentTinyCloudSession();
|
|
@@ -5277,6 +5351,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5277
5351
|
{ cause: activation }
|
|
5278
5352
|
);
|
|
5279
5353
|
}
|
|
5354
|
+
await this.assertMayCreateSpace();
|
|
5355
|
+
if (signal?.aborted) throw signal.reason;
|
|
5280
5356
|
const created = await this.hostOwnedSpaceOnce(spaceId, signal);
|
|
5281
5357
|
if (!created.success) {
|
|
5282
5358
|
throw Object.assign(
|
|
@@ -5390,6 +5466,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5390
5466
|
* session's recap doesn't cover it and the registry has no record; the host
|
|
5391
5467
|
* SIWE is idempotent server-side. Must be called after {@link signIn}.
|
|
5392
5468
|
*
|
|
5469
|
+
* Under `registryPolicy: "fail-closed"`, hosting is refused with
|
|
5470
|
+
* `NodeRegistryEntryExistsError` when the owner's registry record does not
|
|
5471
|
+
* list the host, or `RegistryUnavailableError` when the registry gives no
|
|
5472
|
+
* verdict. {@link hostOwnedSpace} itself is an explicit action and is not
|
|
5473
|
+
* guarded.
|
|
5474
|
+
*
|
|
5393
5475
|
* @param name - The owned space name (e.g. `"secrets"`).
|
|
5394
5476
|
* @returns The hosted owned-space URI.
|
|
5395
5477
|
*/
|
|
@@ -5401,8 +5483,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5401
5483
|
if (this.hostedOwnedSpaceIds.has(spaceId) || await this.isOwnedSpaceRegistered(spaceId)) {
|
|
5402
5484
|
return spaceId;
|
|
5403
5485
|
}
|
|
5486
|
+
await this.assertMayCreateSpace();
|
|
5404
5487
|
return this.hostOwnedSpace(name);
|
|
5405
5488
|
}
|
|
5489
|
+
/**
|
|
5490
|
+
* Space-creation guard (TC-1443) for the automatic hosting paths: sign-in's
|
|
5491
|
+
* owned spaces, account bootstrap, {@link ensureOwnedSpaceHosted} and
|
|
5492
|
+
* {@link ensurePublicSpace}. Only `registryPolicy: "fail-closed"` consults
|
|
5493
|
+
* the registry ({@link NodeUserAuthorization.assertMayCreateSpace}); the
|
|
5494
|
+
* default policy performs no lookup.
|
|
5495
|
+
*/
|
|
5496
|
+
async assertMayCreateSpace() {
|
|
5497
|
+
if (this.config.registryPolicy !== "fail-closed") return;
|
|
5498
|
+
await this.auth.assertMayCreateSpace();
|
|
5499
|
+
}
|
|
5500
|
+
/** Registry-policy settings shared by every authorization this client creates. */
|
|
5501
|
+
registryPolicyConfig() {
|
|
5502
|
+
const { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound } = this.config;
|
|
5503
|
+
return { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound };
|
|
5504
|
+
}
|
|
5406
5505
|
/**
|
|
5407
5506
|
* Submit the host delegation for an owned space, sharing one in-flight
|
|
5408
5507
|
* request (and so one approval) between concurrent callers in this session,
|
|
@@ -5843,7 +5942,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5843
5942
|
const graph = this.createServiceGraphLifetime();
|
|
5844
5943
|
const core = this.auth ? new import_sdk_core10.TinyCloud(this.auth, {
|
|
5845
5944
|
invokeAny: graph.invokeAny,
|
|
5846
|
-
telemetry: this.config.telemetry
|
|
5945
|
+
telemetry: this.config.telemetry,
|
|
5946
|
+
retryPolicy: this.config.retryPolicy
|
|
5847
5947
|
}) : null;
|
|
5848
5948
|
if (core) {
|
|
5849
5949
|
core.initializeServices(graph.invoke, [input.host], graph.fetch);
|
|
@@ -5855,7 +5955,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5855
5955
|
invokeAny: graph.invokeAny,
|
|
5856
5956
|
fetch: graph.fetch,
|
|
5857
5957
|
hosts: [input.host],
|
|
5858
|
-
telemetry: this.config.telemetry
|
|
5958
|
+
telemetry: this.config.telemetry,
|
|
5959
|
+
retryPolicy: this.config.retryPolicy
|
|
5859
5960
|
}));
|
|
5860
5961
|
const kv = new import_sdk_core10.KVService({});
|
|
5861
5962
|
kv.initialize(serviceContext);
|
|
@@ -5941,7 +6042,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5941
6042
|
invoke: config.invoke,
|
|
5942
6043
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
5943
6044
|
hosts: config.hosts,
|
|
5944
|
-
telemetry: this.config.telemetry
|
|
6045
|
+
telemetry: this.config.telemetry,
|
|
6046
|
+
retryPolicy: this.config.retryPolicy
|
|
5945
6047
|
}));
|
|
5946
6048
|
context.setSession(config.session);
|
|
5947
6049
|
service.initialize(context);
|
|
@@ -5951,7 +6053,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5951
6053
|
});
|
|
5952
6054
|
sharingService.updateConfig({
|
|
5953
6055
|
session: input.serviceSession,
|
|
5954
|
-
delegationManager,
|
|
5955
6056
|
sessionExpiry: input.sessionExpiry,
|
|
5956
6057
|
createDelegationWasm: (params) => {
|
|
5957
6058
|
graph.assertActive();
|
|
@@ -5982,7 +6083,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5982
6083
|
invokeAny: graph.invokeAny,
|
|
5983
6084
|
fetch: graph.fetch,
|
|
5984
6085
|
hosts: [input.host],
|
|
5985
|
-
telemetry: this.config.telemetry
|
|
6086
|
+
telemetry: this.config.telemetry,
|
|
6087
|
+
retryPolicy: this.config.retryPolicy
|
|
5986
6088
|
}));
|
|
5987
6089
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
5988
6090
|
scopedKv.initialize(context);
|
|
@@ -5997,7 +6099,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5997
6099
|
invokeAny: graph.invokeAny,
|
|
5998
6100
|
fetch: graph.fetch,
|
|
5999
6101
|
hosts: [input.host],
|
|
6000
|
-
telemetry: this.config.telemetry
|
|
6102
|
+
telemetry: this.config.telemetry,
|
|
6103
|
+
retryPolicy: this.config.retryPolicy
|
|
6001
6104
|
}));
|
|
6002
6105
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
6003
6106
|
scopedKv.initialize(context);
|
|
@@ -6080,6 +6183,21 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6080
6183
|
if (address === void 0 || chainId === void 0) {
|
|
6081
6184
|
return void 0;
|
|
6082
6185
|
}
|
|
6186
|
+
if (this.config.registryPolicy === "fail-closed") {
|
|
6187
|
+
const resolved2 = await (0, import_sdk_core10.resolveFailClosedTinyCloudHosts)(address, {
|
|
6188
|
+
registryUrl: this.config.tinycloudRegistryUrl,
|
|
6189
|
+
registryChainId: this.config.registryChainId,
|
|
6190
|
+
newUserHost: this.config.newUserHost,
|
|
6191
|
+
sequenceStore: this.config.registrySequenceStore,
|
|
6192
|
+
onNodeNotFound: this.config.onNodeNotFound,
|
|
6193
|
+
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
6194
|
+
localNodeUrl: this.config.localNodeUrl,
|
|
6195
|
+
localLinkName: this.config.localLinkName,
|
|
6196
|
+
expectedNodeDid: this.config.expectedNodeDid,
|
|
6197
|
+
localNodeIdentityStore: this.config.localNodeIdentityStore
|
|
6198
|
+
});
|
|
6199
|
+
return resolved2.hosts[0];
|
|
6200
|
+
}
|
|
6083
6201
|
const resolved = await (0, import_sdk_core10.resolveTinyCloudHosts)((0, import_sdk_core10.pkhDid)(address, chainId), {
|
|
6084
6202
|
registryUrl: this.config.tinycloudRegistryUrl,
|
|
6085
6203
|
fallbackHosts: this.config.tinycloudFallbackHosts,
|
|
@@ -6272,6 +6390,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6272
6390
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
6273
6391
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
6274
6392
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
6393
|
+
...this.registryPolicyConfig(),
|
|
6275
6394
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
6276
6395
|
localNodeUrl: this.config.localNodeUrl,
|
|
6277
6396
|
localLinkName: this.config.localLinkName,
|
|
@@ -6293,7 +6412,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6293
6412
|
});
|
|
6294
6413
|
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
6295
6414
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
6296
|
-
telemetry: this.config.telemetry
|
|
6415
|
+
telemetry: this.config.telemetry,
|
|
6416
|
+
retryPolicy: this.config.retryPolicy
|
|
6297
6417
|
});
|
|
6298
6418
|
this.config.prefix = prefix;
|
|
6299
6419
|
}
|
|
@@ -6331,6 +6451,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6331
6451
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
6332
6452
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
6333
6453
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
6454
|
+
...this.registryPolicyConfig(),
|
|
6334
6455
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
6335
6456
|
localNodeUrl: this.config.localNodeUrl,
|
|
6336
6457
|
localLinkName: this.config.localLinkName,
|
|
@@ -6352,7 +6473,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6352
6473
|
});
|
|
6353
6474
|
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
6354
6475
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
6355
|
-
telemetry: this.config.telemetry
|
|
6476
|
+
telemetry: this.config.telemetry,
|
|
6477
|
+
retryPolicy: this.config.retryPolicy
|
|
6356
6478
|
});
|
|
6357
6479
|
this.config.prefix = prefix;
|
|
6358
6480
|
}
|
|
@@ -6376,7 +6498,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6376
6498
|
invokeAny: this._serviceGraph.invokeAny,
|
|
6377
6499
|
fetch: this._serviceGraph.fetch,
|
|
6378
6500
|
hosts: [this.config.host],
|
|
6379
|
-
telemetry: this.config.telemetry
|
|
6501
|
+
telemetry: this.config.telemetry,
|
|
6502
|
+
retryPolicy: this.config.retryPolicy
|
|
6380
6503
|
}));
|
|
6381
6504
|
this._kv = new import_sdk_core10.KVService({});
|
|
6382
6505
|
this._kv.initialize(this._serviceContext);
|
|
@@ -6423,7 +6546,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6423
6546
|
invokeAny: this._serviceContext.invokeAny,
|
|
6424
6547
|
fetch: this._serviceContext.fetch,
|
|
6425
6548
|
hosts: this._serviceContext.hosts,
|
|
6426
|
-
telemetry: this.config.telemetry
|
|
6549
|
+
telemetry: this.config.telemetry,
|
|
6550
|
+
retryPolicy: this.config.retryPolicy
|
|
6427
6551
|
}));
|
|
6428
6552
|
const session = this._serviceContext.session;
|
|
6429
6553
|
if (session) {
|
|
@@ -6874,7 +6998,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6874
6998
|
assertActive: () => graph.assertActive(),
|
|
6875
6999
|
keyProvider: this._keyProvider,
|
|
6876
7000
|
registry: this._capabilityRegistry,
|
|
6877
|
-
delegationManager: this._delegationManager,
|
|
6878
7001
|
sessionExpiry: this.getSessionExpiry(),
|
|
6879
7002
|
createDelegationWasm: (params) => {
|
|
6880
7003
|
graph.assertActive();
|
|
@@ -6891,7 +7014,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6891
7014
|
invoke: config.invoke,
|
|
6892
7015
|
fetch: config.fetch ?? graph.fetch,
|
|
6893
7016
|
hosts: config.hosts,
|
|
6894
|
-
telemetry: this.config.telemetry
|
|
7017
|
+
telemetry: this.config.telemetry,
|
|
7018
|
+
retryPolicy: this.config.retryPolicy
|
|
6895
7019
|
}));
|
|
6896
7020
|
context.setSession(config.session);
|
|
6897
7021
|
service.initialize(context);
|
|
@@ -7212,7 +7336,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7212
7336
|
invokeAny: this._serviceContext.invokeAny,
|
|
7213
7337
|
fetch: this._serviceContext.fetch,
|
|
7214
7338
|
hosts: this._serviceContext.hosts,
|
|
7215
|
-
telemetry: this.config.telemetry
|
|
7339
|
+
telemetry: this.config.telemetry,
|
|
7340
|
+
retryPolicy: this.config.retryPolicy
|
|
7216
7341
|
}));
|
|
7217
7342
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
7218
7343
|
sql.initialize(spaceScopedContext);
|
|
@@ -7415,6 +7540,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7415
7540
|
}
|
|
7416
7541
|
};
|
|
7417
7542
|
}
|
|
7543
|
+
if (result.status === "aad_mismatch") return { status: "read_failed" };
|
|
7418
7544
|
return { status: result.status };
|
|
7419
7545
|
}
|
|
7420
7546
|
if (!isSecretPayload(result.entry.value)) {
|
|
@@ -7856,16 +7982,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7856
7982
|
* ```typescript
|
|
7857
7983
|
* const delegations = alice.delegationManager;
|
|
7858
7984
|
*
|
|
7859
|
-
* //
|
|
7860
|
-
* const
|
|
7861
|
-
* delegateDID: bob.did,
|
|
7862
|
-
* path: "shared/",
|
|
7863
|
-
* actions: ["tinycloud.kv/get", "tinycloud.kv/put"],
|
|
7864
|
-
* expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours
|
|
7865
|
-
* });
|
|
7866
|
-
*
|
|
7867
|
-
* // List delegations
|
|
7868
|
-
* const listResult = await delegations.list();
|
|
7985
|
+
* // Query account delegations
|
|
7986
|
+
* const page = await delegations.query();
|
|
7869
7987
|
*
|
|
7870
7988
|
* // Revoke a delegation
|
|
7871
7989
|
* await delegations.revoke(delegationCid);
|
|
@@ -7967,7 +8085,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7967
8085
|
* Ensure the user's public space exists and is accessible.
|
|
7968
8086
|
* Creates the space and activates a session delegation for it.
|
|
7969
8087
|
* This is the trigger for lazy public space creation — call it
|
|
7970
|
-
* before writing to spaces.get('public').kv.
|
|
8088
|
+
* before writing to spaces.get('public').kv. The vault calls it on unlock.
|
|
8089
|
+
* Under `registryPolicy: "fail-closed"` creation goes through the
|
|
8090
|
+
* space-creation guard.
|
|
7971
8091
|
*/
|
|
7972
8092
|
async ensurePublicSpace() {
|
|
7973
8093
|
if (!this.auth || !this.session || !this.signer) {
|
|
@@ -7977,6 +8097,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7977
8097
|
if (!publicSpaceId) {
|
|
7978
8098
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
7979
8099
|
}
|
|
8100
|
+
await this.assertMayCreateSpace();
|
|
7980
8101
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
7981
8102
|
const kvActions = [import_sdk_core10.KV.PUT, import_sdk_core10.KV.GET, import_sdk_core10.KV.DEL, import_sdk_core10.KV.LIST, import_sdk_core10.KV.METADATA];
|
|
7982
8103
|
const abilities = { kv: { "": kvActions } };
|
|
@@ -8034,7 +8155,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8034
8155
|
invoke: this._serviceGraph.invoke,
|
|
8035
8156
|
fetch: this._serviceGraph.fetch,
|
|
8036
8157
|
hosts: this._serviceContext.hosts,
|
|
8037
|
-
telemetry: this.config.telemetry
|
|
8158
|
+
telemetry: this.config.telemetry,
|
|
8159
|
+
retryPolicy: this.config.retryPolicy
|
|
8038
8160
|
}));
|
|
8039
8161
|
publicContext.setSession({
|
|
8040
8162
|
delegationHeader: delegationSession.delegationHeader,
|
|
@@ -8063,32 +8185,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8063
8185
|
// ===========================================================================
|
|
8064
8186
|
// v2 Delegation Convenience Methods
|
|
8065
8187
|
// ===========================================================================
|
|
8066
|
-
/**
|
|
8067
|
-
* Create a delegation using the v2 DelegationManager.
|
|
8068
|
-
*
|
|
8069
|
-
* This is a convenience method that wraps DelegationManager.create().
|
|
8070
|
-
* For more control, use `this.delegationManager` directly.
|
|
8071
|
-
*
|
|
8072
|
-
* @param params - Delegation parameters
|
|
8073
|
-
* @returns Result containing the created Delegation
|
|
8074
|
-
*
|
|
8075
|
-
* @example
|
|
8076
|
-
* ```typescript
|
|
8077
|
-
* const result = await alice.delegate({
|
|
8078
|
-
* delegateDID: bob.did,
|
|
8079
|
-
* path: "shared/",
|
|
8080
|
-
* actions: ["tinycloud.kv/get", "tinycloud.kv/put"],
|
|
8081
|
-
* expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
8082
|
-
* });
|
|
8083
|
-
*
|
|
8084
|
-
* if (result.ok) {
|
|
8085
|
-
* console.log("Delegation created:", result.data.cid);
|
|
8086
|
-
* }
|
|
8087
|
-
* ```
|
|
8088
|
-
*/
|
|
8089
|
-
async delegate(params) {
|
|
8090
|
-
return this.delegationManager.create(params);
|
|
8091
|
-
}
|
|
8092
8188
|
/**
|
|
8093
8189
|
* Revoke a delegation with the owner wallet when available. Session-only
|
|
8094
8190
|
* clients continue to use their delegated revocation authority.
|
|
@@ -8114,14 +8210,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8114
8210
|
0x55n
|
|
8115
8211
|
);
|
|
8116
8212
|
}
|
|
8117
|
-
/**
|
|
8118
|
-
* List all delegations for the current session's space.
|
|
8119
|
-
*
|
|
8120
|
-
* @returns Result containing an array of Delegations
|
|
8121
|
-
*/
|
|
8122
|
-
async listDelegations() {
|
|
8123
|
-
return this.delegationManager.list();
|
|
8124
|
-
}
|
|
8125
8213
|
/**
|
|
8126
8214
|
* Check if the current session has permission for a path and action.
|
|
8127
8215
|
*
|
|
@@ -8181,6 +8269,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8181
8269
|
"delegateTo: onPrepared cannot be combined with forceWalletSign=true; the wallet-signed path activates the delegation before it could be handed to onPrepared."
|
|
8182
8270
|
);
|
|
8183
8271
|
}
|
|
8272
|
+
if (options?.disableSubDelegation && did.startsWith("did:pkh:")) {
|
|
8273
|
+
throw new Error(TERMINAL_DELEGATION_REQUIRES_SESSION_KEY);
|
|
8274
|
+
}
|
|
8184
8275
|
const session = this.currentTinyCloudSession();
|
|
8185
8276
|
if (!session) {
|
|
8186
8277
|
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
@@ -8246,7 +8337,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8246
8337
|
plan.grant,
|
|
8247
8338
|
plan.operations,
|
|
8248
8339
|
onPrepared,
|
|
8249
|
-
options?.disableSubDelegation === true
|
|
8340
|
+
options?.disableSubDelegation === true,
|
|
8341
|
+
options?.requireActivation === true
|
|
8250
8342
|
);
|
|
8251
8343
|
return { delegation: delegation2, prompted: false };
|
|
8252
8344
|
}
|
|
@@ -8256,7 +8348,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8256
8348
|
effectiveExpiration,
|
|
8257
8349
|
session,
|
|
8258
8350
|
onPrepared,
|
|
8259
|
-
options?.disableSubDelegation === true
|
|
8351
|
+
options?.disableSubDelegation === true,
|
|
8352
|
+
options?.requireActivation === true
|
|
8260
8353
|
);
|
|
8261
8354
|
return { delegation, prompted: false };
|
|
8262
8355
|
}
|
|
@@ -8487,7 +8580,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8487
8580
|
*
|
|
8488
8581
|
* @internal
|
|
8489
8582
|
*/
|
|
8490
|
-
async createDelegationViaWasmPath(did, entries, expirationTime, session, onPrepared, disableSubDelegation = false) {
|
|
8583
|
+
async createDelegationViaWasmPath(did, entries, expirationTime, session, onPrepared, disableSubDelegation = false, requireActivation = false) {
|
|
8491
8584
|
if (entries.length === 0) {
|
|
8492
8585
|
throw new Error(
|
|
8493
8586
|
"createDelegationViaWasmPath requires a non-empty entries array"
|
|
@@ -8571,15 +8664,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8571
8664
|
this.config.host,
|
|
8572
8665
|
delegationHeader
|
|
8573
8666
|
);
|
|
8574
|
-
|
|
8575
|
-
throw Object.assign(
|
|
8576
|
-
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
8577
|
-
{ cause: activateResult }
|
|
8578
|
-
);
|
|
8579
|
-
}
|
|
8667
|
+
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
8580
8668
|
return delegation;
|
|
8581
8669
|
}
|
|
8582
|
-
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations, onPrepared, disableSubDelegation = false) {
|
|
8670
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations, onPrepared, disableSubDelegation = false, requireActivation = false) {
|
|
8583
8671
|
this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
|
|
8584
8672
|
this.assertDelegationCaveatsPreservable(entries);
|
|
8585
8673
|
const result = this.createDelegationWrapper({
|
|
@@ -8613,12 +8701,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8613
8701
|
targetHost,
|
|
8614
8702
|
delegationHeader
|
|
8615
8703
|
);
|
|
8616
|
-
|
|
8617
|
-
throw Object.assign(
|
|
8618
|
-
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
8619
|
-
{ cause: activateResult }
|
|
8620
|
-
);
|
|
8621
|
-
}
|
|
8704
|
+
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
8622
8705
|
return delegation;
|
|
8623
8706
|
}
|
|
8624
8707
|
resolvePermissionSpace(space, session) {
|
|
@@ -9565,6 +9648,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
9565
9648
|
};
|
|
9566
9649
|
}
|
|
9567
9650
|
};
|
|
9651
|
+
/** Set once per process: the registry sync was skipped for want of account access. */
|
|
9652
|
+
_TinyCloudNode.accountRegistrySkipLogged = false;
|
|
9568
9653
|
// ===========================================================================
|
|
9569
9654
|
// Capability-chain delegation (spec: .claude/specs/capability-chain.md)
|
|
9570
9655
|
// ===========================================================================
|