@tinycloud/node-sdk 2.2.0-beta.0 → 2.2.0-beta.10

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/index.cjs CHANGED
@@ -17025,69 +17025,76 @@ var require_utils2 = __commonJS({
17025
17025
  // src/index.ts
17026
17026
  var index_exports = {};
17027
17027
  __export(index_exports, {
17028
- ACCOUNT_REGISTRY_PATH: () => import_sdk_core8.ACCOUNT_REGISTRY_PATH,
17029
- ACCOUNT_REGISTRY_SPACE: () => import_sdk_core8.ACCOUNT_REGISTRY_SPACE,
17030
- AutoApproveSpaceCreationHandler: () => import_sdk_core7.AutoApproveSpaceCreationHandler,
17031
- CapabilityKeyRegistry: () => import_sdk_core15.CapabilityKeyRegistry,
17032
- CapabilityKeyRegistryErrorCodes: () => import_sdk_core15.CapabilityKeyRegistryErrorCodes,
17033
- DEFAULT_MANIFEST_SPACE: () => import_sdk_core8.DEFAULT_MANIFEST_SPACE,
17034
- DEFAULT_MANIFEST_VERSION: () => import_sdk_core8.DEFAULT_MANIFEST_VERSION,
17035
- DataVaultService: () => import_sdk_core12.DataVaultService,
17036
- DatabaseHandle: () => import_sdk_core10.DatabaseHandle,
17028
+ ACCOUNT_REGISTRY_PATH: () => import_sdk_core9.ACCOUNT_REGISTRY_PATH,
17029
+ ACCOUNT_REGISTRY_SPACE: () => import_sdk_core9.ACCOUNT_REGISTRY_SPACE,
17030
+ AutoApproveSpaceCreationHandler: () => import_sdk_core8.AutoApproveSpaceCreationHandler,
17031
+ CapabilityKeyRegistry: () => import_sdk_core16.CapabilityKeyRegistry,
17032
+ CapabilityKeyRegistryErrorCodes: () => import_sdk_core16.CapabilityKeyRegistryErrorCodes,
17033
+ DEFAULT_MANIFEST_SPACE: () => import_sdk_core9.DEFAULT_MANIFEST_SPACE,
17034
+ DEFAULT_MANIFEST_VERSION: () => import_sdk_core9.DEFAULT_MANIFEST_VERSION,
17035
+ DataVaultService: () => import_sdk_core13.DataVaultService,
17036
+ DatabaseHandle: () => import_sdk_core11.DatabaseHandle,
17037
17037
  DelegatedAccess: () => DelegatedAccess,
17038
- DelegationErrorCodes: () => import_sdk_core14.DelegationErrorCodes,
17039
- DelegationManager: () => import_sdk_core14.DelegationManager,
17040
- DuckDbAction: () => import_sdk_core11.DuckDbAction,
17041
- DuckDbDatabaseHandle: () => import_sdk_core11.DuckDbDatabaseHandle,
17042
- DuckDbService: () => import_sdk_core11.DuckDbService,
17038
+ DelegationErrorCodes: () => import_sdk_core15.DelegationErrorCodes,
17039
+ DelegationManager: () => import_sdk_core15.DelegationManager,
17040
+ DuckDbAction: () => import_sdk_core12.DuckDbAction,
17041
+ DuckDbDatabaseHandle: () => import_sdk_core12.DuckDbDatabaseHandle,
17042
+ DuckDbService: () => import_sdk_core12.DuckDbService,
17043
17043
  FileSessionStorage: () => FileSessionStorage,
17044
- HooksService: () => import_sdk_core13.HooksService,
17045
- KVService: () => import_sdk_core9.KVService,
17046
- ManifestValidationError: () => import_sdk_core8.ManifestValidationError,
17044
+ HooksService: () => import_sdk_core14.HooksService,
17045
+ KVService: () => import_sdk_core10.KVService,
17046
+ ManifestValidationError: () => import_sdk_core9.ManifestValidationError,
17047
17047
  MemorySessionStorage: () => MemorySessionStorage,
17048
17048
  NodeUserAuthorization: () => NodeUserAuthorization,
17049
17049
  NodeWasmBindings: () => NodeWasmBindings,
17050
- PermissionNotInManifestError: () => import_sdk_core8.PermissionNotInManifestError,
17051
- PrefixedKVService: () => import_sdk_core9.PrefixedKVService,
17050
+ PermissionNotInManifestError: () => import_sdk_core9.PermissionNotInManifestError,
17051
+ PrefixedKVService: () => import_sdk_core10.PrefixedKVService,
17052
17052
  PrivateKeySigner: () => PrivateKeySigner,
17053
- ProtocolMismatchError: () => import_sdk_core17.ProtocolMismatchError,
17054
- SQLAction: () => import_sdk_core10.SQLAction,
17055
- SQLService: () => import_sdk_core10.SQLService,
17056
- ServiceContext: () => import_sdk_core18.ServiceContext,
17057
- SessionExpiredError: () => import_sdk_core8.SessionExpiredError,
17058
- SharingService: () => import_sdk_core14.SharingService,
17059
- SilentNotificationHandler: () => import_sdk_core7.SilentNotificationHandler,
17060
- Space: () => import_sdk_core16.Space,
17061
- SpaceErrorCodes: () => import_sdk_core16.SpaceErrorCodes,
17062
- SpaceService: () => import_sdk_core16.SpaceService,
17063
- TinyCloud: () => import_sdk_core6.TinyCloud,
17053
+ ProtocolMismatchError: () => import_sdk_core18.ProtocolMismatchError,
17054
+ SECRET_NAME_RE: () => import_sdk_core13.SECRET_NAME_RE,
17055
+ SQLAction: () => import_sdk_core11.SQLAction,
17056
+ SQLService: () => import_sdk_core11.SQLService,
17057
+ SecretsService: () => import_sdk_core13.SecretsService,
17058
+ ServiceContext: () => import_sdk_core19.ServiceContext,
17059
+ SessionExpiredError: () => import_sdk_core9.SessionExpiredError,
17060
+ SharingService: () => import_sdk_core15.SharingService,
17061
+ SilentNotificationHandler: () => import_sdk_core8.SilentNotificationHandler,
17062
+ Space: () => import_sdk_core17.Space,
17063
+ SpaceErrorCodes: () => import_sdk_core17.SpaceErrorCodes,
17064
+ SpaceService: () => import_sdk_core17.SpaceService,
17065
+ TinyCloud: () => import_sdk_core7.TinyCloud,
17064
17066
  TinyCloudNode: () => TinyCloudNode,
17065
- UnsupportedFeatureError: () => import_sdk_core17.UnsupportedFeatureError,
17066
- VaultHeaders: () => import_sdk_core12.VaultHeaders,
17067
- VaultPublicSpaceKVActions: () => import_sdk_core12.VaultPublicSpaceKVActions,
17068
- VersionCheckError: () => import_sdk_core17.VersionCheckError,
17067
+ UnsupportedFeatureError: () => import_sdk_core18.UnsupportedFeatureError,
17068
+ VAULT_PERMISSION_SERVICE: () => import_sdk_core9.VAULT_PERMISSION_SERVICE,
17069
+ VaultHeaders: () => import_sdk_core13.VaultHeaders,
17070
+ VaultPublicSpaceKVActions: () => import_sdk_core13.VaultPublicSpaceKVActions,
17071
+ VersionCheckError: () => import_sdk_core18.VersionCheckError,
17069
17072
  WasmKeyProvider: () => WasmKeyProvider,
17070
- buildSpaceUri: () => import_sdk_core16.buildSpaceUri,
17071
- checkNodeInfo: () => import_sdk_core17.checkNodeInfo,
17072
- composeManifestRequest: () => import_sdk_core8.composeManifestRequest,
17073
- createCapabilityKeyRegistry: () => import_sdk_core15.createCapabilityKeyRegistry,
17074
- createSharingService: () => import_sdk_core14.createSharingService,
17075
- createSpaceService: () => import_sdk_core16.createSpaceService,
17076
- createVaultCrypto: () => import_sdk_core12.createVaultCrypto,
17073
+ buildSpaceUri: () => import_sdk_core17.buildSpaceUri,
17074
+ canonicalizeSecretScope: () => import_sdk_core13.canonicalizeSecretScope,
17075
+ checkNodeInfo: () => import_sdk_core18.checkNodeInfo,
17076
+ composeManifestRequest: () => import_sdk_core9.composeManifestRequest,
17077
+ createCapabilityKeyRegistry: () => import_sdk_core16.createCapabilityKeyRegistry,
17078
+ createSharingService: () => import_sdk_core15.createSharingService,
17079
+ createSpaceService: () => import_sdk_core17.createSpaceService,
17080
+ createVaultCrypto: () => import_sdk_core13.createVaultCrypto,
17077
17081
  createWasmKeyProvider: () => createWasmKeyProvider,
17078
17082
  defaultSignStrategy: () => defaultSignStrategy,
17079
- defaultSpaceCreationHandler: () => import_sdk_core7.defaultSpaceCreationHandler,
17083
+ defaultSpaceCreationHandler: () => import_sdk_core8.defaultSpaceCreationHandler,
17080
17084
  deserializeDelegation: () => deserializeDelegation,
17081
- expandActionShortNames: () => import_sdk_core8.expandActionShortNames,
17082
- isCapabilitySubset: () => import_sdk_core8.isCapabilitySubset,
17083
- loadManifest: () => import_sdk_core8.loadManifest,
17084
- makePublicSpaceId: () => import_sdk_core16.makePublicSpaceId,
17085
- parseExpiry: () => import_sdk_core8.parseExpiry,
17086
- parseSpaceUri: () => import_sdk_core16.parseSpaceUri,
17087
- resolveManifest: () => import_sdk_core8.resolveManifest,
17088
- resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core8.resourceCapabilitiesToSpaceAbilitiesMap,
17085
+ expandActionShortNames: () => import_sdk_core9.expandActionShortNames,
17086
+ expandPermissionEntries: () => import_sdk_core9.expandPermissionEntries,
17087
+ expandPermissionEntry: () => import_sdk_core9.expandPermissionEntry,
17088
+ isCapabilitySubset: () => import_sdk_core9.isCapabilitySubset,
17089
+ loadManifest: () => import_sdk_core9.loadManifest,
17090
+ makePublicSpaceId: () => import_sdk_core17.makePublicSpaceId,
17091
+ parseExpiry: () => import_sdk_core9.parseExpiry,
17092
+ parseSpaceUri: () => import_sdk_core17.parseSpaceUri,
17093
+ resolveManifest: () => import_sdk_core9.resolveManifest,
17094
+ resolveSecretPath: () => import_sdk_core13.resolveSecretPath,
17095
+ resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core9.resourceCapabilitiesToSpaceAbilitiesMap,
17089
17096
  serializeDelegation: () => serializeDelegation,
17090
- validateManifest: () => import_sdk_core8.validateManifest
17097
+ validateManifest: () => import_sdk_core9.validateManifest
17091
17098
  });
17092
17099
  module.exports = __toCommonJS(index_exports);
17093
17100
 
@@ -17191,7 +17198,7 @@ var PrivateKeySigner = class {
17191
17198
  };
17192
17199
 
17193
17200
  // src/TinyCloudNode.ts
17194
- var import_sdk_core4 = require("@tinycloud/sdk-core");
17201
+ var import_sdk_core5 = require("@tinycloud/sdk-core");
17195
17202
 
17196
17203
  // src/authorization/NodeUserAuthorization.ts
17197
17204
  var import_sdk_core = require("@tinycloud/sdk-core");
@@ -17327,9 +17334,9 @@ var NodeUserAuthorization = class {
17327
17334
  this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
17328
17335
  this.autoCreateSpace = config.autoCreateSpace ?? false;
17329
17336
  this.spaceCreationHandler = config.spaceCreationHandler;
17330
- this.tinycloudHosts = config.tinycloudHosts ?? [
17331
- "https://node.tinycloud.xyz"
17332
- ];
17337
+ this.tinycloudHosts = config.tinycloudHosts;
17338
+ this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
17339
+ this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
17333
17340
  this.enablePublicSpace = config.enablePublicSpace ?? true;
17334
17341
  this.nonce = config.nonce;
17335
17342
  this.siweConfig = config.siweConfig;
@@ -17350,6 +17357,9 @@ var NodeUserAuthorization = class {
17350
17357
  get capabilityRequest() {
17351
17358
  return this.getCapabilityRequest();
17352
17359
  }
17360
+ get hosts() {
17361
+ return this.tinycloudHosts ? [...this.tinycloudHosts] : [];
17362
+ }
17353
17363
  /**
17354
17364
  * Install or replace the stored manifest. Takes effect on the next
17355
17365
  * `signIn()` call — the current session (if any) is not touched.
@@ -17374,6 +17384,26 @@ var NodeUserAuthorization = class {
17374
17384
  get tinyCloudSession() {
17375
17385
  return this._tinyCloudSession;
17376
17386
  }
17387
+ async resolveTinyCloudHostsForSignIn(address, chainId) {
17388
+ if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
17389
+ return;
17390
+ }
17391
+ const subject = `did:pkh:eip155:${chainId}:${address}`;
17392
+ const resolved = await (0, import_sdk_core.resolveTinyCloudHosts)(subject, {
17393
+ registryUrl: this.tinycloudRegistryUrl,
17394
+ fallbackHosts: this.tinycloudFallbackHosts
17395
+ });
17396
+ this.tinycloudHosts = resolved.hosts;
17397
+ }
17398
+ requireTinyCloudHosts() {
17399
+ if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
17400
+ throw new Error("TinyCloud hosts have not been resolved. Call signIn() first.");
17401
+ }
17402
+ return this.tinycloudHosts;
17403
+ }
17404
+ get primaryTinyCloudHost() {
17405
+ return this.requireTinyCloudHosts()[0];
17406
+ }
17377
17407
  get nodeFeatures() {
17378
17408
  return this._nodeFeatures;
17379
17409
  }
@@ -17505,7 +17535,7 @@ var NodeUserAuthorization = class {
17505
17535
  if (!this._tinyCloudSession || !this._address || !this._chainId) {
17506
17536
  throw new Error("Must be signed in to host space");
17507
17537
  }
17508
- const host = this.tinycloudHosts[0];
17538
+ const host = this.primaryTinyCloudHost;
17509
17539
  const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
17510
17540
  const peerId = await (0, import_sdk_core.fetchPeerId)(host, spaceId);
17511
17541
  const siwe = this.wasm.generateHostSIWEMessage({
@@ -17547,7 +17577,7 @@ var NodeUserAuthorization = class {
17547
17577
  if (!this._tinyCloudSession) {
17548
17578
  throw new Error("Must be signed in to ensure space exists");
17549
17579
  }
17550
- const host = this.tinycloudHosts[0];
17580
+ const host = this.primaryTinyCloudHost;
17551
17581
  const primarySpaceId = this._tinyCloudSession.spaceId;
17552
17582
  const result = await (0, import_sdk_core.activateSessionWithHost)(
17553
17583
  host,
@@ -17656,6 +17686,7 @@ var NodeUserAuthorization = class {
17656
17686
  this._chainId = await this.signer.getChainId();
17657
17687
  const address = this.wasm.ensureEip55(this._address);
17658
17688
  const chainId = this._chainId;
17689
+ await this.resolveTinyCloudHostsForSignIn(address, chainId);
17659
17690
  const keyId = `session-${Date.now()}`;
17660
17691
  this.sessionManager.renameSessionKeyId("default", keyId);
17661
17692
  const jwkString = this.sessionManager.jwk(keyId);
@@ -17734,7 +17765,7 @@ var NodeUserAuthorization = class {
17734
17765
  this._address = address;
17735
17766
  this._chainId = chainId;
17736
17767
  const nodeInfo = await (0, import_sdk_core.checkNodeInfo)(
17737
- this.tinycloudHosts[0],
17768
+ this.primaryTinyCloudHost,
17738
17769
  this.wasm.protocolVersion()
17739
17770
  );
17740
17771
  this._nodeFeatures = nodeInfo.features;
@@ -17850,6 +17881,7 @@ var NodeUserAuthorization = class {
17850
17881
  });
17851
17882
  const address = this.wasm.ensureEip55(await this.signer.getAddress());
17852
17883
  const chainId = await this.signer.getChainId();
17884
+ await this.resolveTinyCloudHostsForSignIn(address, chainId);
17853
17885
  const clientSession = {
17854
17886
  address,
17855
17887
  walletAddress: address,
@@ -17899,7 +17931,7 @@ var NodeUserAuthorization = class {
17899
17931
  this._address = address;
17900
17932
  this._chainId = chainId;
17901
17933
  const nodeInfo = await (0, import_sdk_core.checkNodeInfo)(
17902
- this.tinycloudHosts[0],
17934
+ this.primaryTinyCloudHost,
17903
17935
  this.wasm.protocolVersion()
17904
17936
  );
17905
17937
  this._nodeFeatures = nodeInfo.features;
@@ -18057,6 +18089,24 @@ var DelegatedAccess = class {
18057
18089
  get hooks() {
18058
18090
  return this._hooks;
18059
18091
  }
18092
+ /**
18093
+ * Export the handles needed to rehydrate this activated delegation via
18094
+ * `TinyCloudNode.restoreSession(...)` in another process or after a
18095
+ * restart.
18096
+ *
18097
+ * See `RestorableSession` for lifetime caveats.
18098
+ */
18099
+ get restorable() {
18100
+ return {
18101
+ delegationHeader: this.session.delegationHeader,
18102
+ delegationCid: this.session.delegationCid,
18103
+ spaceId: this.session.spaceId,
18104
+ jwk: this.session.jwk,
18105
+ verificationMethod: this.session.verificationMethod,
18106
+ address: this.session.address,
18107
+ chainId: this.session.chainId
18108
+ };
18109
+ }
18060
18110
  };
18061
18111
 
18062
18112
  // src/keys/WasmKeyProvider.ts
@@ -18194,6 +18244,148 @@ function extractSiweExpiration(siwe) {
18194
18244
  return d;
18195
18245
  }
18196
18246
 
18247
+ // src/NodeSecretsService.ts
18248
+ var import_sdk_core4 = require("@tinycloud/sdk-core");
18249
+ var SECRETS_SPACE = "secrets";
18250
+ function ok() {
18251
+ return { ok: true, data: void 0 };
18252
+ }
18253
+ function secretsError(code, message, cause) {
18254
+ return {
18255
+ ok: false,
18256
+ error: {
18257
+ code,
18258
+ service: "secrets",
18259
+ message,
18260
+ ...cause ? { cause } : {}
18261
+ }
18262
+ };
18263
+ }
18264
+ function displayActionUrn(action) {
18265
+ return action === "put" ? "tinycloud.vault/write" : "tinycloud.vault/delete";
18266
+ }
18267
+ function kvActionUrn(action) {
18268
+ return `tinycloud.kv/${action}`;
18269
+ }
18270
+ function vaultMutationAction(action) {
18271
+ return action === "put" ? "write" : "delete";
18272
+ }
18273
+ function secretPermissionEntries(name, options, action) {
18274
+ const secretPath = (0, import_sdk_core4.resolveSecretPath)(name, options);
18275
+ return [
18276
+ {
18277
+ service: "tinycloud.vault",
18278
+ space: SECRETS_SPACE,
18279
+ path: secretPath.vaultKey,
18280
+ actions: [vaultMutationAction(action)],
18281
+ skipPrefix: true
18282
+ }
18283
+ ];
18284
+ }
18285
+ function isSecretsSpace(space) {
18286
+ return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
18287
+ }
18288
+ var NodeSecretsService = class {
18289
+ constructor(config) {
18290
+ this.config = config;
18291
+ this.shouldRestoreUnlock = false;
18292
+ }
18293
+ get vault() {
18294
+ return this.service.vault;
18295
+ }
18296
+ get isUnlocked() {
18297
+ return this.service.isUnlocked;
18298
+ }
18299
+ async unlock(signer) {
18300
+ const effectiveSigner = signer ?? this.config.getUnlockSigner?.();
18301
+ if (effectiveSigner !== void 0) {
18302
+ this.unlockSigner = effectiveSigner;
18303
+ }
18304
+ const result = await this.service.unlock(effectiveSigner);
18305
+ if (result.ok) {
18306
+ this.shouldRestoreUnlock = true;
18307
+ }
18308
+ return result;
18309
+ }
18310
+ lock() {
18311
+ this.shouldRestoreUnlock = false;
18312
+ this.service.lock();
18313
+ }
18314
+ get(name, options) {
18315
+ return options === void 0 ? this.service.get(name) : this.service.get(name, options);
18316
+ }
18317
+ async put(name, value, options) {
18318
+ const permission = await this.ensureMutationPermission(name, options, "put");
18319
+ if (!permission.ok) return permission;
18320
+ return options === void 0 ? this.service.put(name, value) : this.service.put(name, value, options);
18321
+ }
18322
+ async delete(name, options) {
18323
+ const permission = await this.ensureMutationPermission(name, options, "del");
18324
+ if (!permission.ok) return permission;
18325
+ return options === void 0 ? this.service.delete(name) : this.service.delete(name, options);
18326
+ }
18327
+ list(options) {
18328
+ return options === void 0 ? this.service.list() : this.service.list(options);
18329
+ }
18330
+ get service() {
18331
+ return this.config.getService();
18332
+ }
18333
+ async ensureMutationPermission(name, options, action) {
18334
+ let permissionEntries;
18335
+ try {
18336
+ permissionEntries = secretPermissionEntries(name, options, action);
18337
+ } catch (error) {
18338
+ return secretsError(
18339
+ import_sdk_core4.ErrorCodes.INVALID_INPUT,
18340
+ error instanceof Error ? error.message : String(error),
18341
+ error instanceof Error ? error : void 0
18342
+ );
18343
+ }
18344
+ if (this.hasMutationPermission(name, options, action)) {
18345
+ return ok();
18346
+ }
18347
+ if (!this.config.canEscalate()) {
18348
+ return secretsError(
18349
+ import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
18350
+ `Cannot autosign ${displayActionUrn(action)} for ${name}; TinyCloudNode needs wallet mode with a signer or privateKey.`
18351
+ );
18352
+ }
18353
+ try {
18354
+ await this.config.grantPermissions(permissionEntries);
18355
+ return this.restoreUnlockAfterEscalation();
18356
+ } catch (error) {
18357
+ return secretsError(
18358
+ import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
18359
+ error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${name} failed.`,
18360
+ error instanceof Error ? error : void 0
18361
+ );
18362
+ }
18363
+ }
18364
+ async restoreUnlockAfterEscalation() {
18365
+ if (!this.shouldRestoreUnlock) {
18366
+ return ok();
18367
+ }
18368
+ return this.service.unlock(this.unlockSigner);
18369
+ }
18370
+ hasMutationPermission(name, options, action) {
18371
+ const manifest = this.config.getManifest();
18372
+ if (manifest === void 0) {
18373
+ return false;
18374
+ }
18375
+ const manifests = Array.isArray(manifest) ? manifest : [manifest];
18376
+ const requiredAction = kvActionUrn(action);
18377
+ const secretPath = (0, import_sdk_core4.resolveSecretPath)(name, options);
18378
+ return manifests.some((entry) => {
18379
+ const resolved = (0, import_sdk_core4.resolveManifest)(entry);
18380
+ return ["keys", "vault"].every(
18381
+ (base2) => resolved.resources.some(
18382
+ (resource) => resource.service === "tinycloud.kv" && isSecretsSpace(resource.space) && resource.path === secretPath.permissionPaths[base2] && resource.actions.includes(requiredAction)
18383
+ )
18384
+ );
18385
+ });
18386
+ }
18387
+ };
18388
+
18197
18389
  // src/TinyCloudNode.ts
18198
18390
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
18199
18391
  var _TinyCloudNode = class _TinyCloudNode {
@@ -18225,6 +18417,31 @@ var _TinyCloudNode = class _TinyCloudNode {
18225
18417
  this.auth = null;
18226
18418
  this.tc = null;
18227
18419
  this._chainId = 1;
18420
+ this.runtimePermissionGrants = [];
18421
+ this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
18422
+ return this.wasmBindings.invoke(
18423
+ this.selectInvocationSession(session, service, path, action),
18424
+ service,
18425
+ path,
18426
+ action,
18427
+ facts
18428
+ );
18429
+ };
18430
+ this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
18431
+ if (!this.wasmBindings.invokeAny) {
18432
+ throw new Error("WASM binding does not support invokeAny");
18433
+ }
18434
+ const grant = this.findGrantForOperations(
18435
+ entries.map((entry) => ({
18436
+ spaceId: entry.spaceId,
18437
+ service: this.invocationServiceName(entry.service),
18438
+ path: entry.path,
18439
+ action: entry.action
18440
+ }))
18441
+ );
18442
+ return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
18443
+ };
18444
+ this.explicitHost = config.host;
18228
18445
  this.config = {
18229
18446
  ...config,
18230
18447
  host: config.host ?? DEFAULT_HOST
@@ -18251,23 +18468,23 @@ var _TinyCloudNode = class _TinyCloudNode {
18251
18468
  throw new Error("Failed to get session key JWK");
18252
18469
  }
18253
18470
  this.sessionKeyJwk = JSON.parse(jwkStr);
18254
- this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
18471
+ this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
18255
18472
  this._keyProvider = new WasmKeyProvider({
18256
18473
  sessionManager: this.sessionManager
18257
18474
  });
18258
- this.notificationHandler = config.notificationHandler ?? new import_sdk_core4.SilentNotificationHandler();
18259
- this._sharingService = new import_sdk_core4.SharingService({
18475
+ this.notificationHandler = config.notificationHandler ?? new import_sdk_core5.SilentNotificationHandler();
18476
+ this._sharingService = new import_sdk_core5.SharingService({
18260
18477
  hosts: [this.config.host],
18261
18478
  // session: undefined - not needed for receive()
18262
- invoke: this.wasmBindings.invoke,
18479
+ invoke: this.invokeWithRuntimePermissions,
18263
18480
  fetch: globalThis.fetch.bind(globalThis),
18264
18481
  keyProvider: this._keyProvider,
18265
18482
  registry: this._capabilityRegistry,
18266
18483
  // delegationManager: undefined - not needed for receive()
18267
18484
  createKVService: (config2) => {
18268
18485
  const prefix = config2.pathPrefix?.replace(/\/$/, "");
18269
- const kvService = new import_sdk_core4.KVService({ prefix });
18270
- const kvContext = new import_sdk_core4.ServiceContext({
18486
+ const kvService = new import_sdk_core5.KVService({ prefix });
18487
+ const kvContext = new import_sdk_core5.ServiceContext({
18271
18488
  invoke: config2.invoke,
18272
18489
  fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
18273
18490
  hosts: config2.hosts
@@ -18306,7 +18523,6 @@ var _TinyCloudNode = class _TinyCloudNode {
18306
18523
  * @internal
18307
18524
  */
18308
18525
  setupAuth(config) {
18309
- const host = this.config.host;
18310
18526
  this.auth = new NodeUserAuthorization({
18311
18527
  signer: this.signer,
18312
18528
  signStrategy: { type: "auto-sign" },
@@ -18315,7 +18531,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18315
18531
  domain: this.siweDomain,
18316
18532
  spacePrefix: config.prefix,
18317
18533
  sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
18318
- tinycloudHosts: [host],
18534
+ tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18535
+ tinycloudRegistryUrl: config.tinycloudRegistryUrl,
18536
+ tinycloudFallbackHosts: config.tinycloudFallbackHosts,
18319
18537
  autoCreateSpace: config.autoCreateSpace,
18320
18538
  enablePublicSpace: config.enablePublicSpace ?? true,
18321
18539
  spaceCreationHandler: config.spaceCreationHandler,
@@ -18325,10 +18543,16 @@ var _TinyCloudNode = class _TinyCloudNode {
18325
18543
  capabilityRequest: config.capabilityRequest,
18326
18544
  includeAccountRegistryPermissions: config.includeAccountRegistryPermissions
18327
18545
  });
18328
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18329
- invokeAny: this.wasmBindings.invokeAny
18546
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
18547
+ invokeAny: this.invokeAnyWithRuntimePermissions
18330
18548
  });
18331
18549
  }
18550
+ syncResolvedHostFromAuth() {
18551
+ const host = this.auth?.hosts[0];
18552
+ if (host) {
18553
+ this.config.host = host;
18554
+ }
18555
+ }
18332
18556
  /**
18333
18557
  * Install or replace the manifest that drives the SIWE recap at
18334
18558
  * sign-in. Takes effect on the next `signIn()` call — the current
@@ -18366,6 +18590,10 @@ var _TinyCloudNode = class _TinyCloudNode {
18366
18590
  get capabilityRequest() {
18367
18591
  return this.auth?.capabilityRequest;
18368
18592
  }
18593
+ get hosts() {
18594
+ const authHosts = this.auth?.hosts ?? [];
18595
+ return authHosts.length > 0 ? authHosts : [this.config.host];
18596
+ }
18369
18597
  /**
18370
18598
  * Get the primary identity DID for this user.
18371
18599
  * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
@@ -18436,8 +18664,14 @@ var _TinyCloudNode = class _TinyCloudNode {
18436
18664
  this._sql = void 0;
18437
18665
  this._duckdb = void 0;
18438
18666
  this._hooks = void 0;
18667
+ this._vault = void 0;
18668
+ this._baseSecrets = void 0;
18669
+ this._secrets = void 0;
18670
+ this._spaceService = void 0;
18439
18671
  this._serviceContext = void 0;
18672
+ this.runtimePermissionGrants = [];
18440
18673
  await this.tc.signIn(options);
18674
+ this.syncResolvedHostFromAuth();
18441
18675
  this.initializeServices();
18442
18676
  await this.writeManifestRegistryRecords();
18443
18677
  this.notificationHandler.success("Successfully signed in");
@@ -18456,8 +18690,8 @@ var _TinyCloudNode = class _TinyCloudNode {
18456
18690
  if (!this.auth || !this.signer) {
18457
18691
  throw new Error("Manifest registry write requires wallet mode");
18458
18692
  }
18459
- const accountSpaceId = this.ownedSpaceId(import_sdk_core4.ACCOUNT_REGISTRY_SPACE);
18460
- await this.auth.hostOwnedSpace(accountSpaceId);
18693
+ const accountSpaceId = this.ownedSpaceId(import_sdk_core5.ACCOUNT_REGISTRY_SPACE);
18694
+ await this.ensureOwnedSpaceHosted(accountSpaceId);
18461
18695
  const accountKV = this.spaces.get(accountSpaceId).kv;
18462
18696
  for (const record of request.registryRecords) {
18463
18697
  const result = await accountKV.put(record.key, {
@@ -18472,6 +18706,39 @@ var _TinyCloudNode = class _TinyCloudNode {
18472
18706
  }
18473
18707
  }
18474
18708
  }
18709
+ async ensureOwnedSpaceHosted(spaceId) {
18710
+ if (!this.auth) {
18711
+ throw new Error("Owned space hosting requires wallet mode");
18712
+ }
18713
+ const session = this.auth.tinyCloudSession;
18714
+ if (!session) {
18715
+ throw new Error("Owned space hosting requires an active session");
18716
+ }
18717
+ const host = this.hosts[0] ?? this.config.host;
18718
+ if (!host) {
18719
+ throw new Error("Owned space hosting requires a TinyCloud host");
18720
+ }
18721
+ const activation = await (0, import_sdk_core5.activateSessionWithHost)(host, session.delegationHeader);
18722
+ if (activation.success && !activation.skipped?.includes(spaceId)) {
18723
+ return;
18724
+ }
18725
+ if (!activation.success && activation.status !== 404) {
18726
+ throw new Error(
18727
+ `Failed to check owned space ${spaceId}: ${activation.error ?? activation.status}`
18728
+ );
18729
+ }
18730
+ const created = await this.auth.hostOwnedSpace(spaceId);
18731
+ if (!created) {
18732
+ throw new Error(`Failed to create owned space: ${spaceId}`);
18733
+ }
18734
+ await new Promise((resolve) => setTimeout(resolve, 100));
18735
+ const retry = await (0, import_sdk_core5.activateSessionWithHost)(host, session.delegationHeader);
18736
+ if (!retry.success || retry.skipped?.includes(spaceId)) {
18737
+ throw new Error(
18738
+ `Failed to activate session after creating owned space ${spaceId}: ${retry.error ?? "space was skipped"}`
18739
+ );
18740
+ }
18741
+ }
18475
18742
  /**
18476
18743
  * Restore a previously established session from stored delegation data.
18477
18744
  *
@@ -18487,29 +18754,34 @@ var _TinyCloudNode = class _TinyCloudNode {
18487
18754
  this._sql = void 0;
18488
18755
  this._duckdb = void 0;
18489
18756
  this._hooks = void 0;
18757
+ this._vault = void 0;
18758
+ this._baseSecrets = void 0;
18759
+ this._secrets = void 0;
18760
+ this._spaceService = void 0;
18490
18761
  this._serviceContext = void 0;
18762
+ this.runtimePermissionGrants = [];
18491
18763
  if (sessionData.address) {
18492
18764
  this._address = sessionData.address;
18493
18765
  }
18494
18766
  if (sessionData.chainId) {
18495
18767
  this._chainId = sessionData.chainId;
18496
18768
  }
18497
- this._serviceContext = new import_sdk_core4.ServiceContext({
18498
- invoke: this.wasmBindings.invoke,
18499
- invokeAny: this.wasmBindings.invokeAny,
18769
+ this._serviceContext = new import_sdk_core5.ServiceContext({
18770
+ invoke: this.invokeWithRuntimePermissions,
18771
+ invokeAny: this.invokeAnyWithRuntimePermissions,
18500
18772
  fetch: globalThis.fetch.bind(globalThis),
18501
18773
  hosts: [this.config.host]
18502
18774
  });
18503
- this._kv = new import_sdk_core4.KVService({});
18775
+ this._kv = new import_sdk_core5.KVService({});
18504
18776
  this._kv.initialize(this._serviceContext);
18505
18777
  this._serviceContext.registerService("kv", this._kv);
18506
- this._sql = new import_sdk_core4.SQLService({});
18778
+ this._sql = new import_sdk_core5.SQLService({});
18507
18779
  this._sql.initialize(this._serviceContext);
18508
18780
  this._serviceContext.registerService("sql", this._sql);
18509
- this._duckdb = new import_sdk_core4.DuckDbService({});
18781
+ this._duckdb = new import_sdk_core5.DuckDbService({});
18510
18782
  this._duckdb.initialize(this._serviceContext);
18511
18783
  this._serviceContext.registerService("duckdb", this._duckdb);
18512
- this._hooks = new import_sdk_core4.HooksService({});
18784
+ this._hooks = new import_sdk_core5.HooksService({});
18513
18785
  this._hooks.initialize(this._serviceContext);
18514
18786
  this._serviceContext.registerService("hooks", this._hooks);
18515
18787
  const serviceSession = {
@@ -18520,41 +18792,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18520
18792
  jwk: sessionData.jwk
18521
18793
  };
18522
18794
  this._serviceContext.setSession(serviceSession);
18523
- const wasm = this.wasmBindings;
18524
- const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
18525
- vault_encrypt: wasm.vault_encrypt,
18526
- vault_decrypt: wasm.vault_decrypt,
18527
- vault_derive_key: wasm.vault_derive_key,
18528
- vault_x25519_from_seed: wasm.vault_x25519_from_seed,
18529
- vault_x25519_dh: wasm.vault_x25519_dh,
18530
- vault_random_bytes: wasm.vault_random_bytes,
18531
- vault_sha256: wasm.vault_sha256
18532
- });
18533
- const self2 = this;
18534
- this._vault = new import_sdk_core4.DataVaultService({
18535
- spaceId: sessionData.spaceId,
18536
- crypto: vaultCrypto,
18537
- tc: {
18538
- kv: this._kv,
18539
- ensurePublicSpace: async () => {
18540
- try {
18541
- await self2.ensurePublicSpace();
18542
- return { ok: true, data: void 0 };
18543
- } catch (error) {
18544
- return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
18545
- }
18546
- },
18547
- get publicKV() {
18548
- return self2._publicKV ?? self2.tc.publicKV;
18549
- },
18550
- readPublicSpace: (host, spaceId, key2) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key2),
18551
- makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
18552
- did: this.did,
18553
- address: sessionData.address ?? this._address ?? "",
18554
- chainId: sessionData.chainId ?? this._chainId,
18555
- hosts: [this.config.host]
18556
- }
18557
- });
18795
+ this._vault = this.createVaultService(sessionData.spaceId, this._kv);
18558
18796
  this._vault.initialize(this._serviceContext);
18559
18797
  this._serviceContext.registerService("vault", this._vault);
18560
18798
  this.initializeV2Services(serviceSession);
@@ -18589,7 +18827,6 @@ var _TinyCloudNode = class _TinyCloudNode {
18589
18827
  throw new Error("Wallet already connected. Cannot connect another wallet.");
18590
18828
  }
18591
18829
  const prefix = options?.prefix ?? "default";
18592
- const host = this.config.host;
18593
18830
  if (!_TinyCloudNode.nodeDefaults) {
18594
18831
  throw new Error(
18595
18832
  "connectWallet() requires PrivateKeySigner. Use connectSigner() instead, or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
@@ -18604,7 +18841,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18604
18841
  domain: this.siweDomain,
18605
18842
  spacePrefix: prefix,
18606
18843
  sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
18607
- tinycloudHosts: [host],
18844
+ tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18845
+ tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
18846
+ tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
18608
18847
  autoCreateSpace: this.config.autoCreateSpace,
18609
18848
  enablePublicSpace: this.config.enablePublicSpace ?? true,
18610
18849
  spaceCreationHandler: this.config.spaceCreationHandler,
@@ -18614,8 +18853,8 @@ var _TinyCloudNode = class _TinyCloudNode {
18614
18853
  capabilityRequest: this.config.capabilityRequest,
18615
18854
  includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
18616
18855
  });
18617
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18618
- invokeAny: this.wasmBindings.invokeAny
18856
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
18857
+ invokeAny: this.invokeAnyWithRuntimePermissions
18619
18858
  });
18620
18859
  this.config.prefix = prefix;
18621
18860
  }
@@ -18637,7 +18876,6 @@ var _TinyCloudNode = class _TinyCloudNode {
18637
18876
  throw new Error("Signer already connected. Cannot connect another signer.");
18638
18877
  }
18639
18878
  const prefix = options?.prefix ?? "default";
18640
- const host = this.config.host;
18641
18879
  this.signer = signer;
18642
18880
  this.auth = new NodeUserAuthorization({
18643
18881
  signer: this.signer,
@@ -18647,7 +18885,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18647
18885
  domain: this.siweDomain,
18648
18886
  spacePrefix: prefix,
18649
18887
  sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
18650
- tinycloudHosts: [host],
18888
+ tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18889
+ tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
18890
+ tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
18651
18891
  autoCreateSpace: this.config.autoCreateSpace,
18652
18892
  enablePublicSpace: this.config.enablePublicSpace ?? true,
18653
18893
  spaceCreationHandler: this.config.spaceCreationHandler,
@@ -18657,8 +18897,8 @@ var _TinyCloudNode = class _TinyCloudNode {
18657
18897
  capabilityRequest: this.config.capabilityRequest,
18658
18898
  includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
18659
18899
  });
18660
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18661
- invokeAny: this.wasmBindings.invokeAny
18900
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
18901
+ invokeAny: this.invokeAnyWithRuntimePermissions
18662
18902
  });
18663
18903
  this.config.prefix = prefix;
18664
18904
  }
@@ -18671,28 +18911,28 @@ var _TinyCloudNode = class _TinyCloudNode {
18671
18911
  if (!session) {
18672
18912
  return;
18673
18913
  }
18674
- this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
18675
- this._serviceContext = new import_sdk_core4.ServiceContext({
18676
- invoke: this.wasmBindings.invoke,
18677
- invokeAny: this.wasmBindings.invokeAny,
18914
+ this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
18915
+ this._serviceContext = new import_sdk_core5.ServiceContext({
18916
+ invoke: this.invokeWithRuntimePermissions,
18917
+ invokeAny: this.invokeAnyWithRuntimePermissions,
18678
18918
  fetch: globalThis.fetch.bind(globalThis),
18679
18919
  hosts: [this.config.host]
18680
18920
  });
18681
- this._kv = new import_sdk_core4.KVService({});
18921
+ this._kv = new import_sdk_core5.KVService({});
18682
18922
  this._kv.initialize(this._serviceContext);
18683
18923
  this._serviceContext.registerService("kv", this._kv);
18684
18924
  const features = this.nodeFeatures;
18685
18925
  if (features.length === 0 || features.includes("sql")) {
18686
- this._sql = new import_sdk_core4.SQLService({});
18926
+ this._sql = new import_sdk_core5.SQLService({});
18687
18927
  this._sql.initialize(this._serviceContext);
18688
18928
  this._serviceContext.registerService("sql", this._sql);
18689
18929
  }
18690
18930
  if (features.length === 0 || features.includes("duckdb")) {
18691
- this._duckdb = new import_sdk_core4.DuckDbService({});
18931
+ this._duckdb = new import_sdk_core5.DuckDbService({});
18692
18932
  this._duckdb.initialize(this._serviceContext);
18693
18933
  this._serviceContext.registerService("duckdb", this._duckdb);
18694
18934
  }
18695
- this._hooks = new import_sdk_core4.HooksService({});
18935
+ this._hooks = new import_sdk_core5.HooksService({});
18696
18936
  this._hooks.initialize(this._serviceContext);
18697
18937
  this._serviceContext.registerService("hooks", this._hooks);
18698
18938
  const serviceSession = {
@@ -18704,8 +18944,30 @@ var _TinyCloudNode = class _TinyCloudNode {
18704
18944
  };
18705
18945
  this._serviceContext.setSession(serviceSession);
18706
18946
  this.tc.serviceContext.setSession(serviceSession);
18947
+ this._vault = this.createVaultService(session.spaceId, this._kv);
18948
+ this._vault.initialize(this._serviceContext);
18949
+ this._serviceContext.registerService("vault", this._vault);
18950
+ this.initializeV2Services(serviceSession);
18951
+ }
18952
+ createSpaceScopedKVService(spaceId) {
18953
+ const kvService = new import_sdk_core5.KVService({});
18954
+ if (this._serviceContext) {
18955
+ const spaceScopedContext = new import_sdk_core5.ServiceContext({
18956
+ invoke: this._serviceContext.invoke,
18957
+ fetch: this._serviceContext.fetch,
18958
+ hosts: this._serviceContext.hosts
18959
+ });
18960
+ const session = this._serviceContext.session;
18961
+ if (session) {
18962
+ spaceScopedContext.setSession({ ...session, spaceId });
18963
+ }
18964
+ kvService.initialize(spaceScopedContext);
18965
+ }
18966
+ return kvService;
18967
+ }
18968
+ createVaultService(spaceId, kv) {
18707
18969
  const wasm = this.wasmBindings;
18708
- const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
18970
+ const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
18709
18971
  vault_encrypt: wasm.vault_encrypt,
18710
18972
  vault_decrypt: wasm.vault_decrypt,
18711
18973
  vault_derive_key: wasm.vault_derive_key,
@@ -18715,11 +18977,11 @@ var _TinyCloudNode = class _TinyCloudNode {
18715
18977
  vault_sha256: wasm.vault_sha256
18716
18978
  });
18717
18979
  const self2 = this;
18718
- this._vault = new import_sdk_core4.DataVaultService({
18719
- spaceId: session.spaceId,
18980
+ return new import_sdk_core5.DataVaultService({
18981
+ spaceId,
18720
18982
  crypto: vaultCrypto,
18721
18983
  tc: {
18722
- kv: this._kv,
18984
+ kv,
18723
18985
  ensurePublicSpace: async () => {
18724
18986
  try {
18725
18987
  await self2.ensurePublicSpace();
@@ -18731,24 +18993,21 @@ var _TinyCloudNode = class _TinyCloudNode {
18731
18993
  get publicKV() {
18732
18994
  return self2._publicKV ?? self2.tc.publicKV;
18733
18995
  },
18734
- readPublicSpace: (host, spaceId, key2) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key2),
18735
- makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
18996
+ readPublicSpace: (host, targetSpaceId, key2) => import_sdk_core5.TinyCloud.readPublicSpace(host, targetSpaceId, key2),
18997
+ makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
18736
18998
  did: this.did,
18737
- address: this._address,
18999
+ address: this._address ?? "",
18738
19000
  chainId: this._chainId,
18739
19001
  hosts: [this.config.host]
18740
19002
  }
18741
19003
  });
18742
- this._vault.initialize(this._serviceContext);
18743
- this._serviceContext.registerService("vault", this._vault);
18744
- this.initializeV2Services(serviceSession);
18745
19004
  }
18746
19005
  /**
18747
19006
  * Initialize the v2 delegation system services.
18748
19007
  * @internal
18749
19008
  */
18750
19009
  initializeV2Services(serviceSession) {
18751
- this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
19010
+ this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
18752
19011
  const tcSession = this.auth?.tinyCloudSession;
18753
19012
  if (tcSession && this._address) {
18754
19013
  const sessionKey = {
@@ -18822,13 +19081,13 @@ var _TinyCloudNode = class _TinyCloudNode {
18822
19081
  }
18823
19082
  this._capabilityRegistry.registerKey(sessionKey, delegations);
18824
19083
  }
18825
- this._delegationManager = new import_sdk_core4.DelegationManager({
19084
+ this._delegationManager = new import_sdk_core5.DelegationManager({
18826
19085
  hosts: [this.config.host],
18827
19086
  session: serviceSession,
18828
- invoke: this.wasmBindings.invoke,
19087
+ invoke: this.invokeWithRuntimePermissions,
18829
19088
  fetch: globalThis.fetch.bind(globalThis)
18830
19089
  });
18831
- this._spaceService = new import_sdk_core4.SpaceService({
19090
+ this._spaceService = new import_sdk_core5.SpaceService({
18832
19091
  hosts: [this.config.host],
18833
19092
  session: serviceSession,
18834
19093
  invoke: this.wasmBindings.invoke,
@@ -18836,20 +19095,15 @@ var _TinyCloudNode = class _TinyCloudNode {
18836
19095
  capabilityRegistry: this._capabilityRegistry,
18837
19096
  userDid: this.did,
18838
19097
  createKVService: (spaceId) => {
18839
- const kvService = new import_sdk_core4.KVService({});
19098
+ return this.createSpaceScopedKVService(spaceId);
19099
+ },
19100
+ createVaultService: (spaceId) => {
19101
+ const kvService = this.createSpaceScopedKVService(spaceId);
19102
+ const vaultService = this.createVaultService(spaceId, kvService);
18840
19103
  if (this._serviceContext) {
18841
- const spaceScopedContext = new import_sdk_core4.ServiceContext({
18842
- invoke: this._serviceContext.invoke,
18843
- fetch: this._serviceContext.fetch,
18844
- hosts: this._serviceContext.hosts
18845
- });
18846
- const session = this._serviceContext.session;
18847
- if (session) {
18848
- spaceScopedContext.setSession({ ...session, spaceId });
18849
- }
18850
- kvService.initialize(spaceScopedContext);
19104
+ vaultService.initialize(this._serviceContext);
18851
19105
  }
18852
- return kvService;
19106
+ return vaultService;
18853
19107
  },
18854
19108
  // Enable space.delegations.create() via SIWE-based delegation
18855
19109
  createDelegation: async (params) => {
@@ -18990,7 +19244,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18990
19244
  ...prepared,
18991
19245
  signature: signature2
18992
19246
  });
18993
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19247
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
18994
19248
  host,
18995
19249
  delegationSession.delegationHeader
18996
19250
  );
@@ -19057,7 +19311,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19057
19311
  if (!this._sql) {
19058
19312
  const features = this.nodeFeatures;
19059
19313
  if (features.length > 0 && !features.includes("sql")) {
19060
- throw new import_sdk_core4.UnsupportedFeatureError("sql", this.config.host, features);
19314
+ throw new import_sdk_core5.UnsupportedFeatureError("sql", this.config.host, features);
19061
19315
  }
19062
19316
  throw new Error("Not signed in. Call signIn() first.");
19063
19317
  }
@@ -19070,7 +19324,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19070
19324
  if (!this._duckdb) {
19071
19325
  const features = this.nodeFeatures;
19072
19326
  if (features.length > 0 && !features.includes("duckdb")) {
19073
- throw new import_sdk_core4.UnsupportedFeatureError("duckdb", this.config.host, features);
19327
+ throw new import_sdk_core5.UnsupportedFeatureError("duckdb", this.config.host, features);
19074
19328
  }
19075
19329
  throw new Error("Not signed in. Call signIn() first.");
19076
19330
  }
@@ -19086,6 +19340,33 @@ var _TinyCloudNode = class _TinyCloudNode {
19086
19340
  }
19087
19341
  return this._vault;
19088
19342
  }
19343
+ /**
19344
+ * App-facing secrets API backed by the `secrets` space vault.
19345
+ */
19346
+ get secrets() {
19347
+ if (!this._spaceService) {
19348
+ throw new Error("Not signed in. Call signIn() first.");
19349
+ }
19350
+ if (!this._secrets) {
19351
+ this._secrets = new NodeSecretsService({
19352
+ getService: () => this.getBaseSecrets(),
19353
+ getManifest: () => this.manifest,
19354
+ grantPermissions: (additional) => this.grantRuntimePermissions(additional),
19355
+ canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
19356
+ getUnlockSigner: () => this.signer ?? void 0
19357
+ });
19358
+ }
19359
+ return this._secrets;
19360
+ }
19361
+ getBaseSecrets() {
19362
+ if (!this._spaceService) {
19363
+ throw new Error("Not signed in. Call signIn() first.");
19364
+ }
19365
+ if (!this._baseSecrets) {
19366
+ this._baseSecrets = new import_sdk_core5.SecretsService(() => this.space("secrets").vault);
19367
+ }
19368
+ return this._baseSecrets;
19369
+ }
19089
19370
  /**
19090
19371
  * Hooks write stream subscription API.
19091
19372
  */
@@ -19156,6 +19437,171 @@ var _TinyCloudNode = class _TinyCloudNode {
19156
19437
  }
19157
19438
  };
19158
19439
  }
19440
+ /**
19441
+ * Check whether the current session or an approved runtime delegation covers
19442
+ * every requested permission.
19443
+ */
19444
+ hasRuntimePermissions(permissions) {
19445
+ const session = this.auth?.tinyCloudSession;
19446
+ if (!session || !Array.isArray(permissions) || permissions.length === 0) {
19447
+ return false;
19448
+ }
19449
+ const expanded = this.expandPermissionEntries(permissions);
19450
+ if (this.sessionCoversPermissionEntries(session, expanded)) {
19451
+ return true;
19452
+ }
19453
+ return this.findRuntimeGrantsForPermissionEntries(expanded, session).length > 0;
19454
+ }
19455
+ /**
19456
+ * Return installed runtime permission delegations. When `permissions` is
19457
+ * provided, only delegations currently covering those permissions are
19458
+ * returned. Base-session manifest permissions are not represented here.
19459
+ */
19460
+ getRuntimePermissionDelegations(permissions) {
19461
+ this.pruneExpiredRuntimePermissionGrants();
19462
+ if (permissions === void 0) {
19463
+ return this.runtimePermissionGrants.map((grant) => grant.delegation);
19464
+ }
19465
+ const session = this.auth?.tinyCloudSession;
19466
+ if (!session || !Array.isArray(permissions) || permissions.length === 0) {
19467
+ return [];
19468
+ }
19469
+ const expanded = this.expandPermissionEntries(permissions);
19470
+ return this.findRuntimeGrantsForPermissionEntries(expanded, session).map(
19471
+ (grant) => grant.delegation
19472
+ );
19473
+ }
19474
+ /**
19475
+ * Install a portable runtime permission delegation into this SDK instance so
19476
+ * matching service calls and downstream `delegateTo()` calls can use it.
19477
+ */
19478
+ async useRuntimeDelegation(delegation) {
19479
+ const session = this.auth?.tinyCloudSession;
19480
+ if (!session) {
19481
+ throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19482
+ }
19483
+ if (delegation.expiry.getTime() <= Date.now()) {
19484
+ throw new import_sdk_core5.SessionExpiredError(delegation.expiry);
19485
+ }
19486
+ const expectedDids = /* @__PURE__ */ new Set([session.verificationMethod, this.sessionDid]);
19487
+ if (!expectedDids.has(delegation.delegateDID)) {
19488
+ throw new Error(
19489
+ `Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
19490
+ );
19491
+ }
19492
+ const targetHost = delegation.host ?? this.config.host;
19493
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19494
+ targetHost,
19495
+ delegation.delegationHeader
19496
+ );
19497
+ if (!activateResult.success) {
19498
+ throw new Error(
19499
+ `Failed to activate runtime permission delegation: ${activateResult.error}`
19500
+ );
19501
+ }
19502
+ this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
19503
+ (grant) => grant.delegation.cid !== delegation.cid
19504
+ );
19505
+ this.runtimePermissionGrants.push(
19506
+ this.runtimeGrantFromDelegation(delegation, session)
19507
+ );
19508
+ }
19509
+ /**
19510
+ * Store additional permissions as narrow delegations to the current session
19511
+ * key. Future service invocations automatically use a stored delegation when
19512
+ * its `(space, service, path, action)` covers the request.
19513
+ */
19514
+ async grantRuntimePermissions(permissions, options) {
19515
+ if (!Array.isArray(permissions) || permissions.length === 0) {
19516
+ throw new Error("grantRuntimePermissions requires a non-empty permissions array");
19517
+ }
19518
+ const session = this.auth?.tinyCloudSession;
19519
+ if (!session) {
19520
+ throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19521
+ }
19522
+ const sessionExpiry = extractSiweExpiration(session.siwe);
19523
+ if (sessionExpiry !== void 0) {
19524
+ const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
19525
+ if (sessionExpiry.getTime() <= Date.now() + marginMs) {
19526
+ throw new import_sdk_core5.SessionExpiredError(sessionExpiry);
19527
+ }
19528
+ }
19529
+ const expanded = this.expandPermissionEntries(permissions);
19530
+ if (this.sessionCoversPermissionEntries(session, expanded)) {
19531
+ return [];
19532
+ }
19533
+ const existingGrants = this.findRuntimeGrantsForPermissionEntries(expanded, session);
19534
+ if (existingGrants.length > 0) {
19535
+ return existingGrants.map((grant) => grant.delegation);
19536
+ }
19537
+ if (!this.signer) {
19538
+ throw new Error(
19539
+ "grantRuntimePermissions requires wallet mode with a signer or privateKey."
19540
+ );
19541
+ }
19542
+ const bySpace = /* @__PURE__ */ new Map();
19543
+ for (const entry of expanded) {
19544
+ const spaceId = this.resolvePermissionSpace(entry.space, session);
19545
+ const current = bySpace.get(spaceId) ?? [];
19546
+ current.push(entry);
19547
+ bySpace.set(spaceId, current);
19548
+ }
19549
+ const now = /* @__PURE__ */ new Date();
19550
+ const requestedExpiryMs = resolveExpiryMs(options?.expiry);
19551
+ let expiresAt = new Date(now.getTime() + requestedExpiryMs);
19552
+ if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
19553
+ expiresAt = sessionExpiry;
19554
+ }
19555
+ const delegations = [];
19556
+ for (const [spaceId, entries] of bySpace) {
19557
+ const abilities = this.permissionsToAbilities(entries);
19558
+ const prepared = this.wasmBindings.prepareSession({
19559
+ abilities,
19560
+ address: this.wasmBindings.ensureEip55(session.address),
19561
+ chainId: session.chainId,
19562
+ domain: this.siweDomain,
19563
+ issuedAt: now.toISOString(),
19564
+ expirationTime: expiresAt.toISOString(),
19565
+ spaceId,
19566
+ jwk: session.jwk
19567
+ });
19568
+ const signature2 = await this.signer.signMessage(prepared.siwe);
19569
+ const delegatedSession = this.wasmBindings.completeSessionSetup({
19570
+ ...prepared,
19571
+ signature: signature2
19572
+ });
19573
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19574
+ this.config.host,
19575
+ delegatedSession.delegationHeader
19576
+ );
19577
+ if (!activateResult.success) {
19578
+ throw new Error(
19579
+ `Failed to activate runtime permission delegation: ${activateResult.error}`
19580
+ );
19581
+ }
19582
+ const delegation = this.runtimeDelegationFromSession(
19583
+ delegatedSession,
19584
+ entries,
19585
+ spaceId,
19586
+ session,
19587
+ expiresAt
19588
+ );
19589
+ this.runtimePermissionGrants.push({
19590
+ session: {
19591
+ delegationHeader: delegatedSession.delegationHeader,
19592
+ delegationCid: delegatedSession.delegationCid,
19593
+ spaceId,
19594
+ verificationMethod: session.verificationMethod,
19595
+ jwk: session.jwk
19596
+ },
19597
+ delegation,
19598
+ operations: this.permissionOperations(entries, spaceId),
19599
+ expiresAt
19600
+ });
19601
+ delegations.push(delegation);
19602
+ }
19603
+ return delegations;
19604
+ }
19159
19605
  /**
19160
19606
  * Get the DelegationManager for delegation CRUD operations.
19161
19607
  *
@@ -19224,6 +19670,12 @@ var _TinyCloudNode = class _TinyCloudNode {
19224
19670
  get spaceService() {
19225
19671
  return this.spaces;
19226
19672
  }
19673
+ /**
19674
+ * Get a Space object by short name or full URI.
19675
+ */
19676
+ space(nameOrUri) {
19677
+ return this.spaces.get(nameOrUri);
19678
+ }
19227
19679
  /**
19228
19680
  * Get the SharingService for creating and receiving v2 sharing links.
19229
19681
  *
@@ -19309,7 +19761,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19309
19761
  ...prepared,
19310
19762
  signature: signature2
19311
19763
  });
19312
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19764
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19313
19765
  this.config.host,
19314
19766
  delegationSession.delegationHeader
19315
19767
  );
@@ -19336,9 +19788,9 @@ var _TinyCloudNode = class _TinyCloudNode {
19336
19788
  }]);
19337
19789
  }
19338
19790
  if (this._serviceContext) {
19339
- const publicKV = new import_sdk_core4.KVService({ prefix: "" });
19340
- const publicContext = new import_sdk_core4.ServiceContext({
19341
- invoke: this.wasmBindings.invoke,
19791
+ const publicKV = new import_sdk_core5.KVService({ prefix: "" });
19792
+ const publicContext = new import_sdk_core5.ServiceContext({
19793
+ invoke: this.invokeWithRuntimePermissions,
19342
19794
  fetch: this._serviceContext.fetch,
19343
19795
  hosts: this._serviceContext.hosts
19344
19796
  });
@@ -19426,8 +19878,9 @@ var _TinyCloudNode = class _TinyCloudNode {
19426
19878
  * Issue a delegation using the capability-chain flow.
19427
19879
  *
19428
19880
  * When every requested permission is a subset of the current
19429
- * session's recap, the delegation is signed by the session key via
19430
- * WASM no wallet prompt. When at least one is NOT derivable, a
19881
+ * session's recap, or of one installed runtime permission delegation,
19882
+ * the delegation is signed by the session key via WASM no wallet
19883
+ * prompt. When at least one is NOT derivable, a
19431
19884
  * {@link PermissionNotInManifestError} is raised (carrying the
19432
19885
  * missing entries) so the caller can trigger an escalation flow
19433
19886
  * (e.g. `TinyCloudWeb.requestPermissions`). Passing
@@ -19462,14 +19915,14 @@ var _TinyCloudNode = class _TinyCloudNode {
19462
19915
  async delegateTo(did, permissions, options) {
19463
19916
  const session = this.auth?.tinyCloudSession;
19464
19917
  if (!session) {
19465
- throw new import_sdk_core4.SessionExpiredError(/* @__PURE__ */ new Date(0));
19918
+ throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19466
19919
  }
