@tinycloud/node-sdk 2.2.0-beta.8 → 2.2.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/index.cjs CHANGED
@@ -17028,67 +17028,115 @@ __export(index_exports, {
17028
17028
  ACCOUNT_REGISTRY_PATH: () => import_sdk_core9.ACCOUNT_REGISTRY_PATH,
17029
17029
  ACCOUNT_REGISTRY_SPACE: () => import_sdk_core9.ACCOUNT_REGISTRY_SPACE,
17030
17030
  AutoApproveSpaceCreationHandler: () => import_sdk_core8.AutoApproveSpaceCreationHandler,
17031
- CapabilityKeyRegistry: () => import_sdk_core16.CapabilityKeyRegistry,
17032
- CapabilityKeyRegistryErrorCodes: () => import_sdk_core16.CapabilityKeyRegistryErrorCodes,
17031
+ CapabilityKeyRegistry: () => import_sdk_core17.CapabilityKeyRegistry,
17032
+ CapabilityKeyRegistryErrorCodes: () => import_sdk_core17.CapabilityKeyRegistryErrorCodes,
17033
+ DECRYPT_ACTION: () => import_sdk_core14.DECRYPT_ACTION,
17034
+ DECRYPT_FACT_TYPE: () => import_sdk_core14.DECRYPT_FACT_TYPE,
17035
+ DECRYPT_RESULT_TYPE: () => import_sdk_core14.DECRYPT_RESULT_TYPE,
17036
+ DEFAULT_ENCRYPTION_ALG: () => import_sdk_core14.DEFAULT_ENCRYPTION_ALG,
17037
+ DEFAULT_KEY_VERSION: () => import_sdk_core14.DEFAULT_KEY_VERSION,
17033
17038
  DEFAULT_MANIFEST_SPACE: () => import_sdk_core9.DEFAULT_MANIFEST_SPACE,
17034
17039
  DEFAULT_MANIFEST_VERSION: () => import_sdk_core9.DEFAULT_MANIFEST_VERSION,
17040
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core10.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
17035
17041
  DataVaultService: () => import_sdk_core13.DataVaultService,
17036
17042
  DatabaseHandle: () => import_sdk_core11.DatabaseHandle,
17037
17043
  DelegatedAccess: () => DelegatedAccess,
17038
- DelegationErrorCodes: () => import_sdk_core15.DelegationErrorCodes,
17039
- DelegationManager: () => import_sdk_core15.DelegationManager,
17044
+ DelegationErrorCodes: () => import_sdk_core16.DelegationErrorCodes,
17045
+ DelegationManager: () => import_sdk_core16.DelegationManager,
17040
17046
  DuckDbAction: () => import_sdk_core12.DuckDbAction,
17041
17047
  DuckDbDatabaseHandle: () => import_sdk_core12.DuckDbDatabaseHandle,
17042
17048
  DuckDbService: () => import_sdk_core12.DuckDbService,
17049
+ ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_core14.ENCRYPTION_NETWORK_URN_PREFIX,
17050
+ ENCRYPTION_SERVICE: () => import_sdk_core14.ENCRYPTION_SERVICE,
17051
+ ENCRYPTION_SERVICE_SHORT: () => import_sdk_core14.ENCRYPTION_SERVICE_SHORT,
17052
+ ENVELOPE_VERSION: () => import_sdk_core14.ENVELOPE_VERSION,
17053
+ EncryptionService: () => import_sdk_core14.EncryptionService,
17043
17054
  FileSessionStorage: () => FileSessionStorage,
17044
- HooksService: () => import_sdk_core14.HooksService,
17055
+ HooksService: () => import_sdk_core15.HooksService,
17045
17056
  KVService: () => import_sdk_core10.KVService,
17046
17057
  ManifestValidationError: () => import_sdk_core9.ManifestValidationError,
17047
17058
  MemorySessionStorage: () => MemorySessionStorage,
17059
+ NETWORK_NAME_PATTERN: () => import_sdk_core14.NETWORK_NAME_PATTERN,
17060
+ NetworkIdError: () => import_sdk_core14.NetworkIdError,
17048
17061
  NodeUserAuthorization: () => NodeUserAuthorization,
17049
17062
  NodeWasmBindings: () => NodeWasmBindings,
17050
17063
  PermissionNotInManifestError: () => import_sdk_core9.PermissionNotInManifestError,
17051
17064
  PrefixedKVService: () => import_sdk_core10.PrefixedKVService,
17052
17065
  PrivateKeySigner: () => PrivateKeySigner,
17053
- ProtocolMismatchError: () => import_sdk_core18.ProtocolMismatchError,
17066
+ ProtocolMismatchError: () => import_sdk_core19.ProtocolMismatchError,
17067
+ SECRET_NAME_RE: () => import_sdk_core13.SECRET_NAME_RE,
17054
17068
  SQLAction: () => import_sdk_core11.SQLAction,
17055
17069
  SQLService: () => import_sdk_core11.SQLService,
17056
17070
  SecretsService: () => import_sdk_core13.SecretsService,
17057
- ServiceContext: () => import_sdk_core19.ServiceContext,
17071
+ ServiceContext: () => import_sdk_core20.ServiceContext,
17058
17072
  SessionExpiredError: () => import_sdk_core9.SessionExpiredError,
17059
- SharingService: () => import_sdk_core15.SharingService,
17073
+ SharingService: () => import_sdk_core16.SharingService,
17060
17074
  SilentNotificationHandler: () => import_sdk_core8.SilentNotificationHandler,
17061
- Space: () => import_sdk_core17.Space,
17062
- SpaceErrorCodes: () => import_sdk_core17.SpaceErrorCodes,
17063
- SpaceService: () => import_sdk_core17.SpaceService,
17075
+ Space: () => import_sdk_core18.Space,
17076
+ SpaceErrorCodes: () => import_sdk_core18.SpaceErrorCodes,
17077
+ SpaceService: () => import_sdk_core18.SpaceService,
17064
17078
  TinyCloud: () => import_sdk_core7.TinyCloud,
17065
17079
  TinyCloudNode: () => TinyCloudNode,
17066
- UnsupportedFeatureError: () => import_sdk_core18.UnsupportedFeatureError,
17080
+ UnsupportedFeatureError: () => import_sdk_core19.UnsupportedFeatureError,
17081
+ VAULT_PERMISSION_SERVICE: () => import_sdk_core9.VAULT_PERMISSION_SERVICE,
17067
17082
  VaultHeaders: () => import_sdk_core13.VaultHeaders,
17068
17083
  VaultPublicSpaceKVActions: () => import_sdk_core13.VaultPublicSpaceKVActions,
17069
- VersionCheckError: () => import_sdk_core18.VersionCheckError,
17084
+ VersionCheckError: () => import_sdk_core19.VersionCheckError,
17070
17085
  WasmKeyProvider: () => WasmKeyProvider,
17071
- buildSpaceUri: () => import_sdk_core17.buildSpaceUri,
17072
- checkNodeInfo: () => import_sdk_core18.checkNodeInfo,
17086
+ buildCanonicalDecryptRequest: () => import_sdk_core14.buildCanonicalDecryptRequest,
17087
+ buildDecryptAttenuation: () => import_sdk_core14.buildDecryptAttenuation,
17088
+ buildDecryptFacts: () => import_sdk_core14.buildDecryptFacts,
17089
+ buildDecryptInvocation: () => import_sdk_core14.buildDecryptInvocation,
17090
+ buildNetworkId: () => import_sdk_core14.buildNetworkId,
17091
+ buildSpaceUri: () => import_sdk_core18.buildSpaceUri,
17092
+ canonicalHashHex: () => import_sdk_core14.canonicalHashHex,
17093
+ canonicalSignedResponse: () => import_sdk_core14.canonicalSignedResponse,
17094
+ canonicalizeEncryptionJson: () => import_sdk_core14.canonicalizeEncryptionJson,
17095
+ canonicalizeSecretScope: () => import_sdk_core13.canonicalizeSecretScope,
17096
+ checkDecryptInvocationInput: () => import_sdk_core14.checkDecryptInvocationInput,
17097
+ checkNodeInfo: () => import_sdk_core19.checkNodeInfo,
17073
17098
  composeManifestRequest: () => import_sdk_core9.composeManifestRequest,
17074
- createCapabilityKeyRegistry: () => import_sdk_core16.createCapabilityKeyRegistry,
17075
- createSharingService: () => import_sdk_core15.createSharingService,
17076
- createSpaceService: () => import_sdk_core17.createSpaceService,
17099
+ createCapabilityKeyRegistry: () => import_sdk_core17.createCapabilityKeyRegistry,
17100
+ createSharingService: () => import_sdk_core16.createSharingService,
17101
+ createSpaceService: () => import_sdk_core18.createSpaceService,
17077
17102
  createVaultCrypto: () => import_sdk_core13.createVaultCrypto,
17078
17103
  createWasmKeyProvider: () => createWasmKeyProvider,
17104
+ decryptEnvelopeWithKey: () => import_sdk_core14.decryptEnvelopeWithKey,
17079
17105
  defaultSignStrategy: () => defaultSignStrategy,
17080
17106
  defaultSpaceCreationHandler: () => import_sdk_core8.defaultSpaceCreationHandler,
17107
+ deriveSignedReceiverKey: () => import_sdk_core14.deriveSignedReceiverKey,
17081
17108
  deserializeDelegation: () => deserializeDelegation,
17109
+ discoverNetwork: () => import_sdk_core14.discoverNetwork,
17110
+ encryptToNetwork: () => import_sdk_core14.encryptToNetwork,
17111
+ encryptionBase64Decode: () => import_sdk_core14.encryptionBase64Decode,
17112
+ encryptionBase64Encode: () => import_sdk_core14.encryptionBase64Encode,
17113
+ encryptionError: () => import_sdk_core14.encryptionError,
17114
+ encryptionUtf8Decode: () => import_sdk_core14.encryptionUtf8Decode,
17115
+ encryptionUtf8Encode: () => import_sdk_core14.encryptionUtf8Encode,
17116
+ ensureNetworkUsableForDecrypt: () => import_sdk_core14.ensureNetworkUsableForDecrypt,
17082
17117
  expandActionShortNames: () => import_sdk_core9.expandActionShortNames,
17118
+ expandPermissionEntries: () => import_sdk_core9.expandPermissionEntries,
17119
+ expandPermissionEntry: () => import_sdk_core9.expandPermissionEntry,
17120
+ generateRandomReceiverKey: () => import_sdk_core14.generateRandomReceiverKey,
17121
+ hexDecode: () => import_sdk_core14.hexDecode,
17122
+ hexEncode: () => import_sdk_core14.hexEncode,
17083
17123
  isCapabilitySubset: () => import_sdk_core9.isCapabilitySubset,
17124
+ isNetworkId: () => import_sdk_core14.isNetworkId,
17084
17125
  loadManifest: () => import_sdk_core9.loadManifest,
17085
- makePublicSpaceId: () => import_sdk_core17.makePublicSpaceId,
17126
+ makePublicSpaceId: () => import_sdk_core18.makePublicSpaceId,
17127
+ networkDiscoveryKey: () => import_sdk_core14.networkDiscoveryKey,
17128
+ openWrappedKey: () => import_sdk_core14.openWrappedKey,
17086
17129
  parseExpiry: () => import_sdk_core9.parseExpiry,
17087
- parseSpaceUri: () => import_sdk_core17.parseSpaceUri,
17130
+ parseNetworkId: () => import_sdk_core14.parseNetworkId,
17131
+ parseSpaceUri: () => import_sdk_core18.parseSpaceUri,
17088
17132
  resolveManifest: () => import_sdk_core9.resolveManifest,
17133
+ resolveSecretListPrefix: () => import_sdk_core13.resolveSecretListPrefix,
17134
+ resolveSecretPath: () => import_sdk_core13.resolveSecretPath,
17089
17135
  resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core9.resourceCapabilitiesToSpaceAbilitiesMap,
17090
17136
  serializeDelegation: () => serializeDelegation,
17091
- validateManifest: () => import_sdk_core9.validateManifest
17137
+ validateEnvelope: () => import_sdk_core14.validateEnvelope,
17138
+ validateManifest: () => import_sdk_core9.validateManifest,
17139
+ verifyDecryptResponse: () => import_sdk_core14.verifyDecryptResponse
17092
17140
  });