19467
19920
  const sessionExpiry = extractSiweExpiration(session.siwe);
19468
19921
  if (sessionExpiry !== void 0) {
19469
19922
  const now2 = Date.now();
19470
19923
  const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
19471
19924
  if (sessionExpiry.getTime() <= now2 + marginMs) {
19472
- throw new import_sdk_core4.SessionExpiredError(sessionExpiry);
19925
+ throw new import_sdk_core5.SessionExpiredError(sessionExpiry);
19473
19926
  }
19474
19927
  }
19475
19928
  if (!Array.isArray(permissions) || permissions.length === 0) {
@@ -19477,10 +19930,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19477
19930
  "delegateTo requires a non-empty permissions array"
19478
19931
  );
19479
19932
  }
19480
- const expandedEntries = permissions.map((entry) => ({
19481
- ...entry,
19482
- actions: (0, import_sdk_core4.expandActionShortNames)(entry.service, entry.actions)
19483
- }));
19933
+ const expandedEntries = this.expandPermissionEntries(permissions);
19484
19934
  const now = /* @__PURE__ */ new Date();
19485
19935
  const expiryMs = resolveExpiryMs(options?.expiry);
19486
19936
  const expirationTime = new Date(now.getTime() + expiryMs);
@@ -19501,13 +19951,30 @@ var _TinyCloudNode = class _TinyCloudNode {
19501
19951
  );
19502
19952
  return { delegation: delegation2, prompted: true };
19503
19953
  }
19504
- const granted = (0, import_sdk_core4.parseRecapCapabilities)(
19954
+ const granted = (0, import_sdk_core5.parseRecapCapabilities)(
19505
19955
  (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
19506
19956
  session.siwe
19507
19957
  );
19508
- const { subset, missing } = (0, import_sdk_core4.isCapabilitySubset)(expandedEntries, granted);
19958
+ const { subset, missing } = (0, import_sdk_core5.isCapabilitySubset)(expandedEntries, granted);
19509
19959
  if (!subset) {
19510
- throw new import_sdk_core4.PermissionNotInManifestError(missing, granted);
19960
+ const runtimeGrant = this.findGrantForOperations(
19961
+ this.permissionEntriesToOperations(expandedEntries, session)
19962
+ );
19963
+ if (runtimeGrant) {
19964
+ const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
19965
+ if (runtimeGrant.expiresAt.getTime() <= Date.now() + marginMs) {
19966
+ throw new import_sdk_core5.SessionExpiredError(runtimeGrant.expiresAt);
19967
+ }
19968
+ const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
19969
+ const delegation2 = await this.createDelegationViaRuntimeGrant(
19970
+ did,
19971
+ expandedEntries,
19972
+ runtimeExpiration,
19973
+ runtimeGrant
19974
+ );
19975
+ return { delegation: delegation2, prompted: false };
19976
+ }
19977
+ throw new import_sdk_core5.PermissionNotInManifestError(missing, granted);
19511
19978
  }
19512
19979
  const delegation = await this.createDelegationViaWasmPath(
19513
19980
  did,
@@ -19587,7 +20054,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19587
20054
  const spaceId = [...resolvedSpaces][0];
19588
20055
  const abilities = {};
19589
20056
  for (const entry of entries) {
19590
- const shortService = import_sdk_core4.SERVICE_LONG_TO_SHORT[entry.service];
20057
+ const shortService = import_sdk_core5.SERVICE_LONG_TO_SHORT[entry.service];
19591
20058
  if (shortService === void 0) {
19592
20059
  throw new Error(
19593
20060
  `delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
@@ -19627,7 +20094,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19627
20094
  });
19628
20095
  const primary = result.resources[0];
19629
20096
  const delegationHeader = { Authorization: result.delegation };
19630
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
20097
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19631
20098
  this.config.host,
19632
20099
  delegationHeader
19633
20100
  );
@@ -19651,6 +20118,41 @@ var _TinyCloudNode = class _TinyCloudNode {
19651
20118
  host: this.config.host
19652
20119
  };
19653
20120
  }
20121
+ async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
20122
+ const result = this.createDelegationWrapper({
20123
+ session: grant.session,
20124
+ delegateDID: did,
20125
+ spaceId: grant.session.spaceId,
20126
+ abilities: this.permissionsToAbilities(entries),
20127
+ expirationSecs: Math.floor(expirationTime.getTime() / 1e3)
20128
+ });
20129
+ const primary = result.resources[0];
20130
+ const delegationHeader = { Authorization: result.delegation };
20131
+ const targetHost = grant.delegation.host ?? this.config.host;
20132
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
20133
+ targetHost,
20134
+ delegationHeader
20135
+ );
20136
+ if (!activateResult.success) {
20137
+ throw new Error(
20138
+ `Failed to activate delegation with host: ${activateResult.error}`
20139
+ );
20140
+ }
20141
+ return {
20142
+ cid: result.cid,
20143
+ delegationHeader,
20144
+ spaceId: grant.session.spaceId,
20145
+ path: primary.path,
20146
+ actions: primary.actions,
20147
+ resources: result.resources,
20148
+ disableSubDelegation: false,
20149
+ expiry: result.expiry,
20150
+ delegateDID: did,
20151
+ ownerAddress: grant.delegation.ownerAddress,
20152
+ chainId: grant.delegation.chainId,
20153
+ host: targetHost
20154
+ };
20155
+ }
19654
20156
  resolvePermissionSpace(space, session) {
19655
20157
  if (space === void 0) {
19656
20158
  return this.wasmBindings.makeSpaceId(
@@ -19667,6 +20169,220 @@ var _TinyCloudNode = class _TinyCloudNode {
19667
20169
  }
19668
20170
  return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
19669
20171
  }
20172
+ expandPermissionEntries(permissions) {
20173
+ return (0, import_sdk_core5.expandPermissionEntries)(permissions);
20174
+ }
20175
+ shortServiceName(service) {
20176
+ const short = import_sdk_core5.SERVICE_LONG_TO_SHORT[service];
20177
+ if (short === void 0) {
20178
+ throw new Error(
20179
+ `unknown service '${service}' \u2014 no short-form mapping`
20180
+ );
20181
+ }
20182
+ return short;
20183
+ }
20184
+ permissionsToAbilities(entries) {
20185
+ const abilities = {};
20186
+ for (const entry of entries) {
20187
+ const service = this.shortServiceName(entry.service);
20188
+ abilities[service] ?? (abilities[service] = {});
20189
+ const existing = abilities[service][entry.path] ?? [];
20190
+ const seen = new Set(existing);
20191
+ for (const action of entry.actions) {
20192
+ if (!seen.has(action)) {
20193
+ existing.push(action);
20194
+ seen.add(action);
20195
+ }
20196
+ }
20197
+ abilities[service][entry.path] = existing;
20198
+ }
20199
+ return abilities;
20200
+ }
20201
+ permissionOperations(entries, spaceId) {
20202
+ return entries.flatMap((entry) => {
20203
+ const service = this.shortServiceName(entry.service);
20204
+ return entry.actions.map((action) => ({
20205
+ spaceId,
20206
+ service,
20207
+ path: entry.path,
20208
+ action
20209
+ }));
20210
+ });
20211
+ }
20212
+ sessionCoversPermissionEntries(session, entries) {
20213
+ try {
20214
+ const granted = (0, import_sdk_core5.parseRecapCapabilities)(
20215
+ (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
20216
+ session.siwe
20217
+ );
20218
+ return (0, import_sdk_core5.isCapabilitySubset)(entries, granted).subset;
20219
+ } catch {
20220
+ return false;
20221
+ }
20222
+ }
20223
+ permissionEntriesToOperations(entries, session) {
20224
+ return entries.flatMap((entry) => {
20225
+ const spaceId = this.resolvePermissionSpace(entry.space, session);
20226
+ const service = this.shortServiceName(entry.service);
20227
+ return entry.actions.map((action) => ({
20228
+ spaceId,
20229
+ service,
20230
+ path: entry.path,
20231
+ action
20232
+ }));
20233
+ });
20234
+ }
20235
+ findRuntimeGrantsForPermissionEntries(entries, session) {
20236
+ const grants = [];
20237
+ const operations = this.permissionEntriesToOperations(entries, session);
20238
+ if (operations.length === 0) {
20239
+ return grants;
20240
+ }
20241
+ for (const operation of operations) {
20242
+ const grant = this.findGrantForOperation(operation);
20243
+ if (!grant) {
20244
+ return [];
20245
+ }
20246
+ if (!grants.includes(grant)) {
20247
+ grants.push(grant);
20248
+ }
20249
+ }
20250
+ return grants;
20251
+ }
20252
+ runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
20253
+ const resources = this.delegatedResourcesForEntries(entries, spaceId);
20254
+ const primary = resources[0];
20255
+ return {
20256
+ cid: delegatedSession.delegationCid,
20257
+ delegationHeader: delegatedSession.delegationHeader,
20258
+ spaceId,
20259
+ path: primary.path,
20260
+ actions: primary.actions,
20261
+ resources,
20262
+ disableSubDelegation: false,
20263
+ expiry: expiresAt,
20264
+ delegateDID: session.verificationMethod,
20265
+ ownerAddress: session.address,
20266
+ chainId: session.chainId,
20267
+ host: this.config.host
20268
+ };
20269
+ }
20270
+ runtimeGrantFromDelegation(delegation, session) {
20271
+ const operations = this.operationsFromDelegation(delegation);
20272
+ return {
20273
+ session: {
20274
+ delegationHeader: delegation.delegationHeader,
20275
+ delegationCid: delegation.cid,
20276
+ spaceId: delegation.spaceId,
20277
+ verificationMethod: session.verificationMethod,
20278
+ jwk: session.jwk
20279
+ },
20280
+ delegation,
20281
+ operations,
20282
+ expiresAt: delegation.expiry
20283
+ };
20284
+ }
20285
+ delegatedResourcesForEntries(entries, spaceId) {
20286
+ return entries.map((entry) => ({
20287
+ service: this.shortServiceName(entry.service),
20288
+ space: spaceId,
20289
+ path: entry.path,
20290
+ actions: [...entry.actions]
20291
+ }));
20292
+ }
20293
+ operationsFromDelegation(delegation) {
20294
+ const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
20295
+ return resources.flatMap(
20296
+ (resource) => resource.actions.map((action) => ({
20297
+ spaceId: resource.space,
20298
+ service: this.invocationServiceName(resource.service),
20299
+ path: resource.path,
20300
+ action
20301
+ }))
20302
+ );
20303
+ }
20304
+ flatDelegationResources(delegation) {
20305
+ const byService = /* @__PURE__ */ new Map();
20306
+ for (const action of delegation.actions) {
20307
+ const service = this.shortServiceName(action.split("/")[0]);
20308
+ const actions = byService.get(service) ?? [];
20309
+ actions.push(action);
20310
+ byService.set(service, actions);
20311
+ }
20312
+ return [...byService.entries()].map(([service, actions]) => ({
20313
+ service,
20314
+ space: delegation.spaceId,
20315
+ path: delegation.path,
20316
+ actions
20317
+ }));
20318
+ }
20319
+ selectInvocationSession(fallback, service, path, action) {
20320
+ const grant = this.findGrantForOperation({
20321
+ spaceId: fallback.spaceId,
20322
+ service: this.invocationServiceName(service),
20323
+ path,
20324
+ action
20325
+ });
20326
+ return grant?.session ?? fallback;
20327
+ }
20328
+ findGrantForOperations(operations) {
20329
+ if (operations.length === 0) {
20330
+ return void 0;
20331
+ }
20332
+ this.pruneExpiredRuntimePermissionGrants();
20333
+ return this.runtimePermissionGrants.find((grant) => {
20334
+ return operations.every(
20335
+ (operation) => grant.operations.some(
20336
+ (granted) => this.operationCovers(granted, operation)
20337
+ )
20338
+ );
20339
+ });
20340
+ }
20341
+ findGrantForOperation(operation) {
20342
+ return this.findGrantForOperations([operation]);
20343
+ }
20344
+ pruneExpiredRuntimePermissionGrants() {
20345
+ const now = Date.now();
20346
+ this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
20347
+ (grant) => grant.expiresAt.getTime() > now
20348
+ );
20349
+ }
20350
+ operationCovers(granted, requested) {
20351
+ return granted.spaceId === requested.spaceId && granted.service === requested.service && this.actionContains(granted.action, requested.action) && this.pathContains(granted.path, requested.path);
20352
+ }
20353
+ actionContains(grantedAction, requestedAction) {
20354
+ if (grantedAction === requestedAction) {
20355
+ return true;
20356
+ }
20357
+ if (grantedAction.endsWith("/*")) {
20358
+ const prefix = grantedAction.slice(0, -2);
20359
+ return requestedAction.startsWith(`${prefix}/`);
20360
+ }
20361
+ return false;
20362
+ }
20363
+ invocationServiceName(service) {
20364
+ return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
20365
+ }
20366
+ pathContains(grantedPath, requestedPath) {
20367
+ if (grantedPath === "" || grantedPath === "/") {
20368
+ return true;
20369
+ }
20370
+ if (grantedPath.endsWith("/**")) {
20371
+ return requestedPath.startsWith(grantedPath.slice(0, -3));
20372
+ }
20373
+ if (grantedPath.endsWith("/*")) {
20374
+ const prefix = grantedPath.slice(0, -2);
20375
+ if (!requestedPath.startsWith(prefix)) {
20376
+ return false;
20377
+ }
20378
+ const remainder = requestedPath.slice(prefix.length);
20379
+ return !remainder.includes("/") || remainder === "/";
20380
+ }
20381
+ if (grantedPath.endsWith("/")) {
20382
+ return requestedPath.startsWith(grantedPath);
20383
+ }
20384
+ return grantedPath === requestedPath;
20385
+ }
19670
20386
  /**
19671
20387
  * Issue a delegation via the legacy wallet-signed SIWE path for a single
19672
20388
  * {@link PermissionEntry}. Shares the implementation with the public
@@ -19723,7 +20439,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19723
20439
  );
19724
20440
  return result.delegation;
19725
20441
  } catch (err) {
19726
- if (err instanceof import_sdk_core4.PermissionNotInManifestError) {
20442
+ if (err instanceof import_sdk_core5.PermissionNotInManifestError) {
19727
20443
  } else {
19728
20444
  throw err;
19729
20445
  }
@@ -19780,7 +20496,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19780
20496
  ...prepared,
19781
20497
  signature: signature2
19782
20498
  });
19783
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
20499
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19784
20500
  this.config.host,
19785
20501
  delegationSession.delegationHeader
19786
20502
  );
@@ -19802,7 +20518,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19802
20518
  };
19803
20519
  const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
19804
20520
  if (hasKvActions && params.includePublicSpace !== false) {
19805
- const publicSpaceId = (0, import_sdk_core4.makePublicSpaceId)(
20521
+ const publicSpaceId = (0, import_sdk_core5.makePublicSpaceId)(
19806
20522
  this.wasmBindings.ensureEip55(session.address),
19807
20523
  session.chainId
19808
20524
  );
@@ -19825,7 +20541,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19825
20541
  ...publicPrepared,
19826
20542
  signature: publicSignature
19827
20543
  });
19828
- const publicActivateResult = await (0, import_sdk_core4.activateSessionWithHost)(
20544
+ const publicActivateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19829
20545
  this.config.host,
19830
20546
  publicSession.delegationHeader
19831
20547
  );
@@ -19924,7 +20640,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19924
20640
  ...prepared,
19925
20641
  signature: signature2
19926
20642
  });
19927
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
20643
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
19928
20644
  targetHost,
19929
20645
  invokerSession.delegationHeader
19930
20646
  );
@@ -20013,7 +20729,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20013
20729
  ...prepared,
20014
20730
  signature: signature2
20015
20731
  });
20016
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
20732
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
20017
20733
  targetHost,
20018
20734
  subDelegationSession.delegationHeader
20019
20735
  );
@@ -20055,11 +20771,11 @@ TinyCloudNode.registerNodeDefaults({
20055
20771
  });
20056
20772
 
20057
20773
  // src/index.ts
20058
- var import_sdk_core6 = require("@tinycloud/sdk-core");
20059
20774
  var import_sdk_core7 = require("@tinycloud/sdk-core");
20775
+ var import_sdk_core8 = require("@tinycloud/sdk-core");
20060
20776
 
20061
20777
  // src/storage/FileSessionStorage.ts
20062
- var import_sdk_core5 = require("@tinycloud/sdk-core");
20778
+ var import_sdk_core6 = require("@tinycloud/sdk-core");
20063
20779
  var import_fs = require("fs");
20064
20780
  var import_path = require("path");
20065
20781
  var FileSessionStorage = class {
@@ -20114,7 +20830,7 @@ var FileSessionStorage = class {
20114
20830
  try {
20115
20831
  const data = (0, import_fs.readFileSync)(filePath, "utf-8");
20116
20832
  const parsed = JSON.parse(data);
20117
- const validation = (0, import_sdk_core5.validatePersistedSessionData)(parsed);
20833
+ const validation = (0, import_sdk_core6.validatePersistedSessionData)(parsed);
20118
20834
  if (!validation.ok) {
20119
20835
  console.warn(`Invalid session data for ${address}:`, validation.error.message);
20120
20836
  (0, import_fs.unlinkSync)(filePath);
@@ -20179,7 +20895,7 @@ var FileSessionStorage = class {
20179
20895
  };
20180
20896
 
20181
20897
  // src/index.ts
20182
- var import_sdk_core8 = require("@tinycloud/sdk-core");
20898
+ var import_sdk_core9 = require("@tinycloud/sdk-core");
20183
20899
 
20184
20900
  // src/delegation.ts
20185
20901
  function serializeDelegation(delegation) {
@@ -20198,7 +20914,6 @@ function deserializeDelegation(data) {
20198
20914
  }
20199
20915
 
20200
20916
  // src/index.ts
20201
- var import_sdk_core9 = require("@tinycloud/sdk-core");
20202
20917
  var import_sdk_core10 = require("@tinycloud/sdk-core");
20203
20918
  var import_sdk_core11 = require("@tinycloud/sdk-core");
20204
20919
  var import_sdk_core12 = require("@tinycloud/sdk-core");
@@ -20208,6 +20923,7 @@ var import_sdk_core15 = require("@tinycloud/sdk-core");
20208
20923
  var import_sdk_core16 = require("@tinycloud/sdk-core");
20209
20924
  var import_sdk_core17 = require("@tinycloud/sdk-core");
20210
20925
  var import_sdk_core18 = require("@tinycloud/sdk-core");
20926
+ var import_sdk_core19 = require("@tinycloud/sdk-core");
20211
20927
  // Annotate the CommonJS export names for ESM import in node:
20212
20928
  0 && (module.exports = {
20213
20929
  ACCOUNT_REGISTRY_PATH,
@@ -20236,8 +20952,10 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
20236
20952
  PrefixedKVService,
20237
20953
  PrivateKeySigner,
20238
20954
  ProtocolMismatchError,
20955
+ SECRET_NAME_RE,
20239
20956
  SQLAction,
20240
20957
  SQLService,
20958
+ SecretsService,
20241
20959
  ServiceContext,
20242
20960
  SessionExpiredError,
20243
20961
  SharingService,
@@ -20248,11 +20966,13 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
20248
20966
  TinyCloud,
20249
20967
  TinyCloudNode,
20250
20968
  UnsupportedFeatureError,
20969
+ VAULT_PERMISSION_SERVICE,
20251
20970
  VaultHeaders,
20252
20971
  VaultPublicSpaceKVActions,
20253
20972
  VersionCheckError,
20254
20973
  WasmKeyProvider,
20255
20974
  buildSpaceUri,
20975
+ canonicalizeSecretScope,
20256
20976
  checkNodeInfo,
20257
20977
  composeManifestRequest,
20258
20978
  createCapabilityKeyRegistry,
@@ -20264,12 +20984,15 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
20264
20984
  defaultSpaceCreationHandler,
20265
20985
  deserializeDelegation,
20266
20986
  expandActionShortNames,
20987
+ expandPermissionEntries,
20988
+ expandPermissionEntry,
20267
20989
  isCapabilitySubset,
20268
20990
  loadManifest,
20269
20991
  makePublicSpaceId,
20270
20992
  parseExpiry,
20271
20993
  parseSpaceUri,
20272
20994
  resolveManifest,
20995
+ resolveSecretPath,
20273
20996
  resourceCapabilitiesToSpaceAbilitiesMap,
20274
20997
  serializeDelegation,
20275
20998
  validateManifest