17093
17141
  module.exports = __toCommonJS(index_exports);
17094
17142
 
@@ -17098,6 +17146,7 @@ var _NodeWasmBindings = class _NodeWasmBindings {
17098
17146
  constructor() {
17099
17147
  this.invoke = import_node_sdk_wasm.invoke;
17100
17148
  this.invokeAny = import_node_sdk_wasm.invokeAny;
17149
+ this.computeCid = import_node_sdk_wasm.computeCid;
17101
17150
  this.prepareSession = import_node_sdk_wasm.prepareSession;
17102
17151
  this.completeSessionSetup = import_node_sdk_wasm.completeSessionSetup;
17103
17152
  this.ensureEip55 = import_node_sdk_wasm.ensureEip55;
@@ -17325,7 +17374,7 @@ var NodeUserAuthorization = class {
17325
17374
  ]
17326
17375
  }
17327
17376
  };
17328
- this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
17377
+ this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core.EXPIRY.SESSION_MS;
17329
17378
  this.autoCreateSpace = config.autoCreateSpace ?? false;
17330
17379
  this.spaceCreationHandler = config.spaceCreationHandler;
17331
17380
  this.tinycloudHosts = config.tinycloudHosts;
@@ -17378,6 +17427,23 @@ var NodeUserAuthorization = class {
17378
17427
  get tinyCloudSession() {
17379
17428
  return this._tinyCloudSession;
17380
17429
  }
17430
+ /**
17431
+ * Rehydrate the auth-layer session from previously-persisted delegation
17432
+ * data. Used by {@link TinyCloudNode.restoreSession} so that downstream
17433
+ * surfaces that read from `tinyCloudSession` (notably
17434
+ * `grantRuntimePermissions`, which extracts the SIWE expiry from it) work
17435
+ * without re-running the full sign-in flow.
17436
+ *
17437
+ * Caller must supply the same fields that `signIn` would have written —
17438
+ * `siwe` is the load-bearing one because `extractSiweExpiration` returns
17439
+ * undefined for missing SIWEs and the SDK then treats the session as
17440
+ * expired-at-epoch-zero.
17441
+ */
17442
+ setRestoredTinyCloudSession(session) {
17443
+ this._tinyCloudSession = session;
17444
+ this._address = session.address;
17445
+ this._chainId = session.chainId;
17446
+ }
17381
17447
  async resolveTinyCloudHostsForSignIn(address, chainId) {
17382
17448
  if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
17383
17449
  return;
@@ -17448,21 +17514,64 @@ var NodeUserAuthorization = class {
17448
17514
  }
17449
17515
  return this.wasm.makeSpaceId(address, chainId, space);
17450
17516
  }
17517
+ defaultEncryptionNetworkId(address, chainId) {
17518
+ return `urn:tinycloud:encryption:did:pkh:eip155:${chainId}:${address}:default`;
17519
+ }
17451
17520
  resolveSignInCapabilities(address, chainId) {
17452
17521
  const request = this.getCapabilityRequest();
17453
17522
  if (request === void 0) {
17523
+ const defaultNetworkId = this.defaultEncryptionNetworkId(address, chainId);
17524
+ const secretsSpaceId = this.wasm.makeSpaceId(address, chainId, "secrets");
17454
17525
  return {
17455
17526
  abilities: this.defaultActions,
17456
- spaceId: this.wasm.makeSpaceId(address, chainId, this.spacePrefix)
17527
+ spaceId: this.wasm.makeSpaceId(address, chainId, this.spacePrefix),
17528
+ spaceAbilities: {
17529
+ [secretsSpaceId]: {
17530
+ kv: {
17531
+ "vault/secrets/": [
17532
+ "tinycloud.kv/get",
17533
+ "tinycloud.kv/put",
17534
+ "tinycloud.kv/del",
17535
+ "tinycloud.kv/list",
17536
+ "tinycloud.kv/metadata"
17537
+ ]
17538
+ }
17539
+ }
17540
+ },
17541
+ rawAbilities: {
17542
+ [defaultNetworkId]: [
17543
+ "tinycloud.encryption/decrypt",
17544
+ "tinycloud.encryption/network.create"
17545
+ ]
17546
+ }
17457
17547
  };
17458
17548
  }
17459
- const primarySpaceName = request.resources.find((entry) => entry.space !== "account")?.space ?? import_sdk_core.DEFAULT_MANIFEST_SPACE;
17549
+ const rawAbilities = {};
17550
+ const spaceResources = request.resources.filter((entry) => {
17551
+ if (entry.service !== import_sdk_core.ENCRYPTION_PERMISSION_SERVICE) {
17552
+ return true;
17553
+ }
17554
+ const existing = rawAbilities[entry.path];
17555
+ if (existing === void 0) {
17556
+ rawAbilities[entry.path] = [...entry.actions];
17557
+ } else {
17558
+ const seen = new Set(existing);
17559
+ for (const action of entry.actions) {
17560
+ if (!seen.has(action)) {
17561
+ existing.push(action);
17562
+ seen.add(action);
17563
+ }
17564
+ }
17565
+ }
17566
+ return false;
17567
+ });
17568
+ const primarySpaceName = spaceResources.find((entry) => entry.space !== "account")?.space ?? import_sdk_core.DEFAULT_MANIFEST_SPACE;
17460
17569
  const primarySpaceId = this.resolveSpaceName(
17461
17570
  primarySpaceName,
17462
17571
  address,
17463
17572
  chainId
17464
17573
  );
17465
- const bySpace = (0, import_sdk_core.resourceCapabilitiesToSpaceAbilitiesMap)(request.resources);
17574
+ const bySpace = (0, import_sdk_core.resourceCapabilitiesToSpaceAbilitiesMap)(spaceResources);
17466
17575
  const spaceAbilities = {};
17467
17576
  for (const [space, abilities] of Object.entries(bySpace)) {
17468
17577
  spaceAbilities[this.resolveSpaceName(space, address, chainId)] = abilities;
@@ -17470,7 +17579,8 @@ var NodeUserAuthorization = class {
17470
17579
  return {
17471
17580
  abilities: spaceAbilities[primarySpaceId] ?? (0, import_sdk_core.resourceCapabilitiesToAbilitiesMap)([]),
17472
17581
  spaceId: primarySpaceId,
17473
- spaceAbilities
17582
+ spaceAbilities,
17583
+ rawAbilities: Object.keys(rawAbilities).length > 0 ? rawAbilities : void 0
17474
17584
  };
17475
17585
  }
17476
17586
  /**
@@ -17695,6 +17805,7 @@ var NodeUserAuthorization = class {
17695
17805
  const prepared = this.wasm.prepareSession({
17696
17806
  abilities: capabilityPlan.abilities,
17697
17807
  ...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
17808
+ ...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
17698
17809
  address,
17699
17810
  chainId,
17700
17811
  domain: this.domain,
@@ -17840,6 +17951,7 @@ var NodeUserAuthorization = class {
17840
17951
  const prepared = this.wasm.prepareSession({
17841
17952
  abilities: capabilityPlan.abilities,
17842
17953
  ...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
17954
+ ...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
17843
17955
  address,
17844
17956
  chainId,
17845
17957
  domain: this.domain,
@@ -18210,9 +18322,10 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
18210
18322
  }
18211
18323
  return entries;
18212
18324
  }
18325
+ var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core3.EXPIRY.SESSION_MS;
18213
18326
  function resolveExpiryMs(expiry) {
18214
18327
  if (expiry === void 0) {
18215
- return 60 * 60 * 1e3;
18328
+ return DEFAULT_DELEGATION_EXPIRY_MS;
18216
18329
  }
18217
18330
  if (typeof expiry === "number") {
18218
18331
  if (!Number.isFinite(expiry) || expiry <= 0) {
@@ -18240,8 +18353,6 @@ function extractSiweExpiration(siwe) {
18240
18353
 
18241
18354
  // src/NodeSecretsService.ts
18242
18355
  var import_sdk_core4 = require("@tinycloud/sdk-core");
18243
- var SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
18244
- var SECRET_PREFIX = "secrets/";
18245
18356
  var SECRETS_SPACE = "secrets";
18246
18357
  function ok() {
18247
18358
  return { ok: true, data: void 0 };
@@ -18257,32 +18368,40 @@ function secretsError(code, message, cause) {
18257
18368
  }
18258
18369
  };
18259
18370
  }
18260
- function actionUrn(action) {
18261
- return `tinycloud.kv/${action}`;
18371
+ function displayActionUrn(action) {
18372
+ switch (action) {
18373
+ case "get":
18374
+ return "tinycloud.kv/get";
18375
+ case "put":
18376
+ return "tinycloud.kv/put";
18377
+ case "del":
18378
+ return "tinycloud.kv/del";
18379
+ case "list":
18380
+ return "tinycloud.kv/list";
18381
+ }
18262
18382
  }
18263
- function secretResourcePath(base2, name) {
18264
- return `${base2}/${SECRET_PREFIX}${name}`;
18383
+ function secretActionName(action) {
18384
+ return action;
18265
18385
  }
18266
- function secretPermissionEntries(name, action) {
18267
- return [
18268
- {
18269
- service: "tinycloud.kv",
18270
- space: SECRETS_SPACE,
18271
- path: secretResourcePath("keys", name),
18272
- actions: [action],
18273
- skipPrefix: true
18274
- },
18275
- {
18276
- service: "tinycloud.kv",
18277
- space: SECRETS_SPACE,
18278
- path: secretResourcePath("vault", name),
18279
- actions: [action],
18386
+ function secretPermissionEntries(name, options, action, encryptionNetworkId) {
18387
+ const entries = [];
18388
+ const path = action === "list" ? (0, import_sdk_core4.resolveSecretListPrefix)(options) : (0, import_sdk_core4.resolveSecretPath)(name, options).permissionPaths.vault;
18389
+ entries.push({
18390
+ service: "tinycloud.kv",
18391
+ space: SECRETS_SPACE,
18392
+ path,
18393
+ actions: [secretActionName(action)],
18394
+ skipPrefix: true
18395
+ });
18396
+ if (action === "get" && encryptionNetworkId !== void 0) {
18397
+ entries.push({
18398
+ service: "tinycloud.encryption",
18399
+ path: encryptionNetworkId,
18400
+ actions: ["decrypt"],
18280
18401
  skipPrefix: true
18281
- }
18282
- ];
18283
- }
18284
- function isSecretsSpace(space) {
18285
- return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
18402
+ });
18403
+ }
18404
+ return entries;
18286
18405
  }
18287
18406
  var NodeSecretsService = class {
18288
18407
  constructor(config) {
@@ -18310,48 +18429,62 @@ var NodeSecretsService = class {
18310
18429
  this.shouldRestoreUnlock = false;
18311
18430
  this.service.lock();
18312
18431
  }
18313
- get(name) {
18314
- return this.service.get(name);
18432
+ async get(name, options) {
18433
+ const permission = await this.ensurePermission(name, options, "get");
18434
+ if (!permission.ok) return permission;
18435
+ return options === void 0 ? this.service.get(name) : this.service.get(name, options);
18315
18436
  }
18316
- async put(name, value) {
18317
- const permission = await this.ensureMutationPermission(name, "put");
18437
+ async put(name, value, options) {
18438
+ const permission = await this.ensurePermission(name, options, "put");
18318
18439
  if (!permission.ok) return permission;
18319
- return this.service.put(name, value);
18440
+ return options === void 0 ? this.service.put(name, value) : this.service.put(name, value, options);
18320
18441
  }
18321
- async delete(name) {
18322
- const permission = await this.ensureMutationPermission(name, "del");
18442
+ async delete(name, options) {
18443
+ const permission = await this.ensurePermission(name, options, "del");
18323
18444
  if (!permission.ok) return permission;
18324
- return this.service.delete(name);
18445
+ return options === void 0 ? this.service.delete(name) : this.service.delete(name, options);
18325
18446
  }
18326
- list() {
18327
- return this.service.list();
18447
+ async list(options) {
18448
+ const permission = await this.ensurePermission("", options, "list");
18449
+ if (!permission.ok) return permission;
18450
+ return options === void 0 ? this.service.list() : this.service.list(options);
18328
18451
  }
18329
18452
  get service() {
18330
18453
  return this.config.getService();
18331
18454
  }
18332
- async ensureMutationPermission(name, action) {
18333
- if (!SECRET_NAME_RE.test(name)) {
18455
+ async ensurePermission(name, options, action) {
18456
+ const target = name || "secrets";
18457
+ let permissionEntries;
18458
+ try {
18459
+ permissionEntries = secretPermissionEntries(
18460
+ name,
18461
+ options,
18462
+ action,
18463
+ action === "get" ? this.config.getEncryptionNetworkId?.() : void 0
18464
+ );
18465
+ } catch (error) {
18334
18466
  return secretsError(
18335
18467
  import_sdk_core4.ErrorCodes.INVALID_INPUT,
18336
- `Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`
18468
+ error instanceof Error ? error.message : String(error),
18469
+ error instanceof Error ? error : void 0
18337
18470
  );
18338
18471
  }
18339
- if (this.hasMutationPermission(name, action)) {
18472
+ if (this.hasPermission(permissionEntries)) {
18340
18473
  return ok();
18341
18474
  }
18342
18475
  if (!this.config.canEscalate()) {
18343
18476
  return secretsError(
18344
18477
  import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
18345
- `Cannot autosign ${actionUrn(action)} for ${name}; TinyCloudNode needs wallet mode with a signer or privateKey.`
18478
+ `Cannot autosign ${displayActionUrn(action)} for ${target}; TinyCloudNode needs wallet mode with a signer or privateKey.`
18346
18479
  );
18347
18480
  }
18348
18481
  try {
18349
- await this.config.grantPermissions(secretPermissionEntries(name, action));
18482
+ await this.config.grantPermissions(permissionEntries);
18350
18483
  return this.restoreUnlockAfterEscalation();
18351
18484
  } catch (error) {
18352
18485
  return secretsError(
18353
18486
  import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
18354
- error instanceof Error ? error.message : `Autosign escalation for ${actionUrn(action)} on ${name} failed.`,
18487
+ error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
18355
18488
  error instanceof Error ? error : void 0
18356
18489
  );
18357
18490
  }
@@ -18362,26 +18495,117 @@ var NodeSecretsService = class {
18362
18495
  }
18363
18496
  return this.service.unlock(this.unlockSigner);
18364
18497
  }
18365
- hasMutationPermission(name, action) {
18498
+ hasPermission(permissionEntries) {
18499
+ if (this.config.hasPermissions?.(permissionEntries)) {
18500
+ return true;
18501
+ }
18366
18502
  const manifest = this.config.getManifest();
18367
18503
  if (manifest === void 0) {
18368
18504
  return false;
18369
18505
  }
18370
18506
  const manifests = Array.isArray(manifest) ? manifest : [manifest];
18371
- const requiredAction = actionUrn(action);
18372
- return manifests.some((entry) => {
18373
- const resolved = (0, import_sdk_core4.resolveManifest)(entry);
18374
- return ["keys", "vault"].every(
18375
- (base2) => resolved.resources.some(
18376
- (resource) => resource.service === "tinycloud.kv" && isSecretsSpace(resource.space) && resource.path === secretResourcePath(base2, name) && resource.actions.includes(requiredAction)
18377
- )
18378
- );
18379
- });
18507
+ const requestedEntries = (0, import_sdk_core4.expandPermissionEntries)(permissionEntries);
18508
+ return requestedEntries.every(
18509
+ (entry) => manifests.some((candidate) => {
18510
+ const resolved = (0, import_sdk_core4.resolveManifest)(candidate);
18511
+ return resolved.resources.some(
18512
+ (resource) => resource.service === entry.service && resource.space === entry.space && resource.path === entry.path && entry.actions.every((action) => resource.actions.includes(action))
18513
+ );
18514
+ })
18515
+ );
18380
18516
  }
18381
18517
  };
18382
18518
 
18383
18519
  // src/TinyCloudNode.ts
18384
18520
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
18521
+ var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
18522
+ var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
18523
+ var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
18524
+ var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
18525
+ var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core5.EXPIRY.SESSION_MS;
18526
+ function base64UrlEncode(bytes) {
18527
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
18528
+ let output = "";
18529
+ for (let i = 0; i < bytes.length; i += 3) {
18530
+ const a = bytes[i];
18531
+ const b = bytes[i + 1];
18532
+ const c = bytes[i + 2];
18533
+ const triplet = a << 16 | (b ?? 0) << 8 | (c ?? 0);
18534
+ output += alphabet[triplet >> 18 & 63];
18535
+ output += alphabet[triplet >> 12 & 63];
18536
+ if (i + 1 < bytes.length) output += alphabet[triplet >> 6 & 63];
18537
+ if (i + 2 < bytes.length) output += alphabet[triplet & 63];
18538
+ }
18539
+ return output;
18540
+ }
18541
+ function base64UrlDecode(value) {
18542
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
18543
+ const bytes = [];
18544
+ let buffer = 0;
18545
+ let bits = 0;
18546
+ for (const char of value) {
18547
+ const index = alphabet.indexOf(char);
18548
+ if (index < 0) {
18549
+ throw new Error("invalid base64url input");
18550
+ }
18551
+ buffer = buffer << 6 | index;
18552
+ bits += 6;
18553
+ if (bits >= 8) {
18554
+ bits -= 8;
18555
+ bytes.push(buffer >> bits & 255);
18556
+ }
18557
+ }
18558
+ return new Uint8Array(bytes);
18559
+ }
18560
+ async function signJwtInputWithJwk(signingInput, jwk) {
18561
+ const bytes = new TextEncoder().encode(signingInput);
18562
+ try {
18563
+ const subtle = globalThis.crypto?.subtle;
18564
+ if (!subtle) {
18565
+ throw new Error("WebCrypto subtle API is unavailable");
18566
+ }
18567
+ const key2 = await subtle.importKey(
18568
+ "jwk",
18569
+ jwk,
18570
+ { name: "Ed25519" },
18571
+ false,
18572
+ ["sign"]
18573
+ );
18574
+ return new Uint8Array(await subtle.sign({ name: "Ed25519" }, key2, bytes));
18575
+ } catch {
18576
+ const nodeCrypto = await import("crypto");
18577
+ const key2 = nodeCrypto.createPrivateKey({ key: jwk, format: "jwk" });
18578
+ return new Uint8Array(nodeCrypto.sign(null, Buffer.from(bytes), key2));
18579
+ }
18580
+ }
18581
+ async function rewriteInvocationAudience(authorization, audience, jwk) {
18582
+ const [headerPart, payloadPart] = authorization.split(".");
18583
+ if (!headerPart || !payloadPart) {
18584
+ throw new Error("invalid invocation authorization");
18585
+ }
18586
+ const header = JSON.parse(new TextDecoder().decode(base64UrlDecode(headerPart)));
18587
+ const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(payloadPart)));
18588
+ payload.aud = audience;
18589
+ const signingInput = `${base64UrlEncode(
18590
+ new TextEncoder().encode(JSON.stringify(header))
18591
+ )}.${base64UrlEncode(new TextEncoder().encode(JSON.stringify(payload)))}`;
18592
+ const signature2 = await signJwtInputWithJwk(signingInput, jwk);
18593
+ return `${signingInput}.${base64UrlEncode(signature2)}`;
18594
+ }
18595
+ function authorizationHeader(headers) {
18596
+ if (Array.isArray(headers)) {
18597
+ const entry = headers.find(([name]) => name.toLowerCase() === "authorization");
18598
+ if (!entry) {
18599
+ throw new Error("network invocation did not include an Authorization header");
18600
+ }
18601
+ return entry[1];
18602
+ }
18603
+ const value = headers.Authorization ?? headers.authorization;
18604
+ if (!value) {
18605
+ throw new Error("network invocation did not include an Authorization header");
18606
+ }
18607
+ return value;
18608
+ }
18385
18609
  var _TinyCloudNode = class _TinyCloudNode {
18386
18610
  /**
18387
18611
  * Create a new TinyCloudNode instance.
@@ -18426,12 +18650,10 @@ var _TinyCloudNode = class _TinyCloudNode {
18426
18650
  throw new Error("WASM binding does not support invokeAny");
18427
18651
  }
18428
18652
  const grant = this.findGrantForOperations(
18429
- entries.map((entry) => ({
18430
- spaceId: entry.spaceId,
18431
- service: this.invocationServiceName(entry.service),
18432
- path: entry.path,
18433
- action: entry.action
18434
- }))
18653
+ entries.flatMap((entry) => {
18654
+ const operation = this.operationFromInvokeAnyEntry(entry);
18655
+ return operation ? [operation] : [];
18656
+ })
18435
18657
  );
18436
18658
  return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
18437
18659
  };
@@ -18524,7 +18746,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18524
18746
  sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
18525
18747
  domain: this.siweDomain,
18526
18748
  spacePrefix: config.prefix,
18527
- sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
18749
+ sessionExpirationMs: config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
18528
18750
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18529
18751
  tinycloudRegistryUrl: config.tinycloudRegistryUrl,
18530
18752
  tinycloudFallbackHosts: config.tinycloudFallbackHosts,
@@ -18659,6 +18881,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18659
18881
  this._duckdb = void 0;
18660
18882
  this._hooks = void 0;
18661
18883
  this._vault = void 0;
18884
+ this._encryption = void 0;
18662
18885
  this._baseSecrets = void 0;
18663
18886
  this._secrets = void 0;
18664
18887
  this._spaceService = void 0;
@@ -18667,6 +18890,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18667
18890
  await this.tc.signIn(options);
18668
18891
  this.syncResolvedHostFromAuth();
18669
18892
  this.initializeServices();
18893
+ if (this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
18894
+ await this.ensureOwnedSpaceHosted(this.ownedSpaceId("secrets"));
18895
+ }
18670
18896
  await this.writeManifestRegistryRecords();
18671
18897
  this.notificationHandler.success("Successfully signed in");
18672
18898
  }
@@ -18749,6 +18975,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18749
18975
  this._duckdb = void 0;
18750
18976
  this._hooks = void 0;
18751
18977
  this._vault = void 0;
18978
+ this._encryption = void 0;
18752
18979
  this._baseSecrets = void 0;
18753
18980
  this._secrets = void 0;
18754
18981
  this._spaceService = void 0;
@@ -18790,6 +19017,33 @@ var _TinyCloudNode = class _TinyCloudNode {
18790
19017
  this._vault.initialize(this._serviceContext);
18791
19018
  this._serviceContext.registerService("vault", this._vault);
18792
19019
  this.initializeV2Services(serviceSession);
19020
+ if (sessionData.siwe && sessionData.address && sessionData.chainId) {
19021
+ const tcSession = {
19022
+ address: sessionData.address,
19023
+ chainId: sessionData.chainId,
19024
+ sessionKey: JSON.stringify(sessionData.jwk),
19025
+ spaceId: sessionData.spaceId,
19026
+ delegationCid: sessionData.delegationCid,
19027
+ delegationHeader: sessionData.delegationHeader,
19028
+ verificationMethod: sessionData.verificationMethod,
19029
+ jwk: sessionData.jwk,
19030
+ siwe: sessionData.siwe,
19031
+ signature: sessionData.signature ?? ""
19032
+ };
19033
+ if (this.auth) {
19034
+ this.auth.setRestoredTinyCloudSession(tcSession);
19035
+ } else {
19036
+ this._restoredTcSession = tcSession;
19037
+ }
19038
+ }
19039
+ }
19040
+ /**
19041
+ * Resolve the currently-active TinyCloudSession, preferring the auth
19042
+ * layer's value (wallet mode) and falling back to the node-level
19043
+ * rehydration set by {@link restoreSession} (session-only mode).
19044
+ */
19045
+ currentTinyCloudSession() {
19046
+ return this.auth?.tinyCloudSession ?? this._restoredTcSession;
18793
19047
  }
18794
19048
  /**
18795
19049
  * Connect a wallet to upgrade from session-only mode to wallet mode.
@@ -18834,7 +19088,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18834
19088
  sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
18835
19089
  domain: this.siweDomain,
18836
19090
  spacePrefix: prefix,
18837
- sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
19091
+ sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
18838
19092
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18839
19093
  tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
18840
19094
  tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
@@ -18878,7 +19132,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18878
19132
  sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
18879
19133
  domain: this.siweDomain,
18880
19134
  spacePrefix: prefix,
18881
- sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
19135
+ sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
18882
19136
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
18883
19137
  tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
18884
19138
  tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
@@ -18901,7 +19155,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18901
19155
  * @internal
18902
19156
  */
18903
19157
  initializeServices() {
18904
- const session = this.auth?.tinyCloudSession;
19158
+ const session = this.currentTinyCloudSession();
18905
19159
  if (!session) {
18906
19160
  return;
18907
19161
  }
@@ -18959,6 +19213,163 @@ var _TinyCloudNode = class _TinyCloudNode {
18959
19213
  }
18960
19214
  return kvService;
18961
19215
  }
19216
+ getDefaultEncryptionNetworkId(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
19217
+ return `urn:tinycloud:encryption:${this.did}:${name}`;
19218
+ }
19219
+ requireServiceSession() {
19220
+ const session = this._serviceContext?.session;
19221
+ if (!session) {
19222
+ throw new Error("Not signed in. Call signIn() first.");
19223
+ }
19224
+ return session;
19225
+ }
19226
+ createEncryptionCrypto() {
19227
+ const wasm = this.wasmBindings;
19228
+ const columnEncrypt = (key2, plaintext) => {
19229
+ const encrypted = wasm.vault_encrypt(key2, plaintext);
19230
+ const out = new Uint8Array(1 + encrypted.length);
19231
+ out[0] = 1;
19232
+ out.set(encrypted, 1);
19233
+ return out;
19234
+ };
19235
+ const columnDecrypt = (key2, blob) => {
19236
+ if (blob[0] !== 1) {
19237
+ return blob;
19238
+ }
19239
+ return wasm.vault_decrypt(key2, blob.slice(1));
19240
+ };
19241
+ return {
19242
+ sha256: (data) => wasm.vault_sha256(data),
19243
+ randomBytes: (length) => wasm.vault_random_bytes(length),
19244
+ x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),
19245
+ x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),
19246
+ authEncrypt: (key2, plaintext) => wasm.vault_encrypt(key2, plaintext),
19247
+ authDecrypt: (key2, ciphertext) => wasm.vault_decrypt(key2, ciphertext),
19248
+ sealToNetworkKey: (networkPublicKey, symmetricKey) => {
19249
+ const seed = wasm.vault_random_bytes(32);
19250
+ const ephemeral = wasm.vault_x25519_from_seed(seed);
19251
+ const shared = wasm.vault_x25519_dh(
19252
+ ephemeral.privateKey,
19253
+ networkPublicKey
19254
+ );
19255
+ const encrypted = columnEncrypt(shared, symmetricKey);
19256
+ const out = new Uint8Array(ephemeral.publicKey.length + encrypted.length);
19257
+ out.set(ephemeral.publicKey, 0);
19258
+ out.set(encrypted, ephemeral.publicKey.length);
19259
+ return out;
19260
+ },
19261
+ openWithReceiverKey: (receiverPrivateKey, wrappedKey) => {
19262
+ const peerPublic = wrappedKey.slice(0, 32);
19263
+ const ciphertext = wrappedKey.slice(32);
19264
+ const shared = wasm.vault_x25519_dh(receiverPrivateKey, peerPublic);
19265
+ return columnDecrypt(shared, ciphertext);
19266
+ },
19267
+ verifyNodeSignature: (nodeId, message, signature2) => (0, import_sdk_core5.verifyDidKeyEd25519Signature)(nodeId, message, signature2)
19268
+ };
19269
+ }
19270
+ async fetchNodeId() {
19271
+ const response = await fetch(`${this.config.host}/info`);
19272
+ if (!response.ok) {
19273
+ throw new Error(`Failed to fetch node info: HTTP ${response.status}`);
19274
+ }
19275
+ const info = await response.json();
19276
+ if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
19277
+ throw new Error("Node /info response did not include nodeId");
19278
+ }
19279
+ return info.nodeId;
19280
+ }
19281
+ async signRawNetworkAuthorization(input) {
19282
+ if (!this.wasmBindings.invokeAny) {
19283
+ throw new Error("WASM binding does not support raw-resource invokeAny");
19284
+ }
19285
+ if (!this.wasmBindings.computeCid) {
19286
+ throw new Error("WASM binding does not support invocation CID computation");
19287
+ }
19288
+ const session = this.requireServiceSession();
19289
+ const headers = this.invokeAnyWithRuntimePermissions(
19290
+ session,
19291
+ [
19292
+ {
19293
+ resource: input.networkId,
19294
+ service: "encryption",
19295
+ path: input.networkId,
19296
+ action: input.action
19297
+ }
19298
+ ],
19299
+ [input.facts]
19300
+ );
19301
+ const authorization = authorizationHeader(headers);
19302
+ const audienceBound = await rewriteInvocationAudience(
19303
+ authorization,
19304
+ input.targetNode,
19305
+ session.jwk
19306
+ );
19307
+ return {
19308
+ authorization: audienceBound,
19309
+ invocationCid: this.wasmBindings.computeCid(
19310
+ new TextEncoder().encode(audienceBound),
19311
+ 0x55n
19312
+ )
19313
+ };
19314
+ }
19315
+ createEncryptionService() {
19316
+ const crypto2 = this.createEncryptionCrypto();
19317
+ const transport = {
19318
+ postDecrypt: async ({ networkId, authorization, canonicalBody }) => {
19319
+ const response = await fetch(
19320
+ `${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
19321
+ {
19322
+ method: "POST",
19323
+ headers: {
19324
+ Authorization: authorization,
19325
+ "Content-Type": "application/json"
19326
+ },
19327
+ body: canonicalBody
19328
+ }
19329
+ );
19330
+ if (!response.ok) {
19331
+ throw new Error(
19332
+ `decrypt failed ${response.status}: ${await response.text()}`
19333
+ );
19334
+ }
19335
+ return await response.json();
19336
+ }
19337
+ };
19338
+ return new import_sdk_core5.EncryptionService({
19339
+ crypto: crypto2,
19340
+ signer: {
19341
+ signDecryptInvocation: async (input) => {
19342
+ const signed2 = await this.signRawNetworkAuthorization({
19343
+ targetNode: input.targetNode,
19344
+ networkId: input.networkId,
19345
+ action: DECRYPT_ACTION,
19346
+ facts: input.facts
19347
+ });
19348
+ return {
19349
+ ...signed2,
19350
+ canonicalBody: (0, import_sdk_core5.canonicalizeEncryptionJson)(
19351
+ input.body
19352
+ )
19353
+ };
19354
+ }
19355
+ },
19356
+ transport,
19357
+ node: {
19358
+ fetchByNetworkId: (networkId) => this.getEncryptionNetwork(networkId)
19359
+ }
19360
+ });
19361
+ }
19362
+ getEncryptionService() {
19363
+ if (!this._serviceContext) {
19364
+ throw new Error("Not signed in. Call signIn() first.");
19365
+ }
19366
+ if (!this._encryption) {
19367
+ this._encryption = this.createEncryptionService();
19368
+ this._encryption.initialize(this._serviceContext);
19369
+ this._serviceContext.registerService("encryption", this._encryption);
19370
+ }
19371
+ return this._encryption;
19372
+ }
18962
19373
  createVaultService(spaceId, kv) {
18963
19374
  const wasm = this.wasmBindings;
18964
19375
  const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
@@ -18974,6 +19385,13 @@ var _TinyCloudNode = class _TinyCloudNode {
18974
19385
  return new import_sdk_core5.DataVaultService({
18975
19386
  spaceId,
18976
19387
  crypto: vaultCrypto,
19388
+ encryption: {
19389
+ networkId: this.getDefaultEncryptionNetworkId(),
19390
+ service: this.getEncryptionService(),
19391
+ decryptCapabilityProof: () => ({
19392
+ proofs: [this.requireServiceSession().delegationCid]
19393
+ })
19394
+ },
18977
19395
  tc: {
18978
19396
  kv,
18979
19397
  ensurePublicSpace: async () => {
@@ -19154,7 +19572,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19154
19572
  * @internal
19155
19573
  */
19156
19574
  getSessionExpiry() {
19157
- const expirationMs = this.config.sessionExpirationMs ?? 60 * 60 * 1e3;
19575
+ const expirationMs = this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS;
19158
19576
  return new Date(Date.now() + expirationMs);
19159
19577
  }
19160
19578
  /**
@@ -19211,7 +19629,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19211
19629
  if (!this.signer) {
19212
19630
  return void 0;
19213
19631
  }
19214
- const session = this.auth?.tinyCloudSession;
19632
+ const session = this.currentTinyCloudSession();
19215
19633
  if (!session) {
19216
19634
  return void 0;
19217
19635
  }
@@ -19311,6 +19729,34 @@ var _TinyCloudNode = class _TinyCloudNode {
19311
19729
  }
19312
19730
  return this._sql;
19313
19731
  }
19732
+ /**
19733
+ * Get an SQL service scoped to a specific space.
19734
+ *
19735
+ * Mirrors {@link SpaceService}'s per-space KV factory: clones the active
19736
+ * service context and overrides its session's spaceId so that subsequent
19737
+ * `sql/<dbName>/<action>` invocations route to that space. Useful when
19738
+ * the caller already holds a delegation covering the target space (e.g.
19739
+ * via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
19740
+ * but the SDK's per-space SQL surface isn't otherwise exposed.
19741
+ *
19742
+ * Does NOT auto-create the space.
19743
+ *
19744
+ * @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
19745
+ */
19746
+ sqlForSpace(spaceId) {
19747
+ if (!this._serviceContext || !this._serviceContext.session) {
19748
+ throw new Error("Not signed in. Call signIn() first.");
19749
+ }
19750
+ const sql = new import_sdk_core5.SQLService({});
19751
+ const spaceScopedContext = new import_sdk_core5.ServiceContext({
19752
+ invoke: this._serviceContext.invoke,
19753
+ fetch: this._serviceContext.fetch,
19754
+ hosts: this._serviceContext.hosts
19755
+ });
19756
+ spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
19757
+ sql.initialize(spaceScopedContext);
19758
+ return sql;
19759
+ }
19314
19760
  /**
19315
19761
  * DuckDB database operations on this user's space.
19316
19762
  */
@@ -19334,6 +19780,79 @@ var _TinyCloudNode = class _TinyCloudNode {
19334
19780
  }
19335
19781
  return this._vault;
19336
19782
  }
19783
+ /**
19784
+ * Network-scoped encryption/decrypt service.
19785
+ */
19786
+ get encryption() {
19787
+ return this.getEncryptionService();
19788
+ }
19789
+ async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
19790
+ const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
19791
+ const response = await fetch(
19792
+ `${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}`
19793
+ );
19794
+ if (response.status === 404) {
19795
+ return null;
19796
+ }
19797
+ if (!response.ok) {
19798
+ throw new Error(
19799
+ `Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
19800
+ );
19801
+ }
19802
+ const body = await response.json();
19803
+ return "descriptor" in body && body.descriptor ? body.descriptor : body;
19804
+ }
19805
+ async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
19806
+ const targetNode = await this.fetchNodeId();
19807
+ const principal = this.did;
19808
+ const networkId = this.getDefaultEncryptionNetworkId(name);
19809
+ const body = {
19810
+ name,
19811
+ principal,
19812
+ threshold: { n: 1, t: 1 }
19813
+ };
19814
+ const crypto2 = this.createEncryptionCrypto();
19815
+ const facts = {
19816
+ type: NETWORK_ADMIN_TYPE,
19817
+ targetNode,
19818
+ networkId,
19819
+ bodyHash: (0, import_sdk_core5.canonicalHashHex)(
19820
+ crypto2.sha256,
19821
+ body
19822
+ ),
19823
+ action: NETWORK_CREATE_ACTION
19824
+ };
19825
+ const signed2 = await this.signRawNetworkAuthorization({
19826
+ targetNode,
19827
+ networkId,
19828
+ action: NETWORK_CREATE_ACTION,
19829
+ facts
19830
+ });
19831
+ const response = await fetch(`${this.config.host}/encryption/networks`, {
19832
+ method: "POST",
19833
+ headers: {
19834
+ Authorization: signed2.authorization,
19835
+ "Content-Type": "application/json"
19836
+ },
19837
+ body: (0, import_sdk_core5.canonicalizeEncryptionJson)(
19838
+ body
19839
+ )
19840
+ });
19841
+ if (!response.ok) {
19842
+ throw new Error(
19843
+ `Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
19844
+ );
19845
+ }
19846
+ const created = await response.json();
19847
+ return created.descriptor;
19848
+ }
19849
+ async ensureEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
19850
+ const existing = await this.getEncryptionNetwork(name);
19851
+ if (existing) {
19852
+ return existing;
19853
+ }
19854
+ return this.createEncryptionNetwork(name);
19855
+ }
19337
19856
  /**
19338
19857
  * App-facing secrets API backed by the `secrets` space vault.
19339
19858
  */
@@ -19345,8 +19864,10 @@ var _TinyCloudNode = class _TinyCloudNode {
19345
19864
  this._secrets = new NodeSecretsService({
19346
19865
  getService: () => this.getBaseSecrets(),
19347
19866
  getManifest: () => this.manifest,
19867
+ hasPermissions: (permissions) => this.hasRuntimePermissions(permissions),
19348
19868
  grantPermissions: (additional) => this.grantRuntimePermissions(additional),
19349
19869
  canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
19870
+ getEncryptionNetworkId: () => this.getDefaultEncryptionNetworkId(),
19350
19871
  getUnlockSigner: () => this.signer ?? void 0
19351
19872
  });
19352
19873
  }
@@ -19436,7 +19957,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19436
19957
  * every requested permission.
19437
19958
  */
19438
19959
  hasRuntimePermissions(permissions) {
19439
- const session = this.auth?.tinyCloudSession;
19960
+ const session = this.currentTinyCloudSession();
19440
19961
  if (!session || !Array.isArray(permissions) || permissions.length === 0) {
19441
19962
  return false;
19442
19963
  }
@@ -19456,7 +19977,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19456
19977
  if (permissions === void 0) {
19457
19978
  return this.runtimePermissionGrants.map((grant) => grant.delegation);
19458
19979
  }
19459
- const session = this.auth?.tinyCloudSession;
19980
+ const session = this.currentTinyCloudSession();
19460
19981
  if (!session || !Array.isArray(permissions) || permissions.length === 0) {
19461
19982
  return [];
19462
19983
  }
@@ -19470,7 +19991,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19470
19991
  * matching service calls and downstream `delegateTo()` calls can use it.
19471
19992
  */
19472
19993
  async useRuntimeDelegation(delegation) {
19473
- const session = this.auth?.tinyCloudSession;
19994
+ const session = this.currentTinyCloudSession();
19474
19995
  if (!session) {
19475
19996
  throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19476
19997
  }
@@ -19509,7 +20030,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19509
20030
  if (!Array.isArray(permissions) || permissions.length === 0) {
19510
20031
  throw new Error("grantRuntimePermissions requires a non-empty permissions array");
19511
20032
  }
19512
- const session = this.auth?.tinyCloudSession;
20033
+ const session = this.currentTinyCloudSession();
19513
20034
  if (!session) {
19514
20035
  throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19515
20036
  }
@@ -19533,13 +20054,22 @@ var _TinyCloudNode = class _TinyCloudNode {
19533
20054
  "grantRuntimePermissions requires wallet mode with a signer or privateKey."
19534
20055
  );
19535
20056
  }
20057
+ const rawEntries = expanded.filter(
20058
+ (entry) => this.isEncryptionPermissionEntry(entry)
20059
+ );
20060
+ const spaceEntries = expanded.filter(
20061
+ (entry) => !this.isEncryptionPermissionEntry(entry)
20062
+ );
19536
20063
  const bySpace = /* @__PURE__ */ new Map();
19537
- for (const entry of expanded) {
20064
+ for (const entry of spaceEntries) {
19538
20065
  const spaceId = this.resolvePermissionSpace(entry.space, session);
19539
20066
  const current = bySpace.get(spaceId) ?? [];
19540
20067
  current.push(entry);
19541
20068
  bySpace.set(spaceId, current);
19542
20069
  }
20070
+ if (bySpace.size === 0 && rawEntries.length > 0) {
20071
+ bySpace.set(session.spaceId, []);
20072
+ }
19543
20073
  const now = /* @__PURE__ */ new Date();
19544
20074
  const requestedExpiryMs = resolveExpiryMs(options?.expiry);
19545
20075
  let expiresAt = new Date(now.getTime() + requestedExpiryMs);
@@ -19547,10 +20077,17 @@ var _TinyCloudNode = class _TinyCloudNode {
19547
20077
  expiresAt = sessionExpiry;
19548
20078
  }
19549
20079
  const delegations = [];
20080
+ let rawEntriesAttached = false;
19550
20081
  for (const [spaceId, entries] of bySpace) {
20082
+ const rawForDelegation = !rawEntriesAttached ? rawEntries : [];
20083
+ if (rawForDelegation.length > 0) {
20084
+ rawEntriesAttached = true;
20085
+ }
20086
+ const delegatedEntries = [...entries, ...rawForDelegation];
19551
20087
  const abilities = this.permissionsToAbilities(entries);
19552
20088
  const prepared = this.wasmBindings.prepareSession({
19553
20089
  abilities,
20090
+ ...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
19554
20091
  address: this.wasmBindings.ensureEip55(session.address),
19555
20092
  chainId: session.chainId,
19556
20093
  domain: this.siweDomain,
@@ -19575,7 +20112,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19575
20112
  }
19576
20113
  const delegation = this.runtimeDelegationFromSession(
19577
20114
  delegatedSession,
19578
- entries,
20115
+ delegatedEntries,
19579
20116
  spaceId,
19580
20117
  session,
19581
20118
  expiresAt
@@ -19589,7 +20126,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19589
20126
  jwk: session.jwk
19590
20127
  },
19591
20128
  delegation,
19592
- operations: this.permissionOperations(entries, spaceId),
20129
+ operations: this.permissionOperations(delegatedEntries, spaceId),
19593
20130
  expiresAt
19594
20131
  });
19595
20132
  delegations.push(delegation);
@@ -19737,7 +20274,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19737
20274
  ];
19738
20275
  const abilities = { kv: { "": kvActions } };
19739
20276
  const now = /* @__PURE__ */ new Date();
19740
- const expiryMs = 60 * 60 * 1e3;
20277
+ const expiryMs = import_sdk_core5.EXPIRY.EPHEMERAL_MS;
19741
20278
  const expirationTime = new Date(now.getTime() + expiryMs);
19742
20279
  const prepared = this.wasmBindings.prepareSession({
19743
20280
  abilities,
@@ -19907,7 +20444,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19907
20444
  * `forceWalletSign` is not set.
19908
20445
  */
19909
20446
  async delegateTo(did, permissions, options) {
19910
- const session = this.auth?.tinyCloudSession;
20447
+ const session = this.currentTinyCloudSession();
19911
20448
  if (!session) {
19912
20449
  throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
19913
20450
  }
@@ -19924,10 +20461,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19924
20461
  "delegateTo requires a non-empty permissions array"
19925
20462
  );
19926
20463
  }
19927
- const expandedEntries = permissions.map((entry) => ({
19928
- ...entry,
19929
- actions: (0, import_sdk_core5.expandActionShortNames)(entry.service, entry.actions)
19930
- }));
20464
+ const expandedEntries = this.expandPermissionEntries(permissions);
19931
20465
  const now = /* @__PURE__ */ new Date();
19932
20466
  const expiryMs = resolveExpiryMs(options?.expiry);
19933
20467
  const expirationTime = new Date(now.getTime() + expiryMs);
@@ -20024,11 +20558,8 @@ var _TinyCloudNode = class _TinyCloudNode {
20024
20558
  * the current session; we build one multi-resource abilities map
20025
20559
  * and emit one signed UCAN covering them all.
20026
20560
  *
20027
- * All entries must share the same target space (the UCAN is
20028
- * scoped to a single space). If they don't, this throws mixing
20029
- * spaces in a single delegation is not supported by the underlying
20030
- * Rust create_delegation call and the resulting UCAN would be
20031
- * under-specified.
20561
+ * Non-encryption entries must share the same target space. Encryption
20562
+ * entries are raw network URNs and do not participate in space grouping.
20032
20563
  *
20033
20564
  * @internal
20034
20565
  */
@@ -20040,15 +20571,18 @@ var _TinyCloudNode = class _TinyCloudNode {
20040
20571
  }
20041
20572
  const resolvedSpaces = /* @__PURE__ */ new Set();
20042
20573
  for (const entry of entries) {
20574
+ if (this.isEncryptionPermissionEntry(entry)) {
20575
+ continue;
20576
+ }
20043
20577
  const spaceId2 = this.resolvePermissionSpace(entry.space, session);
20044
20578
  resolvedSpaces.add(spaceId2);
20045
20579
  }
20046
- if (resolvedSpaces.size !== 1) {
20580
+ if (resolvedSpaces.size > 1) {
20047
20581
  throw new Error(
20048
20582
  `delegateTo: all permission entries must target the same space, got ${resolvedSpaces.size}: ${JSON.stringify([...resolvedSpaces])}`
20049
20583
  );
20050
20584
  }
20051
- const spaceId = [...resolvedSpaces][0];
20585
+ const spaceId = resolvedSpaces.size === 1 ? [...resolvedSpaces][0] : session.spaceId;
20052
20586
  const abilities = {};
20053
20587
  for (const entry of entries) {
20054
20588
  const shortService = import_sdk_core5.SERVICE_LONG_TO_SHORT[entry.service];
@@ -20167,10 +20701,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20167
20701
  return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
20168
20702
  }
20169
20703
  expandPermissionEntries(permissions) {
20170
- return permissions.map((entry) => ({
20171
- ...entry,
20172
- actions: (0, import_sdk_core5.expandActionShortNames)(entry.service, entry.actions)
20173
- }));
20704
+ return (0, import_sdk_core5.expandPermissionEntries)(permissions);
20174
20705
  }
20175
20706
  shortServiceName(service) {
20176
20707
  const short = import_sdk_core5.SERVICE_LONG_TO_SHORT[service];
@@ -20198,11 +20729,32 @@ var _TinyCloudNode = class _TinyCloudNode {
20198
20729
  }
20199
20730
  return abilities;
20200
20731
  }
20732
+ isEncryptionPermissionEntry(entry) {
20733
+ return entry.service === import_sdk_core5.ENCRYPTION_PERMISSION_SERVICE && entry.path.startsWith("urn:tinycloud:encryption:");
20734
+ }
20735
+ permissionsToRawAbilities(entries) {
20736
+ const rawAbilities = {};
20737
+ for (const entry of entries) {
20738
+ if (!this.isEncryptionPermissionEntry(entry)) {
20739
+ continue;
20740
+ }
20741
+ const existing = rawAbilities[entry.path] ?? [];
20742
+ const seen = new Set(existing);
20743
+ for (const action of entry.actions) {
20744
+ if (!seen.has(action)) {
20745
+ existing.push(action);
20746
+ seen.add(action);
20747
+ }
20748
+ }
20749
+ rawAbilities[entry.path] = existing;
20750
+ }
20751
+ return rawAbilities;
20752
+ }
20201
20753
  permissionOperations(entries, spaceId) {
20202
20754
  return entries.flatMap((entry) => {
20203
20755
  const service = this.shortServiceName(entry.service);
20204
20756
  return entry.actions.map((action) => ({
20205
- spaceId,
20757
+ ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
20206
20758
  service,
20207
20759
  path: entry.path,
20208
20760
  action
@@ -20225,7 +20777,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20225
20777
  const spaceId = this.resolvePermissionSpace(entry.space, session);
20226
20778
  const service = this.shortServiceName(entry.service);
20227
20779
  return entry.actions.map((action) => ({
20228
- spaceId,
20780
+ ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
20229
20781
  service,
20230
20782
  path: entry.path,
20231
20783
  action
@@ -20282,24 +20834,40 @@ var _TinyCloudNode = class _TinyCloudNode {
20282
20834
  expiresAt: delegation.expiry
20283
20835
  };
20284
20836
  }
20837
+ installRuntimeGrantFromServiceSession(delegation, session, expiresAt) {
20838
+ const operations = this.operationsFromDelegation(delegation);
20839
+ if (operations.length === 0) {
20840
+ return;
20841
+ }
20842
+ this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
20843
+ (grant) => grant.delegation.cid !== delegation.cid && grant.session.delegationCid !== session.delegationCid
20844
+ );
20845
+ this.runtimePermissionGrants.push({
20846
+ session,
20847
+ delegation,
20848
+ operations,
20849
+ expiresAt
20850
+ });
20851
+ }
20285
20852
  delegatedResourcesForEntries(entries, spaceId) {
20286
20853
  return entries.map((entry) => ({
20287
20854
  service: this.shortServiceName(entry.service),
20288
- space: spaceId,
20855
+ space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
20289
20856
  path: entry.path,
20290
20857
  actions: [...entry.actions]
20291
20858
  }));
20292
20859
  }
20293
20860
  operationsFromDelegation(delegation) {
20294
20861
  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),
20862
+ return resources.flatMap((resource) => {
20863
+ const service = this.invocationServiceName(resource.service);
20864
+ return resource.actions.map((action) => ({
20865
+ ...this.isEncryptionNetworkOperation(service, resource.path) ? { resource: resource.path } : { spaceId: resource.space },
20866
+ service,
20299
20867
  path: resource.path,
20300
20868
  action
20301
- }))
20302
- );
20869
+ }));
20870
+ });
20303
20871
  }
20304
20872
  flatDelegationResources(delegation) {
20305
20873
  const byService = /* @__PURE__ */ new Map();
@@ -20348,7 +20916,13 @@ var _TinyCloudNode = class _TinyCloudNode {
20348
20916
  );
20349
20917
  }
20350
20918
  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);
20919
+ if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
20920
+ return false;
20921
+ }
20922
+ if (granted.resource !== void 0 || requested.resource !== void 0) {
20923
+ return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
20924
+ }
20925
+ return granted.spaceId !== void 0 && requested.spaceId !== void 0 && granted.spaceId === requested.spaceId && this.pathContains(granted.path, requested.path);
20352
20926
  }
20353
20927
  actionContains(grantedAction, requestedAction) {
20354
20928
  if (grantedAction === requestedAction) {
@@ -20363,6 +20937,37 @@ var _TinyCloudNode = class _TinyCloudNode {
20363
20937
  invocationServiceName(service) {
20364
20938
  return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
20365
20939
  }
20940
+ isEncryptionNetworkOperation(service, path) {
20941
+ return service === "encryption" && path.startsWith("urn:tinycloud:encryption:");
20942
+ }
20943
+ operationFromInvokeAnyEntry(entry) {
20944
+ const service = this.invocationServiceName(entry.service);
20945
+ if (typeof entry.resource === "string") {
20946
+ return {
20947
+ resource: entry.resource,
20948
+ service,
20949
+ path: entry.path,
20950
+ action: entry.action
20951
+ };
20952
+ }
20953
+ if (this.isEncryptionNetworkOperation(service, entry.path)) {
20954
+ return {
20955
+ resource: entry.path,
20956
+ service,
20957
+ path: entry.path,
20958
+ action: entry.action
20959
+ };
20960
+ }
20961
+ if (typeof entry.spaceId === "string") {
20962
+ return {
20963
+ spaceId: entry.spaceId,
20964
+ service,
20965
+ path: entry.path,
20966
+ action: entry.action
20967
+ };
20968
+ }
20969
+ return void 0;
20970
+ }
20366
20971
  pathContains(grantedPath, requestedPath) {
20367
20972
  if (grantedPath === "" || grantedPath === "/") {
20368
20973
  return true;
@@ -20601,6 +21206,17 @@ var _TinyCloudNode = class _TinyCloudNode {
20601
21206
  // Not used in session-only mode
20602
21207
  };
20603
21208
  this.trackReceivedDelegation(delegation, this.sessionKeyJwk);
21209
+ this.installRuntimeGrantFromServiceSession(
21210
+ delegation,
21211
+ {
21212
+ delegationHeader: session2.delegationHeader,
21213
+ delegationCid: session2.delegationCid,
21214
+ spaceId: session2.spaceId,
21215
+ verificationMethod: session2.verificationMethod,
21216
+ jwk: session2.jwk
21217
+ },
21218
+ delegation.expiry
21219
+ );
20604
21220
  return new DelegatedAccess(session2, delegation, targetHost, this.wasmBindings.invoke);
20605
21221
  }
20606
21222
  const mySession = this.auth?.tinyCloudSession;
@@ -20612,6 +21228,10 @@ var _TinyCloudNode = class _TinyCloudNode {
20612
21228
  const kvActions = delegation.actions.filter((a) => a.startsWith("tinycloud.kv/"));
20613
21229
  const sqlActions = delegation.actions.filter((a) => a.startsWith("tinycloud.sql/"));
20614
21230
  const duckdbActions = delegation.actions.filter((a) => a.startsWith("tinycloud.duckdb/"));
21231
+ const encryptionActions = delegation.actions.filter(
21232
+ (a) => a.startsWith("tinycloud.encryption/")
21233
+ );
21234
+ const rawAbilities = {};
20615
21235
  if (kvActions.length > 0) {
20616
21236
  abilities.kv = { [delegation.path]: kvActions };
20617
21237
  }
@@ -20621,6 +21241,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20621
21241
  if (duckdbActions.length > 0) {
20622
21242
  abilities.duckdb = { [delegation.path]: duckdbActions };
20623
21243
  }
21244
+ if (encryptionActions.length > 0 && delegation.path.startsWith("urn:tinycloud:encryption:")) {
21245
+ rawAbilities[delegation.path] = encryptionActions;
21246
+ }
20624
21247
  const now = /* @__PURE__ */ new Date();
20625
21248
  const maxExpiry = new Date(now.getTime() + 60 * 60 * 1e3);
20626
21249
  const expirationTime = delegation.expiry < maxExpiry ? delegation.expiry : maxExpiry;
@@ -20633,7 +21256,8 @@ var _TinyCloudNode = class _TinyCloudNode {
20633
21256
  expirationTime: expirationTime.toISOString(),
20634
21257
  spaceId: delegation.spaceId,
20635
21258
  jwk,
20636
- parents: [delegation.cid]
21259
+ parents: [delegation.cid],
21260
+ ...Object.keys(rawAbilities).length > 0 ? { rawAbilities } : {}
20637
21261
  });
20638
21262
  const signature2 = await this.signer.signMessage(prepared.siwe);
20639
21263
  const invokerSession = this.wasmBindings.completeSessionSetup({
@@ -20660,6 +21284,17 @@ var _TinyCloudNode = class _TinyCloudNode {
20660
21284
  signature: signature2
20661
21285
  };
20662
21286
  this.trackReceivedDelegation(delegation, jwk);
21287
+ this.installRuntimeGrantFromServiceSession(
21288
+ delegation,
21289
+ {
21290
+ delegationHeader: session.delegationHeader,
21291
+ delegationCid: session.delegationCid,
21292
+ spaceId: session.spaceId,
21293
+ verificationMethod: session.verificationMethod,
21294
+ jwk: session.jwk
21295
+ },
21296
+ expirationTime
21297
+ );
20663
21298
  return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);
20664
21299
  }
20665
21300
  /**
@@ -20924,6 +21559,7 @@ var import_sdk_core16 = require("@tinycloud/sdk-core");
20924
21559
  var import_sdk_core17 = require("@tinycloud/sdk-core");
20925
21560
  var import_sdk_core18 = require("@tinycloud/sdk-core");
20926
21561
  var import_sdk_core19 = require("@tinycloud/sdk-core");
21562
+ var import_sdk_core20 = require("@tinycloud/sdk-core");
20927
21563
  // Annotate the CommonJS export names for ESM import in node:
20928
21564
  0 && (module.exports = {
20929
21565
  ACCOUNT_REGISTRY_PATH,
@@ -20931,8 +21567,14 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
20931
21567
  AutoApproveSpaceCreationHandler,
20932
21568
  CapabilityKeyRegistry,
20933
21569
  CapabilityKeyRegistryErrorCodes,
21570
+ DECRYPT_ACTION,
21571
+ DECRYPT_FACT_TYPE,
21572
+ DECRYPT_RESULT_TYPE,
21573
+ DEFAULT_ENCRYPTION_ALG,
21574
+ DEFAULT_KEY_VERSION,
20934
21575
  DEFAULT_MANIFEST_SPACE,
20935
21576
  DEFAULT_MANIFEST_VERSION,
21577
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
20936
21578
  DataVaultService,
20937
21579
  DatabaseHandle,
20938
21580
  DelegatedAccess,
@@ -20941,17 +21583,25 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
20941
21583
  DuckDbAction,
20942
21584
  DuckDbDatabaseHandle,
20943
21585
  DuckDbService,
21586
+ ENCRYPTION_NETWORK_URN_PREFIX,
21587
+ ENCRYPTION_SERVICE,
21588
+ ENCRYPTION_SERVICE_SHORT,
21589
+ ENVELOPE_VERSION,
21590
+ EncryptionService,
20944
21591
  FileSessionStorage,
20945
21592
  HooksService,
20946
21593
  KVService,
20947
21594
  ManifestValidationError,
20948
21595
  MemorySessionStorage,
21596
+ NETWORK_NAME_PATTERN,
21597
+ NetworkIdError,
20949
21598
  NodeUserAuthorization,
20950
21599
  NodeWasmBindings,
20951
21600
  PermissionNotInManifestError,
20952
21601
  PrefixedKVService,
20953
21602
  PrivateKeySigner,
20954
21603
  ProtocolMismatchError,
21604
+ SECRET_NAME_RE,
20955
21605
  SQLAction,
20956
21606
  SQLService,
20957
21607
  SecretsService,
@@ -20965,11 +21615,22 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
20965
21615
  TinyCloud,
20966
21616
  TinyCloudNode,
20967
21617
  UnsupportedFeatureError,
21618
+ VAULT_PERMISSION_SERVICE,
20968
21619
  VaultHeaders,
20969
21620
  VaultPublicSpaceKVActions,
20970
21621
  VersionCheckError,
20971
21622
  WasmKeyProvider,
21623
+ buildCanonicalDecryptRequest,
21624
+ buildDecryptAttenuation,
21625
+ buildDecryptFacts,
21626
+ buildDecryptInvocation,
21627
+ buildNetworkId,
20972
21628
  buildSpaceUri,
21629
+ canonicalHashHex,
21630
+ canonicalSignedResponse,
21631
+ canonicalizeEncryptionJson,
21632
+ canonicalizeSecretScope,
21633
+ checkDecryptInvocationInput,
20973
21634
  checkNodeInfo,
20974
21635
  composeManifestRequest,
20975
21636
  createCapabilityKeyRegistry,
@@ -20977,19 +21638,42 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
20977
21638
  createSpaceService,
20978
21639
  createVaultCrypto,
20979
21640
  createWasmKeyProvider,
21641
+ decryptEnvelopeWithKey,
20980
21642
  defaultSignStrategy,
20981
21643
  defaultSpaceCreationHandler,
21644
+ deriveSignedReceiverKey,
20982
21645
  deserializeDelegation,
21646
+ discoverNetwork,
21647
+ encryptToNetwork,
21648
+ encryptionBase64Decode,
21649
+ encryptionBase64Encode,
21650
+ encryptionError,
21651
+ encryptionUtf8Decode,
21652
+ encryptionUtf8Encode,
21653
+ ensureNetworkUsableForDecrypt,
20983
21654
  expandActionShortNames,
21655
+ expandPermissionEntries,
21656
+ expandPermissionEntry,
21657
+ generateRandomReceiverKey,
21658
+ hexDecode,
21659
+ hexEncode,
20984
21660
  isCapabilitySubset,
21661
+ isNetworkId,
20985
21662
  loadManifest,
20986
21663
  makePublicSpaceId,
21664
+ networkDiscoveryKey,
21665
+ openWrappedKey,
20987
21666
  parseExpiry,
21667
+ parseNetworkId,
20988
21668
  parseSpaceUri,
20989
21669
  resolveManifest,
21670
+ resolveSecretListPrefix,
21671
+ resolveSecretPath,
20990
21672
  resourceCapabilitiesToSpaceAbilitiesMap,
20991
21673
  serializeDelegation,
20992
- validateManifest
21674
+ validateEnvelope,
21675
+ validateManifest,
21676
+ verifyDecryptResponse
20993
21677
  });
20994
21678
  /*! Bundled license information:
20995
21679