@tinycloud/node-sdk 2.7.0-beta.2 → 2.7.0-beta.4

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,143 +17025,147 @@ 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_core11.ACCOUNT_REGISTRY_PATH,
17029
- ACCOUNT_REGISTRY_SPACE: () => import_sdk_core11.ACCOUNT_REGISTRY_SPACE,
17028
+ ACCOUNT_REGISTRY_PATH: () => import_sdk_core12.ACCOUNT_REGISTRY_PATH,
17029
+ ACCOUNT_REGISTRY_SPACE: () => import_sdk_core12.ACCOUNT_REGISTRY_SPACE,
17030
17030
  AccountService: () => import_sdk_core3.AccountService,
17031
- AutoApproveSpaceCreationHandler: () => import_sdk_core10.AutoApproveSpaceCreationHandler,
17032
- CapabilityKeyRegistry: () => import_sdk_core19.CapabilityKeyRegistry,
17033
- CapabilityKeyRegistryErrorCodes: () => import_sdk_core19.CapabilityKeyRegistryErrorCodes,
17034
- DECRYPT_ACTION: () => import_sdk_core16.DECRYPT_ACTION,
17035
- DECRYPT_FACT_TYPE: () => import_sdk_core16.DECRYPT_FACT_TYPE,
17036
- DECRYPT_RESULT_TYPE: () => import_sdk_core16.DECRYPT_RESULT_TYPE,
17037
- DEFAULT_ENCRYPTION_ALG: () => import_sdk_core16.DEFAULT_ENCRYPTION_ALG,
17038
- DEFAULT_KEY_VERSION: () => import_sdk_core16.DEFAULT_KEY_VERSION,
17039
- DEFAULT_MANIFEST_SPACE: () => import_sdk_core11.DEFAULT_MANIFEST_SPACE,
17040
- DEFAULT_MANIFEST_VERSION: () => import_sdk_core11.DEFAULT_MANIFEST_VERSION,
17041
- DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core12.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
17042
- DataVaultService: () => import_sdk_core15.DataVaultService,
17043
- DatabaseHandle: () => import_sdk_core13.DatabaseHandle,
17031
+ AutoApproveSpaceCreationHandler: () => import_sdk_core11.AutoApproveSpaceCreationHandler,
17032
+ CapabilityKeyRegistry: () => import_sdk_core20.CapabilityKeyRegistry,
17033
+ CapabilityKeyRegistryErrorCodes: () => import_sdk_core20.CapabilityKeyRegistryErrorCodes,
17034
+ CaveatedDelegationUnsupportedError: () => import_sdk_core12.CaveatedDelegationUnsupportedError,
17035
+ DECRYPT_ACTION: () => import_sdk_core17.DECRYPT_ACTION,
17036
+ DECRYPT_FACT_TYPE: () => import_sdk_core17.DECRYPT_FACT_TYPE,
17037
+ DECRYPT_RESULT_TYPE: () => import_sdk_core17.DECRYPT_RESULT_TYPE,
17038
+ DEFAULT_ENCRYPTION_ALG: () => import_sdk_core17.DEFAULT_ENCRYPTION_ALG,
17039
+ DEFAULT_KEY_VERSION: () => import_sdk_core17.DEFAULT_KEY_VERSION,
17040
+ DEFAULT_MANIFEST_SPACE: () => import_sdk_core12.DEFAULT_MANIFEST_SPACE,
17041
+ DEFAULT_MANIFEST_VERSION: () => import_sdk_core12.DEFAULT_MANIFEST_VERSION,
17042
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core13.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
17043
+ DataVaultService: () => import_sdk_core16.DataVaultService,
17044
+ DatabaseHandle: () => import_sdk_core14.DatabaseHandle,
17045
+ DecryptTransportResponseError: () => import_sdk_core17.DecryptTransportResponseError,
17044
17046
  DelegatedAccess: () => DelegatedAccess,
17045
- DelegationErrorCodes: () => import_sdk_core18.DelegationErrorCodes,
17046
- DelegationManager: () => import_sdk_core18.DelegationManager,
17047
- DuckDbAction: () => import_sdk_core14.DuckDbAction,
17048
- DuckDbDatabaseHandle: () => import_sdk_core14.DuckDbDatabaseHandle,
17049
- DuckDbService: () => import_sdk_core14.DuckDbService,
17050
- ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_core16.ENCRYPTION_NETWORK_URN_PREFIX,
17051
- ENCRYPTION_SERVICE: () => import_sdk_core16.ENCRYPTION_SERVICE,
17052
- ENCRYPTION_SERVICE_SHORT: () => import_sdk_core16.ENCRYPTION_SERVICE_SHORT,
17053
- ENVELOPE_VERSION: () => import_sdk_core16.ENVELOPE_VERSION,
17054
- EncryptionService: () => import_sdk_core16.EncryptionService,
17047
+ DelegationErrorCodes: () => import_sdk_core19.DelegationErrorCodes,
17048
+ DelegationManager: () => import_sdk_core19.DelegationManager,
17049
+ DuckDbAction: () => import_sdk_core15.DuckDbAction,
17050
+ DuckDbDatabaseHandle: () => import_sdk_core15.DuckDbDatabaseHandle,
17051
+ DuckDbService: () => import_sdk_core15.DuckDbService,
17052
+ ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_core17.ENCRYPTION_NETWORK_URN_PREFIX,
17053
+ ENCRYPTION_SERVICE: () => import_sdk_core17.ENCRYPTION_SERVICE,
17054
+ ENCRYPTION_SERVICE_SHORT: () => import_sdk_core17.ENCRYPTION_SERVICE_SHORT,
17055
+ ENVELOPE_VERSION: () => import_sdk_core17.ENVELOPE_VERSION,
17056
+ EncryptionService: () => import_sdk_core17.EncryptionService,
17055
17057
  FileSessionStorage: () => FileSessionStorage,
17056
- HooksService: () => import_sdk_core17.HooksService,
17057
- IdentityParseError: () => import_sdk_core10.IdentityParseError,
17058
- KVService: () => import_sdk_core12.KVService,
17059
- ManifestValidationError: () => import_sdk_core11.ManifestValidationError,
17058
+ HooksService: () => import_sdk_core18.HooksService,
17059
+ IdentityParseError: () => import_sdk_core11.IdentityParseError,
17060
+ KVService: () => import_sdk_core13.KVService,
17061
+ ManifestValidationError: () => import_sdk_core12.ManifestValidationError,
17060
17062
  MemorySessionStorage: () => MemorySessionStorage,
17061
- NETWORK_NAME_PATTERN: () => import_sdk_core16.NETWORK_NAME_PATTERN,
17062
- NetworkIdError: () => import_sdk_core16.NetworkIdError,
17063
+ NETWORK_NAME_PATTERN: () => import_sdk_core17.NETWORK_NAME_PATTERN,
17064
+ NetworkIdError: () => import_sdk_core17.NetworkIdError,
17063
17065
  NodeUserAuthorization: () => NodeUserAuthorization,
17064
17066
  NodeWasmBindings: () => NodeWasmBindings,
17065
- PermissionNotInManifestError: () => import_sdk_core11.PermissionNotInManifestError,
17066
- PrefixedKVService: () => import_sdk_core12.PrefixedKVService,
17067
+ PermissionNotInManifestError: () => import_sdk_core12.PermissionNotInManifestError,
17068
+ PrefixedKVService: () => import_sdk_core13.PrefixedKVService,
17067
17069
  PrivateKeySigner: () => PrivateKeySigner,
17068
- ProtocolMismatchError: () => import_sdk_core21.ProtocolMismatchError,
17069
- SECRET_NAME_RE: () => import_sdk_core15.SECRET_NAME_RE,
17070
- SQLAction: () => import_sdk_core13.SQLAction,
17071
- SQLService: () => import_sdk_core13.SQLService,
17072
- SecretsService: () => import_sdk_core15.SecretsService,
17073
- ServiceContext: () => import_sdk_core22.ServiceContext,
17074
- SessionExpiredError: () => import_sdk_core11.SessionExpiredError,
17075
- SharingService: () => import_sdk_core18.SharingService,
17076
- SilentNotificationHandler: () => import_sdk_core10.SilentNotificationHandler,
17077
- Space: () => import_sdk_core20.Space,
17078
- SpaceErrorCodes: () => import_sdk_core20.SpaceErrorCodes,
17079
- SpaceService: () => import_sdk_core20.SpaceService,
17080
- TinyCloud: () => import_sdk_core9.TinyCloud,
17081
- TinyCloudDebugLogger: () => import_sdk_core10.TinyCloudDebugLogger,
17070
+ ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
17071
+ SECRET_NAME_RE: () => import_sdk_core16.SECRET_NAME_RE,
17072
+ SQLAction: () => import_sdk_core14.SQLAction,
17073
+ SQLService: () => import_sdk_core14.SQLService,
17074
+ SecretsService: () => import_sdk_core16.SecretsService,
17075
+ ServiceContext: () => import_sdk_core23.ServiceContext,
17076
+ SessionExpiredError: () => import_sdk_core12.SessionExpiredError,
17077
+ SharingService: () => import_sdk_core19.SharingService,
17078
+ SilentNotificationHandler: () => import_sdk_core11.SilentNotificationHandler,
17079
+ Space: () => import_sdk_core21.Space,
17080
+ SpaceErrorCodes: () => import_sdk_core21.SpaceErrorCodes,
17081
+ SpaceService: () => import_sdk_core21.SpaceService,
17082
+ TinyCloud: () => import_sdk_core10.TinyCloud,
17083
+ TinyCloudDebugLogger: () => import_sdk_core11.TinyCloudDebugLogger,
17082
17084
  TinyCloudNode: () => TinyCloudNode,
17083
- UnsupportedFeatureError: () => import_sdk_core21.UnsupportedFeatureError,
17084
- VAULT_PERMISSION_SERVICE: () => import_sdk_core11.VAULT_PERMISSION_SERVICE,
17085
- VaultHeaders: () => import_sdk_core15.VaultHeaders,
17086
- VaultPublicSpaceKVActions: () => import_sdk_core15.VaultPublicSpaceKVActions,
17087
- VersionCheckError: () => import_sdk_core21.VersionCheckError,
17085
+ UnsupportedFeatureError: () => import_sdk_core22.UnsupportedFeatureError,
17086
+ UnsupportedSessionRestoreError: () => UnsupportedSessionRestoreError,
17087
+ VAULT_PERMISSION_SERVICE: () => import_sdk_core12.VAULT_PERMISSION_SERVICE,
17088
+ VaultHeaders: () => import_sdk_core16.VaultHeaders,
17089
+ VaultPublicSpaceKVActions: () => import_sdk_core16.VaultPublicSpaceKVActions,
17090
+ VersionCheckError: () => import_sdk_core22.VersionCheckError,
17088
17091
  WasmKeyProvider: () => WasmKeyProvider,
17089
- addressStorageKey: () => import_sdk_core10.addressStorageKey,
17090
- buildCanonicalDecryptRequest: () => import_sdk_core16.buildCanonicalDecryptRequest,
17091
- buildDecryptAttenuation: () => import_sdk_core16.buildDecryptAttenuation,
17092
- buildDecryptFacts: () => import_sdk_core16.buildDecryptFacts,
17093
- buildDecryptInvocation: () => import_sdk_core16.buildDecryptInvocation,
17094
- buildNetworkId: () => import_sdk_core16.buildNetworkId,
17095
- buildSpaceUri: () => import_sdk_core20.buildSpaceUri,
17096
- canonicalHashHex: () => import_sdk_core16.canonicalHashHex,
17097
- canonicalSignedResponse: () => import_sdk_core16.canonicalSignedResponse,
17098
- canonicalizeAddress: () => import_sdk_core10.canonicalizeAddress,
17099
- canonicalizeDid: () => import_sdk_core10.canonicalizeDid,
17100
- canonicalizeDidUrl: () => import_sdk_core10.canonicalizeDidUrl,
17101
- canonicalizeEncryptionJson: () => import_sdk_core16.canonicalizeEncryptionJson,
17102
- canonicalizeNetworkId: () => import_sdk_core10.canonicalizeNetworkId,
17103
- canonicalizeSecretScope: () => import_sdk_core15.canonicalizeSecretScope,
17104
- checkDecryptInvocationInput: () => import_sdk_core16.checkDecryptInvocationInput,
17105
- checkNodeInfo: () => import_sdk_core21.checkNodeInfo,
17106
- clearTinyCloudDebugLogs: () => import_sdk_core10.clearTinyCloudDebugLogs,
17107
- composeManifestRequest: () => import_sdk_core11.composeManifestRequest,
17108
- createCapabilityKeyRegistry: () => import_sdk_core19.createCapabilityKeyRegistry,
17092
+ activateValidatedRuntimeDelegation: () => activateValidatedRuntimeDelegation,
17093
+ addressStorageKey: () => import_sdk_core11.addressStorageKey,
17094
+ buildCanonicalDecryptRequest: () => import_sdk_core17.buildCanonicalDecryptRequest,
17095
+ buildDecryptAttenuation: () => import_sdk_core17.buildDecryptAttenuation,
17096
+ buildDecryptFacts: () => import_sdk_core17.buildDecryptFacts,
17097
+ buildDecryptInvocation: () => import_sdk_core17.buildDecryptInvocation,
17098
+ buildNetworkId: () => import_sdk_core17.buildNetworkId,
17099
+ buildSpaceUri: () => import_sdk_core21.buildSpaceUri,
17100
+ canonicalHashHex: () => import_sdk_core17.canonicalHashHex,
17101
+ canonicalSignedResponse: () => import_sdk_core17.canonicalSignedResponse,
17102
+ canonicalizeAddress: () => import_sdk_core11.canonicalizeAddress,
17103
+ canonicalizeDid: () => import_sdk_core11.canonicalizeDid,
17104
+ canonicalizeDidUrl: () => import_sdk_core11.canonicalizeDidUrl,
17105
+ canonicalizeEncryptionJson: () => import_sdk_core17.canonicalizeEncryptionJson,
17106
+ canonicalizeNetworkId: () => import_sdk_core11.canonicalizeNetworkId,
17107
+ canonicalizeSecretScope: () => import_sdk_core16.canonicalizeSecretScope,
17108
+ checkDecryptInvocationInput: () => import_sdk_core17.checkDecryptInvocationInput,
17109
+ checkNodeInfo: () => import_sdk_core22.checkNodeInfo,
17110
+ clearTinyCloudDebugLogs: () => import_sdk_core11.clearTinyCloudDebugLogs,
17111
+ composeManifestRequest: () => import_sdk_core12.composeManifestRequest,
17112
+ createCapabilityKeyRegistry: () => import_sdk_core20.createCapabilityKeyRegistry,
17109
17113
  createOpenKeyCallbackSigningStrategy: () => import_sdk_core.createOpenKeyCallbackSigningStrategy,
17110
- createSharingService: () => import_sdk_core18.createSharingService,
17111
- createSpaceService: () => import_sdk_core20.createSpaceService,
17112
- createVaultCrypto: () => import_sdk_core15.createVaultCrypto,
17114
+ createSharingService: () => import_sdk_core19.createSharingService,
17115
+ createSpaceService: () => import_sdk_core21.createSpaceService,
17116
+ createVaultCrypto: () => import_sdk_core16.createVaultCrypto,
17113
17117
  createWasmKeyProvider: () => createWasmKeyProvider,
17114
- decryptEnvelopeWithKey: () => import_sdk_core16.decryptEnvelopeWithKey,
17118
+ decryptEnvelopeWithKey: () => import_sdk_core17.decryptEnvelopeWithKey,
17115
17119
  defaultSignStrategy: () => defaultSignStrategy,
17116
- defaultSpaceCreationHandler: () => import_sdk_core10.defaultSpaceCreationHandler,
17117
- deriveSignedReceiverKey: () => import_sdk_core16.deriveSignedReceiverKey,
17120
+ defaultSpaceCreationHandler: () => import_sdk_core11.defaultSpaceCreationHandler,
17121
+ deriveSignedReceiverKey: () => import_sdk_core17.deriveSignedReceiverKey,
17118
17122
  deserializeDelegation: () => deserializeDelegation,
17119
- didCacheKey: () => import_sdk_core10.didCacheKey,
17120
- didEquals: () => import_sdk_core10.didEquals,
17121
- disableTinyCloudDebug: () => import_sdk_core10.disableTinyCloudDebug,
17122
- discoverNetwork: () => import_sdk_core16.discoverNetwork,
17123
- enableTinyCloudDebug: () => import_sdk_core10.enableTinyCloudDebug,
17124
- encryptToNetwork: () => import_sdk_core16.encryptToNetwork,
17125
- encryptionBase64Decode: () => import_sdk_core16.encryptionBase64Decode,
17126
- encryptionBase64Encode: () => import_sdk_core16.encryptionBase64Encode,
17127
- encryptionError: () => import_sdk_core16.encryptionError,
17128
- encryptionUtf8Decode: () => import_sdk_core16.encryptionUtf8Decode,
17129
- encryptionUtf8Encode: () => import_sdk_core16.encryptionUtf8Encode,
17130
- ensureNetworkUsableForDecrypt: () => import_sdk_core16.ensureNetworkUsableForDecrypt,
17131
- expandActionShortNames: () => import_sdk_core11.expandActionShortNames,
17132
- expandPermissionEntries: () => import_sdk_core11.expandPermissionEntries,
17133
- expandPermissionEntry: () => import_sdk_core11.expandPermissionEntry,
17134
- generateRandomReceiverKey: () => import_sdk_core16.generateRandomReceiverKey,
17135
- getTinyCloudDebugLogs: () => import_sdk_core10.getTinyCloudDebugLogs,
17123
+ didCacheKey: () => import_sdk_core11.didCacheKey,
17124
+ didEquals: () => import_sdk_core11.didEquals,
17125
+ disableTinyCloudDebug: () => import_sdk_core11.disableTinyCloudDebug,
17126
+ discoverNetwork: () => import_sdk_core17.discoverNetwork,
17127
+ enableTinyCloudDebug: () => import_sdk_core11.enableTinyCloudDebug,
17128
+ encryptToNetwork: () => import_sdk_core17.encryptToNetwork,
17129
+ encryptionBase64Decode: () => import_sdk_core17.encryptionBase64Decode,
17130
+ encryptionBase64Encode: () => import_sdk_core17.encryptionBase64Encode,
17131
+ encryptionError: () => import_sdk_core17.encryptionError,
17132
+ encryptionUtf8Decode: () => import_sdk_core17.encryptionUtf8Decode,
17133
+ encryptionUtf8Encode: () => import_sdk_core17.encryptionUtf8Encode,
17134
+ ensureNetworkUsableForDecrypt: () => import_sdk_core17.ensureNetworkUsableForDecrypt,
17135
+ expandActionShortNames: () => import_sdk_core12.expandActionShortNames,
17136
+ expandPermissionEntries: () => import_sdk_core12.expandPermissionEntries,
17137
+ expandPermissionEntry: () => import_sdk_core12.expandPermissionEntry,
17138
+ generateRandomReceiverKey: () => import_sdk_core17.generateRandomReceiverKey,
17139
+ getTinyCloudDebugLogs: () => import_sdk_core11.getTinyCloudDebugLogs,
17136
17140
  grantAuthRequest: () => grantAuthRequest,
17137
- hexDecode: () => import_sdk_core16.hexDecode,
17138
- hexEncode: () => import_sdk_core16.hexEncode,
17139
- installTinyCloudDebugGlobals: () => import_sdk_core10.installTinyCloudDebugGlobals,
17140
- isCapabilitySubset: () => import_sdk_core11.isCapabilitySubset,
17141
- isEvmAddress: () => import_sdk_core10.isEvmAddress,
17142
- isNetworkId: () => import_sdk_core16.isNetworkId,
17143
- loadManifest: () => import_sdk_core11.loadManifest,
17144
- makePkhSpaceId: () => import_sdk_core10.makePkhSpaceId,
17145
- makePublicSpaceId: () => import_sdk_core20.makePublicSpaceId,
17146
- networkDiscoveryKey: () => import_sdk_core16.networkDiscoveryKey,
17147
- openWrappedKey: () => import_sdk_core16.openWrappedKey,
17148
- parseCanonicalNetworkId: () => import_sdk_core10.parseCanonicalNetworkId,
17149
- parseExpiry: () => import_sdk_core11.parseExpiry,
17150
- parseNetworkId: () => import_sdk_core16.parseNetworkId,
17151
- parsePkhDid: () => import_sdk_core10.parsePkhDid,
17152
- parseSpaceUri: () => import_sdk_core20.parseSpaceUri,
17153
- pkhDid: () => import_sdk_core10.pkhDid,
17154
- principalDid: () => import_sdk_core10.principalDid,
17155
- principalDidEquals: () => import_sdk_core10.principalDidEquals,
17156
- resolveManifest: () => import_sdk_core11.resolveManifest,
17157
- resolveSecretListPrefix: () => import_sdk_core15.resolveSecretListPrefix,
17158
- resolveSecretPath: () => import_sdk_core15.resolveSecretPath,
17159
- resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core11.resourceCapabilitiesToSpaceAbilitiesMap,
17141
+ hexDecode: () => import_sdk_core17.hexDecode,
17142
+ hexEncode: () => import_sdk_core17.hexEncode,
17143
+ installTinyCloudDebugGlobals: () => import_sdk_core11.installTinyCloudDebugGlobals,
17144
+ isCapabilitySubset: () => import_sdk_core12.isCapabilitySubset,
17145
+ isEvmAddress: () => import_sdk_core11.isEvmAddress,
17146
+ isNetworkId: () => import_sdk_core17.isNetworkId,
17147
+ loadManifest: () => import_sdk_core12.loadManifest,
17148
+ makePkhSpaceId: () => import_sdk_core11.makePkhSpaceId,
17149
+ makePublicSpaceId: () => import_sdk_core21.makePublicSpaceId,
17150
+ networkDiscoveryKey: () => import_sdk_core17.networkDiscoveryKey,
17151
+ openWrappedKey: () => import_sdk_core17.openWrappedKey,
17152
+ parseCanonicalNetworkId: () => import_sdk_core11.parseCanonicalNetworkId,
17153
+ parseExpiry: () => import_sdk_core12.parseExpiry,
17154
+ parseNetworkId: () => import_sdk_core17.parseNetworkId,
17155
+ parsePkhDid: () => import_sdk_core11.parsePkhDid,
17156
+ parseSpaceUri: () => import_sdk_core21.parseSpaceUri,
17157
+ pkhDid: () => import_sdk_core11.pkhDid,
17158
+ principalDid: () => import_sdk_core11.principalDid,
17159
+ principalDidEquals: () => import_sdk_core11.principalDidEquals,
17160
+ resolveManifest: () => import_sdk_core12.resolveManifest,
17161
+ resolveSecretListPrefix: () => import_sdk_core16.resolveSecretListPrefix,
17162
+ resolveSecretPath: () => import_sdk_core16.resolveSecretPath,
17163
+ resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core12.resourceCapabilitiesToSpaceAbilitiesMap,
17160
17164
  serializeDelegation: () => serializeDelegation,
17161
- tinyCloudDebugLogger: () => import_sdk_core10.tinyCloudDebugLogger,
17162
- validateEnvelope: () => import_sdk_core16.validateEnvelope,
17163
- validateManifest: () => import_sdk_core11.validateManifest,
17164
- verifyDecryptResponse: () => import_sdk_core16.verifyDecryptResponse
17165
+ tinyCloudDebugLogger: () => import_sdk_core11.tinyCloudDebugLogger,
17166
+ validateEnvelope: () => import_sdk_core17.validateEnvelope,
17167
+ validateManifest: () => import_sdk_core12.validateManifest,
17168
+ verifyDecryptResponse: () => import_sdk_core17.verifyDecryptResponse
17165
17169
  });
17166
17170
  module.exports = __toCommonJS(index_exports);
17167
17171
 
@@ -17178,6 +17182,7 @@ var _NodeWasmBindings = class _NodeWasmBindings {
17178
17182
  this.makeSpaceId = import_node_sdk_wasm.makeSpaceId;
17179
17183
  this.createDelegation = import_node_sdk_wasm.createDelegation;
17180
17184
  this.parseRecapFromSiwe = import_node_sdk_wasm.parseRecapFromSiwe;
17185
+ this.parseVerifiedRecapFromSiwe = import_node_sdk_wasm.parseVerifiedRecapFromSiwe;
17181
17186
  this.generateHostSIWEMessage = import_node_sdk_wasm.generateHostSIWEMessage;
17182
17187
  this.siweToDelegationHeaders = import_node_sdk_wasm.siweToDelegationHeaders;
17183
17188
  this.protocolVersion = import_node_sdk_wasm.protocolVersion;
@@ -17194,6 +17199,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
17194
17199
  _NodeWasmBindings.panicHookInitialized = true;
17195
17200
  }
17196
17201
  }
17202
+ validatePersistedSession(proof) {
17203
+ return (0, import_node_sdk_wasm.validatePersistedSession)(proof);
17204
+ }
17197
17205
  createSessionManager() {
17198
17206
  return new import_node_sdk_wasm.TCWSessionManager();
17199
17207
  }
@@ -17267,6 +17275,7 @@ var PrivateKeySigner = class {
17267
17275
 
17268
17276
  // src/TinyCloudNode.ts
17269
17277
  var import_sdk_core7 = require("@tinycloud/sdk-core");
17278
+ var import_sdk_services = require("@tinycloud/sdk-services");
17270
17279
 
17271
17280
  // src/authorization/NodeUserAuthorization.ts
17272
17281
  var import_sdk_core2 = require("@tinycloud/sdk-core");
@@ -17487,6 +17496,30 @@ var NodeUserAuthorization = class {
17487
17496
  this.tinycloudHosts = [...hosts];
17488
17497
  }
17489
17498
  }
17499
+ /** @internal Atomically adopt the state staged by TinyCloudNode.restoreSession. */
17500
+ installRestoredSession(sessionManager, session, hosts) {
17501
+ this.sessionManager = sessionManager;
17502
+ this.tinycloudHosts = hosts && hosts.length > 0 ? [...hosts] : void 0;
17503
+ this._lastActivationSkippedSpaceIds = [];
17504
+ if (!session) {
17505
+ this._session = void 0;
17506
+ this._tinyCloudSession = void 0;
17507
+ this._address = void 0;
17508
+ this._chainId = void 0;
17509
+ return;
17510
+ }
17511
+ this._tinyCloudSession = { ...session };
17512
+ this._address = session.address;
17513
+ this._chainId = session.chainId;
17514
+ this._session = {
17515
+ address: session.address,
17516
+ walletAddress: session.address,
17517
+ chainId: session.chainId,
17518
+ sessionKey: session.sessionKey,
17519
+ siwe: session.siwe,
17520
+ signature: session.signature
17521
+ };
17522
+ }
17490
17523
  /**
17491
17524
  * Ensure `tinycloudHosts` are resolved before a host-needing call.
17492
17525
  *
@@ -18678,6 +18711,9 @@ var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
18678
18711
  var NETWORK_CREATE_ACTION2 = import_sdk_core7.ENCRYPTION.NETWORK_CREATE;
18679
18712
  var DECRYPT_ACTION2 = import_sdk_core7.ENCRYPTION.DECRYPT;
18680
18713
  var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
18714
+ function isSecretPayload(value) {
18715
+ return typeof value === "object" && value !== null && "value" in value && typeof value.value === "string" && "createdAt" in value && typeof value.createdAt === "string" && "updatedAt" in value && typeof value.updatedAt === "string";
18716
+ }
18681
18717
  var ROOT_DELEGATION_ACTIONS = [
18682
18718
  import_sdk_core7.KV.PUT,
18683
18719
  import_sdk_core7.KV.GET,
@@ -18732,6 +18768,141 @@ function didPrincipalMatches2(actual, expected) {
18732
18768
  return actual === expected;
18733
18769
  }
18734
18770
  }
18771
+ function clonePersistedSessionJwk(jwk) {
18772
+ if (jwk === null || typeof jwk !== "object" || Array.isArray(jwk)) {
18773
+ throw new Error("Persisted session has an invalid private Ed25519 session key.");
18774
+ }
18775
+ try {
18776
+ const serialized = JSON.stringify(jwk);
18777
+ const cloned = serialized === void 0 ? void 0 : JSON.parse(serialized);
18778
+ if (cloned === null || typeof cloned !== "object" || Array.isArray(cloned)) {
18779
+ throw new Error("invalid JWK object");
18780
+ }
18781
+ return cloned;
18782
+ } catch {
18783
+ throw new Error("Persisted session has an invalid private Ed25519 session key.");
18784
+ }
18785
+ }
18786
+ function cloneRecapCaveats(caveats) {
18787
+ if (!caveats) return [];
18788
+ const cloneJson = (value) => {
18789
+ if (value === null || typeof value === "boolean" || typeof value === "string") {
18790
+ return value;
18791
+ }
18792
+ if (typeof value === "number") {
18793
+ if (Number.isFinite(value)) return value;
18794
+ throw new Error("ReCap caveats must contain only JSON values.");
18795
+ }
18796
+ if (Array.isArray(value)) return value.map(cloneJson);
18797
+ if (typeof value === "object") {
18798
+ const prototype = Object.getPrototypeOf(value);
18799
+ if (prototype !== Object.prototype && prototype !== null) {
18800
+ throw new Error("ReCap caveats must contain only JSON values.");
18801
+ }
18802
+ const copy = /* @__PURE__ */ Object.create(null);
18803
+ for (const [key2, nested] of Object.entries(value)) {
18804
+ copy[key2] = cloneJson(nested);
18805
+ }
18806
+ return copy;
18807
+ }
18808
+ throw new Error("ReCap caveats must contain only JSON values.");
18809
+ };
18810
+ try {
18811
+ return JSON.parse(JSON.stringify(caveats.map(cloneJson)));
18812
+ } catch {
18813
+ throw new Error("Verified persisted session ReCap contains invalid caveats.");
18814
+ }
18815
+ }
18816
+ var ServiceGraphLifetime = class {
18817
+ constructor(invokeFn, invokeAnyFn, fetchFn) {
18818
+ this.invokeFn = invokeFn;
18819
+ this.invokeAnyFn = invokeAnyFn;
18820
+ this.fetchFn = fetchFn;
18821
+ this.abortController = new AbortController();
18822
+ this.contexts = /* @__PURE__ */ new Set();
18823
+ this.retired = false;
18824
+ this.invoke = (session, service, path, action, facts) => {
18825
+ this.assertActive();
18826
+ return this.invokeFn(session, service, path, action, facts);
18827
+ };
18828
+ this.invokeAny = (session, entries, facts) => {
18829
+ this.assertActive();
18830
+ return this.invokeAnyFn(session, entries, facts);
18831
+ };
18832
+ this.fetch = (url, init2) => {
18833
+ this.assertActive();
18834
+ return this.fetchFn(url, {
18835
+ ...init2,
18836
+ signal: this.combineSignals(init2?.signal)
18837
+ });
18838
+ };
18839
+ }
18840
+ track(context) {
18841
+ this.assertActive();
18842
+ this.contexts.add(context);
18843
+ return context;
18844
+ }
18845
+ retire() {
18846
+ if (this.retired) return;
18847
+ this.retired = true;
18848
+ this.abortController.abort();
18849
+ try {
18850
+ for (const context of this.contexts) {
18851
+ try {
18852
+ const retire = context.retire;
18853
+ if (retire) retire.call(context);
18854
+ else context.abort();
18855
+ } catch (error) {
18856
+ console.error("Error retiring service graph context:", error);
18857
+ }
18858
+ }
18859
+ } finally {
18860
+ this.contexts.clear();
18861
+ }
18862
+ }
18863
+ assertActive() {
18864
+ if (this.retired) {
18865
+ throw new Error("Service graph has been retired by session replacement.");
18866
+ }
18867
+ }
18868
+ combineSignals(signal) {
18869
+ if (!signal) return this.abortController.signal;
18870
+ const combined = new AbortController();
18871
+ const abort = () => combined.abort();
18872
+ if (signal.aborted || this.abortController.signal.aborted) {
18873
+ abort();
18874
+ } else {
18875
+ signal.addEventListener("abort", abort, { once: true });
18876
+ this.abortController.signal.addEventListener("abort", abort, { once: true });
18877
+ }
18878
+ return combined.signal;
18879
+ }
18880
+ };
18881
+ var UnsupportedSessionRestoreError = class extends Error {
18882
+ constructor(reason = "it cannot replace and enumerate every live session signer") {
18883
+ super(`Persisted session restore is unsupported by this WASM binding because ${reason}.`);
18884
+ this.code = "RESTORE_SESSION_KEY_REPLACEMENT_UNSUPPORTED";
18885
+ this.name = "UnsupportedSessionRestoreError";
18886
+ }
18887
+ };
18888
+ function canonicalRestoredVerificationMethod(canonicalVerificationMethod, persistedVerificationMethod) {
18889
+ if (typeof persistedVerificationMethod !== "string") return void 0;
18890
+ const principal = canonicalVerificationMethod.split("#", 1)[0];
18891
+ return persistedVerificationMethod === principal || persistedVerificationMethod === canonicalVerificationMethod ? canonicalVerificationMethod : void 0;
18892
+ }
18893
+ function persistedExpiry(value) {
18894
+ if (typeof value !== "string") {
18895
+ throw new Error("Persisted session without a SIWE expiration must include expiresAt.");
18896
+ }
18897
+ const expiry = new Date(value);
18898
+ if (!Number.isFinite(expiry.getTime()) || expiry.getTime() <= Date.now()) {
18899
+ throw new Error("Persisted session expiry is invalid or expired.");
18900
+ }
18901
+ return expiry;
18902
+ }
18903
+ function sameInstant(left, right) {
18904
+ return left.getTime() === right.getTime();
18905
+ }
18735
18906
  function sharingActionsToAbilities(path, actions) {
18736
18907
  var _a;
18737
18908
  const abilities = {};
@@ -18858,6 +19029,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18858
19029
  this.auth = null;
18859
19030
  this.tc = null;
18860
19031
  this._chainId = 1;
19032
+ this._baseVaults = /* @__PURE__ */ new Map();
18861
19033
  this._baseSecrets = /* @__PURE__ */ new Map();
18862
19034
  this._secrets = /* @__PURE__ */ new Map();
18863
19035
  this.runtimePermissionGrants = [];
@@ -18877,26 +19049,55 @@ var _TinyCloudNode = class _TinyCloudNode {
18877
19049
  skipped: false
18878
19050
  };
18879
19051
  this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
18880
- return this.wasmBindings.invoke(
18881
- this.selectInvocationSession(session, service, path, action),
18882
- service,
19052
+ const operation = {
19053
+ spaceId: session.spaceId,
19054
+ service: this.invocationServiceName(service),
18883
19055
  path,
18884
- action,
18885
- facts
19056
+ action
19057
+ };
19058
+ const grant = this.findGrantForOperation(operation);
19059
+ const grantedOperation = grant?.operations.find(
19060
+ (candidate) => this.operationCovers(candidate, operation)
18886
19061
  );
19062
+ const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
19063
+ if ((grantedOperation?.caveats?.length ?? 0) > 0) {
19064
+ if (!this.wasmBindings.invokeAny) {
19065
+ throw new Error("WASM binding does not support caveat-preserving invocation");
19066
+ }
19067
+ return this.wasmBindings.invokeAny(invocationSession, [{
19068
+ spaceId: invocationSession.spaceId,
19069
+ service,
19070
+ path,
19071
+ action,
19072
+ caveats: cloneRecapCaveats(grantedOperation.caveats)
19073
+ }], facts);
19074
+ }
19075
+ return this.wasmBindings.invoke(invocationSession, service, path, action, facts);
18887
19076
  };
18888
19077
  this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
18889
19078
  if (!this.wasmBindings.invokeAny) {
18890
19079
  throw new Error("WASM binding does not support invokeAny");
18891
19080
  }
18892
- const grant = this.findGrantForOperations(
18893
- entries.flatMap((entry) => {
18894
- const operation = this.operationFromInvokeAnyEntry(entry);
18895
- return operation ? [operation] : [];
18896
- })
18897
- );
19081
+ const operations = entries.flatMap((entry) => {
19082
+ const operation = this.operationFromInvokeAnyEntry(entry);
19083
+ return operation ? [operation] : [];
19084
+ });
19085
+ const grant = this.findGrantForOperations(operations);
18898
19086
  const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
18899
- return this.wasmBindings.invokeAny(invocationSession, entries, facts);
19087
+ const caveatPreservingEntries = grant ? entries.map((entry) => {
19088
+ const requested = this.operationFromInvokeAnyEntry(entry);
19089
+ const granted = requested && grant.operations.find(
19090
+ (candidate) => this.operationCovers(candidate, requested)
19091
+ );
19092
+ if (!granted?.caveats?.length) {
19093
+ return entry;
19094
+ }
19095
+ if (entry.caveats !== void 0 && !(0, import_sdk_core7.recapCaveatsEqual)(entry.caveats, granted.caveats)) {
19096
+ throw new Error("Invocation caveats do not match signed ReCap authority.");
19097
+ }
19098
+ return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
19099
+ }) : entries;
19100
+ return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
18900
19101
  };
18901
19102
  this.explicitHost = config.host;
18902
19103
  this.config = {
@@ -18925,16 +19126,19 @@ var _TinyCloudNode = class _TinyCloudNode {
18925
19126
  throw new Error("Failed to get session key JWK");
18926
19127
  }
18927
19128
  this.sessionKeyJwk = JSON.parse(jwkStr);
19129
+ this._serviceGraph = this.createServiceGraphLifetime();
18928
19130
  this._capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
18929
19131
  this._keyProvider = new WasmKeyProvider({
18930
19132
  sessionManager: this.sessionManager
18931
19133
  });
18932
19134
  this.notificationHandler = config.notificationHandler ?? new import_sdk_core7.SilentNotificationHandler();
19135
+ const receiveOnlyGraph = this._serviceGraph;
18933
19136
  this._sharingService = new import_sdk_core7.SharingService({
18934
19137
  hosts: [this.config.host],
18935
19138
  // session: undefined - not needed for receive()
18936
- invoke: this.invokeWithRuntimePermissions,
18937
- fetch: globalThis.fetch.bind(globalThis),
19139
+ invoke: receiveOnlyGraph.invoke,
19140
+ fetch: receiveOnlyGraph.fetch,
19141
+ assertActive: () => receiveOnlyGraph.assertActive(),
18938
19142
  keyProvider: this._keyProvider,
18939
19143
  registry: this._capabilityRegistry,
18940
19144
  createDelegationWasm: (params) => this.createDelegationWrapper(params),
@@ -18946,12 +19150,12 @@ var _TinyCloudNode = class _TinyCloudNode {
18946
19150
  createKVService: (config2) => {
18947
19151
  const prefix = config2.pathPrefix?.replace(/\/$/, "");
18948
19152
  const kvService = new import_sdk_core7.KVService({ prefix });
18949
- const kvContext = new import_sdk_core7.ServiceContext({
19153
+ const kvContext = receiveOnlyGraph.track(new import_sdk_core7.ServiceContext({
18950
19154
  invoke: config2.invoke,
18951
19155
  fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
18952
19156
  hosts: config2.hosts,
18953
19157
  telemetry: this.config.telemetry
18954
- });
19158
+ }));
18955
19159
  kvContext.setSession(config2.session);
18956
19160
  kvService.initialize(kvContext);
18957
19161
  return kvService;
@@ -19025,6 +19229,16 @@ var _TinyCloudNode = class _TinyCloudNode {
19025
19229
  shouldUseBootstrapSignInRequest(config) {
19026
19230
  return config.autoBootstrapAccount !== false && config.manifest === void 0 && config.capabilityRequest === void 0 && (config.prefix ?? "default") === "default" && isOpenKeyAutoSignStrategy(config.signStrategy);
19027
19231
  }
19232
+ createServiceGraphLifetime() {
19233
+ return new ServiceGraphLifetime(
19234
+ this.invokeWithRuntimePermissions,
19235
+ this.invokeAnyWithRuntimePermissions,
19236
+ // Resolve fetch at request time. This keeps the graph-owned lifetime
19237
+ // signal while preserving the SDK's existing injectable global fetch
19238
+ // behavior (including adapters that install it after construction).
19239
+ (url, init2) => globalThis.fetch(url, init2)
19240
+ );
19241
+ }
19028
19242
  syncResolvedHostFromAuth() {
19029
19243
  const host = this.auth?.hosts[0];
19030
19244
  if (host) {
@@ -19094,6 +19308,27 @@ var _TinyCloudNode = class _TinyCloudNode {
19094
19308
  get sessionDid() {
19095
19309
  return this.sessionManager.getDID(this.sessionKeyId);
19096
19310
  }
19311
+ /**
19312
+ * Return the current session's signed ReCap capabilities after the session
19313
+ * has been authenticated or restored. This is intentionally distinct from
19314
+ * installed runtime delegations: it reports base-session authority only.
19315
+ *
19316
+ * Invalid or unparseable signed ReCap material throws so callers fail closed
19317
+ * rather than treating a malformed session as unrestricted authority.
19318
+ */
19319
+ getVerifiedSessionCapabilities() {
19320
+ const session = this.currentTinyCloudSession();
19321
+ if (!session || !session.siwe) return [];
19322
+ return (0, import_sdk_core7.parseRecapCapabilities)(
19323
+ (siwe) => this.parseRecapWithCaveats(siwe),
19324
+ session.siwe
19325
+ ).map((entry) => entry.service === "tinycloud.encryption" ? {
19326
+ service: entry.service,
19327
+ path: entry.path,
19328
+ actions: [...entry.actions],
19329
+ ...entry.caveats === void 0 ? {} : { caveats: entry.caveats }
19330
+ } : entry);
19331
+ }
19097
19332
  /**
19098
19333
  * Get the Ethereum address for this user.
19099
19334
  */
@@ -19136,6 +19371,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19136
19371
  getPrimarySpaceId: () => this.spaceId,
19137
19372
  getAccountSpaceId: () => this.accountSpaceId,
19138
19373
  getSpaces: () => this.spaces,
19374
+ getDelegationManager: () => this.delegationManager,
19139
19375
  getAccountDb: () => this.accountSpaceId ? this.sqlForSpace(this.accountSpaceId).db("account") : void 0,
19140
19376
  ensureAccountSpaceHosted: async () => {
19141
19377
  if (this.accountSpaceId && this.auth) {
@@ -19182,6 +19418,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19182
19418
  this._hooks = void 0;
19183
19419
  this._vault = void 0;
19184
19420
  this._encryption = void 0;
19421
+ this._baseVaults.clear();
19185
19422
  this._baseSecrets.clear();
19186
19423
  this._secrets.clear();
19187
19424
  this._spaceService = void 0;
@@ -19189,6 +19426,10 @@ var _TinyCloudNode = class _TinyCloudNode {
19189
19426
  this.runtimePermissionGrants = [];
19190
19427
  await this.tc.signIn(options);
19191
19428
  this.syncResolvedHostFromAuth();
19429
+ const oldGraph = this._serviceGraph;
19430
+ this._serviceGraph = this.createServiceGraphLifetime();
19431
+ oldGraph.retire();
19432
+ this.tc.retireServices();
19192
19433
  const signedInSession = this.currentTinyCloudSession();
19193
19434
  if (signedInSession) {
19194
19435
  this.sessionKeyId = signedInSession.sessionKey;
@@ -19473,7 +19714,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19473
19714
  }
19474
19715
  let operations = [];
19475
19716
  try {
19476
- const entries = this.wasmBindings.parseRecapFromSiwe(siwe);
19717
+ const entries = this.parseRecapWithCaveats(siwe);
19477
19718
  if (Array.isArray(entries)) {
19478
19719
  operations = entries.flatMap((entry) => {
19479
19720
  const service = this.invocationServiceName(entry.service);
@@ -19481,7 +19722,8 @@ var _TinyCloudNode = class _TinyCloudNode {
19481
19722
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
19482
19723
  service,
19483
19724
  path: entry.path,
19484
- action
19725
+ action,
19726
+ caveats: cloneRecapCaveats(entry.caveats)
19485
19727
  }));
19486
19728
  });
19487
19729
  }
@@ -19834,86 +20076,441 @@ var _TinyCloudNode = class _TinyCloudNode {
19834
20076
  */
19835
20077
  async restoreSession(sessionData) {
19836
20078
  await this.wasmBindings.ensureInitialized?.();
19837
- this._kv = void 0;
19838
- this._sql = void 0;
19839
- this._duckdb = void 0;
19840
- this._hooks = void 0;
19841
- this._vault = void 0;
19842
- this._encryption = void 0;
19843
- this._baseSecrets.clear();
19844
- this._secrets.clear();
19845
- this._spaceService = void 0;
19846
- this._serviceContext = void 0;
19847
- this.runtimePermissionGrants = [];
19848
- const restoredAddress = sessionData.address ? (0, import_sdk_core7.canonicalizeAddress)(sessionData.address) : void 0;
19849
- if (restoredAddress) {
19850
- this._address = restoredAddress;
20079
+ const restoredJwk = clonePersistedSessionJwk(sessionData.jwk);
20080
+ if (sessionData.chainId !== void 0 && (!Number.isSafeInteger(sessionData.chainId) || sessionData.chainId <= 0)) {
20081
+ throw new Error("Persisted session chain ID must be a positive safe integer.");
20082
+ }
20083
+ const stagedManager = this.wasmBindings.createSessionManager();
20084
+ const stagedReplace = stagedManager.replaceSessionKey;
20085
+ const liveKeys = this.sessionManager.listSessionKeys;
20086
+ const stagedKeys = stagedManager.listSessionKeys;
20087
+ if (typeof stagedReplace !== "function" || typeof liveKeys !== "function" || typeof stagedKeys !== "function") {
20088
+ throw new UnsupportedSessionRestoreError();
20089
+ }
20090
+ let stagedKeyId;
20091
+ let stagedJwk;
20092
+ let canonicalVerificationMethod;
20093
+ try {
20094
+ const keyIds = liveKeys.call(this.sessionManager);
20095
+ if (!Array.isArray(keyIds) || !keyIds.every((keyId) => typeof keyId === "string")) {
20096
+ throw new UnsupportedSessionRestoreError("it cannot reliably enumerate every live session signer");
20097
+ }
20098
+ for (const keyId of keyIds) {
20099
+ if (keyId === this.sessionKeyId) continue;
20100
+ const jwk = this.sessionManager.jwk(keyId);
20101
+ if (!jwk) throw new Error("missing live session key");
20102
+ stagedReplace.call(stagedManager, clonePersistedSessionJwk(JSON.parse(jwk)), keyId);
20103
+ }
20104
+ stagedKeyId = stagedReplace.call(stagedManager, restoredJwk, this.sessionKeyId);
20105
+ const stagedJwkJson = stagedManager.jwk(stagedKeyId);
20106
+ if (!stagedJwkJson) throw new Error("missing restored session key");
20107
+ stagedJwk = clonePersistedSessionJwk(JSON.parse(stagedJwkJson));
20108
+ canonicalVerificationMethod = stagedManager.getDID(stagedKeyId);
20109
+ } catch (error) {
20110
+ if (error instanceof UnsupportedSessionRestoreError) throw error;
20111
+ throw new Error("Persisted session has an invalid private Ed25519 session key.");
19851
20112
  }
19852
- if (sessionData.chainId) {
19853
- this._chainId = sessionData.chainId;
20113
+ const restoredVerificationMethod = canonicalRestoredVerificationMethod(
20114
+ canonicalVerificationMethod,
20115
+ sessionData.verificationMethod
20116
+ );
20117
+ if (!restoredVerificationMethod) {
20118
+ throw new Error(
20119
+ "Persisted session verification method does not match its private Ed25519 session key."
20120
+ );
20121
+ }
20122
+ const proofValues = [
20123
+ sessionData.siwe,
20124
+ sessionData.signature,
20125
+ sessionData.address,
20126
+ sessionData.chainId
20127
+ ];
20128
+ const hasPersistedProof = proofValues.every((value) => value !== void 0);
20129
+ if (!hasPersistedProof && (proofValues.some((value) => value !== void 0) || sessionData.expiresAt !== void 0)) {
20130
+ throw new Error("Persisted session authority metadata is incomplete.");
20131
+ }
20132
+ const restoredAddress = hasPersistedProof ? (0, import_sdk_core7.canonicalizeAddress)(sessionData.address) : void 0;
20133
+ let stagedSessionExpiry = /* @__PURE__ */ new Date(0);
20134
+ let stagedRecap = [];
20135
+ if (hasPersistedProof) {
20136
+ if (typeof this.wasmBindings.validatePersistedSession !== "function") {
20137
+ throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
20138
+ }
20139
+ const verified = this.wasmBindings.validatePersistedSession({
20140
+ delegationHeader: sessionData.delegationHeader,
20141
+ delegationCid: sessionData.delegationCid,
20142
+ spaceId: sessionData.spaceId,
20143
+ jwk: stagedJwk,
20144
+ address: restoredAddress,
20145
+ chainId: sessionData.chainId,
20146
+ siwe: sessionData.siwe,
20147
+ signature: sessionData.signature
20148
+ });
20149
+ const exactRecap = verified.verifiedRecap;
20150
+ if (!Array.isArray(exactRecap) || !exactRecap.every(
20151
+ (entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
20152
+ (caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
20153
+ )
20154
+ )) {
20155
+ throw new UnsupportedSessionRestoreError(
20156
+ "it cannot reconstruct caveat-preserving persisted ReCap authority"
20157
+ );
20158
+ }
20159
+ stagedRecap = exactRecap.map((entry) => ({
20160
+ service: entry.service,
20161
+ space: entry.space,
20162
+ path: entry.path,
20163
+ actions: [...entry.actions],
20164
+ caveats: cloneRecapCaveats(entry.caveats)
20165
+ }));
20166
+ const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
20167
+ const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
20168
+ if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
20169
+ throw new Error("Persisted session expiry does not match its signed SIWE authority.");
20170
+ }
20171
+ stagedSessionExpiry = signedExpiry ?? persistedPolicyExpiry ?? persistedExpiry(void 0);
19854
20172
  }
19855
20173
  const resolvedHost = await this.resolveRestoredHost(
19856
20174
  sessionData.tinycloudHosts,
19857
20175
  restoredAddress,
19858
20176
  sessionData.chainId
19859
20177
  );
19860
- if (resolvedHost) {
19861
- this.config.host = resolvedHost;
19862
- }
19863
- this._serviceContext = new import_sdk_core7.ServiceContext({
19864
- invoke: this.invokeWithRuntimePermissions,
19865
- invokeAny: this.invokeAnyWithRuntimePermissions,
19866
- fetch: globalThis.fetch.bind(globalThis),
19867
- hosts: [this.config.host],
19868
- telemetry: this.config.telemetry
19869
- });
19870
- this._kv = new import_sdk_core7.KVService({});
19871
- this._kv.initialize(this._serviceContext);
19872
- this._serviceContext.registerService("kv", this._kv);
19873
- this._sql = new import_sdk_core7.SQLService({});
19874
- this._sql.initialize(this._serviceContext);
19875
- this._serviceContext.registerService("sql", this._sql);
19876
- this._duckdb = new import_sdk_core7.DuckDbService({});
19877
- this._duckdb.initialize(this._serviceContext);
19878
- this._serviceContext.registerService("duckdb", this._duckdb);
19879
- this._hooks = new import_sdk_core7.HooksService({});
19880
- this._hooks.initialize(this._serviceContext);
19881
- this._serviceContext.registerService("hooks", this._hooks);
20178
+ const stagedHost = resolvedHost ?? this.config.host;
20179
+ const stagedAddress = restoredAddress;
20180
+ const stagedChainId = sessionData.chainId ?? 1;
20181
+ const stagedNodeDid = stagedAddress ? (0, import_sdk_core7.pkhDid)(stagedAddress, stagedChainId) : canonicalVerificationMethod;
19882
20182
  const serviceSession = {
19883
20183
  delegationHeader: sessionData.delegationHeader,
19884
20184
  delegationCid: sessionData.delegationCid,
19885
20185
  spaceId: sessionData.spaceId,
19886
- verificationMethod: sessionData.verificationMethod,
19887
- jwk: sessionData.jwk
20186
+ verificationMethod: restoredVerificationMethod,
20187
+ jwk: stagedJwk
19888
20188
  };
19889
- this._serviceContext.setSession(serviceSession);
19890
- this._vault = this.createVaultService(sessionData.spaceId, this._kv);
19891
- this._vault.initialize(this._serviceContext);
19892
- this._serviceContext.registerService("vault", this._vault);
19893
- this.initializeV2Services(serviceSession);
19894
- if (sessionData.siwe && restoredAddress && sessionData.chainId) {
19895
- const tcSession = {
19896
- address: restoredAddress,
19897
- chainId: sessionData.chainId,
19898
- sessionKey: JSON.stringify(sessionData.jwk),
19899
- spaceId: sessionData.spaceId,
19900
- delegationCid: sessionData.delegationCid,
19901
- delegationHeader: sessionData.delegationHeader,
19902
- verificationMethod: sessionData.verificationMethod,
19903
- jwk: sessionData.jwk,
19904
- siwe: sessionData.siwe,
19905
- signature: sessionData.signature ?? ""
19906
- };
19907
- if (this.auth) {
19908
- this.auth.setRestoredTinyCloudSession(
19909
- tcSession,
19910
- this.config.host ? [this.config.host] : void 0
20189
+ const stagedTcSession = hasPersistedProof ? {
20190
+ address: restoredAddress,
20191
+ chainId: sessionData.chainId,
20192
+ sessionKey: JSON.stringify(stagedJwk),
20193
+ spaceId: sessionData.spaceId,
20194
+ spaces: sessionData.spaces,
20195
+ delegationCid: sessionData.delegationCid,
20196
+ delegationHeader: sessionData.delegationHeader,
20197
+ verificationMethod: restoredVerificationMethod,
20198
+ jwk: stagedJwk,
20199
+ siwe: sessionData.siwe,
20200
+ signature: sessionData.signature
20201
+ } : void 0;
20202
+ const stagedPrimary = this.stagePrimarySessionState(
20203
+ stagedTcSession,
20204
+ stagedNodeDid,
20205
+ stagedHost,
20206
+ stagedSessionExpiry,
20207
+ stagedRecap
20208
+ );
20209
+ const stagedGraph = this.stageRestoredServiceGraph({
20210
+ host: stagedHost,
20211
+ manager: stagedManager,
20212
+ serviceSession,
20213
+ verificationMethod: canonicalVerificationMethod,
20214
+ nodeDid: stagedNodeDid,
20215
+ address: stagedAddress,
20216
+ chainId: stagedChainId,
20217
+ tinyCloudSession: stagedTcSession,
20218
+ sessionExpiry: stagedSessionExpiry,
20219
+ recap: stagedRecap
20220
+ });
20221
+ const oldGraph = this._serviceGraph;
20222
+ const oldCore = this.tc;
20223
+ this.sessionManager = stagedManager;
20224
+ this.sessionKeyId = stagedKeyId;
20225
+ this.sessionKeyJwk = stagedJwk;
20226
+ if (resolvedHost) this.config.host = resolvedHost;
20227
+ this._address = stagedAddress;
20228
+ this._chainId = stagedChainId;
20229
+ this._serviceContext = stagedGraph.serviceContext;
20230
+ this._kv = stagedGraph.kv;
20231
+ this._sql = stagedGraph.sql;
20232
+ this._duckdb = stagedGraph.duckdb;
20233
+ this._hooks = stagedGraph.hooks;
20234
+ this._vault = stagedGraph.vault;
20235
+ this._encryption = stagedGraph.encryption;
20236
+ this._capabilityRegistry = stagedGraph.capabilityRegistry;
20237
+ this._keyProvider = stagedGraph.keyProvider;
20238
+ this._sharingService = stagedGraph.sharingService;
20239
+ this._delegationManager = stagedGraph.delegationManager;
20240
+ this._spaceService = stagedGraph.spaceService;
20241
+ this._serviceGraph = stagedGraph.graph;
20242
+ this._baseSecrets = /* @__PURE__ */ new Map();
20243
+ this._secrets = /* @__PURE__ */ new Map();
20244
+ this._publicKV = void 0;
20245
+ this._account = void 0;
20246
+ this.tc = stagedGraph.core;
20247
+ this._recapOperationsCache = stagedPrimary.cache;
20248
+ this.runtimePermissionGrants = stagedPrimary.grants;
20249
+ if (this.auth) {
20250
+ this.auth.installRestoredSession(stagedManager, stagedTcSession, [stagedHost]);
20251
+ this._restoredTcSession = void 0;
20252
+ } else {
20253
+ this._restoredTcSession = stagedTcSession;
20254
+ }
20255
+ oldGraph.retire();
20256
+ oldCore?.retireServices?.();
20257
+ }
20258
+ stagePrimarySessionState(session, verificationMethod, host, sessionExpiry, recap) {
20259
+ if (!session?.siwe) return { cache: void 0, grants: [] };
20260
+ let operations = [];
20261
+ operations = recap.flatMap((entry) => {
20262
+ const service = this.invocationServiceName(entry.service);
20263
+ return entry.actions.map((action) => ({
20264
+ ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
20265
+ service,
20266
+ path: entry.path,
20267
+ action,
20268
+ caveats: cloneRecapCaveats(entry.caveats)
20269
+ }));
20270
+ });
20271
+ const cache = { siwe: session.siwe, operations };
20272
+ if (operations.length === 0) return { cache, grants: [] };
20273
+ const expiresAt = sessionExpiry;
20274
+ return {
20275
+ cache,
20276
+ grants: [{
20277
+ session: {
20278
+ delegationHeader: session.delegationHeader,
20279
+ delegationCid: session.delegationCid,
20280
+ spaceId: session.spaceId,
20281
+ verificationMethod: session.verificationMethod,
20282
+ jwk: session.jwk
20283
+ },
20284
+ delegation: {
20285
+ cid: session.delegationCid,
20286
+ delegationHeader: session.delegationHeader,
20287
+ delegateDID: session.verificationMethod,
20288
+ delegatorDID: verificationMethod,
20289
+ spaceId: session.spaceId,
20290
+ path: "",
20291
+ actions: [...new Set(operations.map((operation) => operation.action))],
20292
+ expiry: expiresAt,
20293
+ allowSubDelegation: true,
20294
+ ownerAddress: session.address,
20295
+ chainId: session.chainId,
20296
+ host
20297
+ },
20298
+ operations,
20299
+ expiresAt,
20300
+ provenance: "primary"
20301
+ }]
20302
+ };
20303
+ }
20304
+ stageRestoredServiceGraph(input) {
20305
+ const graph = this.createServiceGraphLifetime();
20306
+ const core = this.auth ? new import_sdk_core7.TinyCloud(this.auth, {
20307
+ invokeAny: graph.invokeAny,
20308
+ telemetry: this.config.telemetry
20309
+ }) : null;
20310
+ if (core) {
20311
+ core.initializeServices(graph.invoke, [input.host], graph.fetch);
20312
+ const coreContext = graph.track(core.serviceContext);
20313
+ coreContext.setSession(input.serviceSession);
20314
+ }
20315
+ const serviceContext = graph.track(new import_sdk_core7.ServiceContext({
20316
+ invoke: graph.invoke,
20317
+ invokeAny: graph.invokeAny,
20318
+ fetch: graph.fetch,
20319
+ hosts: [input.host],
20320
+ telemetry: this.config.telemetry
20321
+ }));
20322
+ const kv = new import_sdk_core7.KVService({});
20323
+ kv.initialize(serviceContext);
20324
+ serviceContext.registerService("kv", kv);
20325
+ const sql = new import_sdk_core7.SQLService({});
20326
+ sql.initialize(serviceContext);
20327
+ serviceContext.registerService("sql", sql);
20328
+ const duckdb = new import_sdk_core7.DuckDbService({});
20329
+ duckdb.initialize(serviceContext);
20330
+ serviceContext.registerService("duckdb", duckdb);
20331
+ const hooks = new import_sdk_core7.HooksService({});
20332
+ hooks.initialize(serviceContext);
20333
+ serviceContext.registerService("hooks", hooks);
20334
+ serviceContext.setSession(input.serviceSession);
20335
+ const encryption = this.createEncryptionService({
20336
+ graph,
20337
+ host: input.host,
20338
+ session: input.serviceSession,
20339
+ did: input.nodeDid,
20340
+ address: input.address,
20341
+ chainId: input.chainId
20342
+ });
20343
+ encryption.initialize(serviceContext);
20344
+ serviceContext.registerService("encryption", encryption);
20345
+ const vault = this.createVaultService(input.serviceSession.spaceId, kv, encryption, {
20346
+ host: input.host,
20347
+ did: input.nodeDid,
20348
+ address: input.address,
20349
+ chainId: input.chainId,
20350
+ serviceGraph: graph
20351
+ });
20352
+ vault.initialize(serviceContext);
20353
+ serviceContext.registerService("vault", vault);
20354
+ const capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
20355
+ if (input.tinyCloudSession) {
20356
+ const session = input.tinyCloudSession;
20357
+ const delegations = input.recap.map((entry) => ({
20358
+ cid: session.delegationCid,
20359
+ delegateDID: session.verificationMethod,
20360
+ spaceId: entry.space,
20361
+ path: entry.path,
20362
+ actions: [...entry.actions],
20363
+ caveats: cloneRecapCaveats(entry.caveats),
20364
+ expiry: input.sessionExpiry,
20365
+ isRevoked: false,
20366
+ allowSubDelegation: true
20367
+ }));
20368
+ if (delegations.length > 0) {
20369
+ capabilityRegistry.registerKey({
20370
+ id: session.sessionKey,
20371
+ did: session.verificationMethod,
20372
+ type: "session",
20373
+ jwk: session.jwk,
20374
+ priority: 0
20375
+ }, delegations);
20376
+ }
20377
+ }
20378
+ const delegationManager = new import_sdk_core7.DelegationManager({
20379
+ hosts: [input.host],
20380
+ session: input.serviceSession,
20381
+ invoke: graph.invoke,
20382
+ invokeAny: graph.invokeAny,
20383
+ fetch: graph.fetch
20384
+ });
20385
+ const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
20386
+ const sharingService = new import_sdk_core7.SharingService({
20387
+ hosts: [input.host],
20388
+ invoke: graph.invoke,
20389
+ fetch: graph.fetch,
20390
+ assertActive: () => graph.assertActive(),
20391
+ keyProvider,
20392
+ registry: capabilityRegistry,
20393
+ createDelegationWasm: (params) => this.createDelegationWrapper(params),
20394
+ computeCid: (data, codec) => {
20395
+ if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
20396
+ return this.wasmBindings.computeCid(data, codec);
20397
+ },
20398
+ createKVService: (config) => {
20399
+ const service = new import_sdk_core7.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
20400
+ const context = graph.track(new import_sdk_core7.ServiceContext({
20401
+ invoke: config.invoke,
20402
+ fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
20403
+ hosts: config.hosts,
20404
+ telemetry: this.config.telemetry
20405
+ }));
20406
+ context.setSession(config.session);
20407
+ service.initialize(context);
20408
+ return service;
20409
+ }
20410
+ });
20411
+ sharingService.updateConfig({
20412
+ session: input.serviceSession,
20413
+ delegationManager,
20414
+ sessionExpiry: input.sessionExpiry,
20415
+ createDelegationWasm: (params) => {
20416
+ graph.assertActive();
20417
+ return this.createDelegationWrapper(params);
20418
+ },
20419
+ onRootDelegationNeeded: this.signer ? async (params) => {
20420
+ graph.assertActive();
20421
+ const delegation = await this.createRootDelegationForSharing(
20422
+ params,
20423
+ () => graph.assertActive()
19911
20424
  );
19912
- } else {
19913
- this._restoredTcSession = tcSession;
20425
+ graph.assertActive();
20426
+ return delegation;
20427
+ } : void 0
20428
+ });
20429
+ const spaceService = new import_sdk_core7.SpaceService({
20430
+ hosts: [input.host],
20431
+ session: input.serviceSession,
20432
+ invoke: graph.invoke,
20433
+ fetch: graph.fetch,
20434
+ capabilityRegistry,
20435
+ userDid: input.nodeDid,
20436
+ createKVService: (spaceId) => {
20437
+ graph.assertActive();
20438
+ const scopedKv = new import_sdk_core7.KVService({});
20439
+ const context = graph.track(new import_sdk_core7.ServiceContext({
20440
+ invoke: graph.invoke,
20441
+ invokeAny: graph.invokeAny,
20442
+ fetch: graph.fetch,
20443
+ hosts: [input.host],
20444
+ telemetry: this.config.telemetry
20445
+ }));
20446
+ context.setSession({ ...input.serviceSession, spaceId });
20447
+ scopedKv.initialize(context);
20448
+ return scopedKv;
20449
+ },
20450
+ createVaultService: (spaceId) => {
20451
+ graph.assertActive();
20452
+ const scopedKv = new import_sdk_core7.KVService({});
20453
+ const context = graph.track(new import_sdk_core7.ServiceContext({
20454
+ invoke: graph.invoke,
20455
+ invokeAny: graph.invokeAny,
20456
+ fetch: graph.fetch,
20457
+ hosts: [input.host],
20458
+ telemetry: this.config.telemetry
20459
+ }));
20460
+ context.setSession({ ...input.serviceSession, spaceId });
20461
+ scopedKv.initialize(context);
20462
+ const scopedVault = this.createVaultService(spaceId, scopedKv, encryption, {
20463
+ host: input.host,
20464
+ did: input.nodeDid,
20465
+ address: input.address,
20466
+ chainId: input.chainId,
20467
+ serviceGraph: graph
20468
+ });
20469
+ scopedVault.initialize(context);
20470
+ return scopedVault;
20471
+ },
20472
+ createSecretsService: (spaceId) => {
20473
+ graph.assertActive();
20474
+ return this.secretsForSpace(spaceId);
20475
+ },
20476
+ createDelegation: async (params) => {
20477
+ graph.assertActive();
20478
+ try {
20479
+ const portableDelegation = await this.createDelegation({
20480
+ delegateDID: params.delegateDID,
20481
+ path: params.path,
20482
+ actions: params.actions,
20483
+ disableSubDelegation: params.disableSubDelegation,
20484
+ expiryMs: params.expiry ? params.expiry.getTime() - Date.now() : void 0
20485
+ });
20486
+ return { ok: true, data: {
20487
+ cid: portableDelegation.cid,
20488
+ delegateDID: portableDelegation.delegateDID,
20489
+ delegatorDID: this.did,
20490
+ spaceId: portableDelegation.spaceId,
20491
+ path: portableDelegation.path,
20492
+ actions: portableDelegation.actions,
20493
+ expiry: portableDelegation.expiry,
20494
+ isRevoked: false,
20495
+ allowSubDelegation: !portableDelegation.disableSubDelegation,
20496
+ createdAt: /* @__PURE__ */ new Date(),
20497
+ authHeader: portableDelegation.delegationHeader.Authorization
20498
+ } };
20499
+ } catch (error) {
20500
+ return { ok: false, error: {
20501
+ code: "CREATION_FAILED",
20502
+ message: error instanceof Error ? error.message : String(error),
20503
+ service: "delegation"
20504
+ } };
20505
+ }
20506
+ },
20507
+ onSpaceRegistered: async (space) => {
20508
+ graph.assertActive();
20509
+ await this.account.spaces.register(space);
19914
20510
  }
19915
- this.registerPrimarySessionGrant(tcSession);
19916
- }
20511
+ });
20512
+ spaceService.updateConfig({ sharingService });
20513
+ return { core, graph, serviceContext, kv, sql, duckdb, hooks, vault, encryption, capabilityRegistry, keyProvider, sharingService, delegationManager, spaceService };
19917
20514
  }
19918
20515
  /**
19919
20516
  * Resolve the host a restored session should target.
@@ -20075,14 +20672,19 @@ var _TinyCloudNode = class _TinyCloudNode {
20075
20672
  if (!session) {
20076
20673
  return;
20077
20674
  }
20078
- this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
20079
- this._serviceContext = new import_sdk_core7.ServiceContext({
20080
- invoke: this.invokeWithRuntimePermissions,
20081
- invokeAny: this.invokeAnyWithRuntimePermissions,
20082
- fetch: globalThis.fetch.bind(globalThis),
20675
+ this.tc.initializeServices(
20676
+ this._serviceGraph.invoke,
20677
+ [this.config.host],
20678
+ this._serviceGraph.fetch
20679
+ );
20680
+ this._serviceGraph.track(this.tc.serviceContext);
20681
+ this._serviceContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20682
+ invoke: this._serviceGraph.invoke,
20683
+ invokeAny: this._serviceGraph.invokeAny,
20684
+ fetch: this._serviceGraph.fetch,
20083
20685
  hosts: [this.config.host],
20084
20686
  telemetry: this.config.telemetry
20085
- });
20687
+ }));
20086
20688
  this._kv = new import_sdk_core7.KVService({});
20087
20689
  this._kv.initialize(this._serviceContext);
20088
20690
  this._serviceContext.registerService("kv", this._kv);
@@ -20117,12 +20719,12 @@ var _TinyCloudNode = class _TinyCloudNode {
20117
20719
  createSpaceScopedKVService(spaceId) {
20118
20720
  const kvService = new import_sdk_core7.KVService({});
20119
20721
  if (this._serviceContext) {
20120
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
20722
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20121
20723
  invoke: this._serviceContext.invoke,
20122
20724
  fetch: this._serviceContext.fetch,
20123
20725
  hosts: this._serviceContext.hosts,
20124
20726
  telemetry: this.config.telemetry
20125
- });
20727
+ }));
20126
20728
  const session = this._serviceContext.session;
20127
20729
  if (session) {
20128
20730
  spaceScopedContext.setSession({ ...session, spaceId });
@@ -20155,6 +20757,18 @@ var _TinyCloudNode = class _TinyCloudNode {
20155
20757
  }
20156
20758
  return session;
20157
20759
  }
20760
+ /**
20761
+ * Runtime-permission helpers can be used from an authenticated Node session
20762
+ * before its public ServiceContext is initialized. They still need the
20763
+ * current signed session, never an optional or stale authority object.
20764
+ */
20765
+ requireEncryptionSession() {
20766
+ const session = this._serviceContext?.session ?? this.auth?.tinyCloudSession;
20767
+ if (!session) {
20768
+ throw new Error("Not signed in. Call signIn() first.");
20769
+ }
20770
+ return session;
20771
+ }
20158
20772
  createEncryptionCrypto() {
20159
20773
  const wasm = this.wasmBindings;
20160
20774
  const columnEncrypt = (key2, plaintext) => {
@@ -20210,14 +20824,15 @@ var _TinyCloudNode = class _TinyCloudNode {
20210
20824
  }
20211
20825
  return info.nodeId;
20212
20826
  }
20213
- async signRawNetworkAuthorization(input) {
20827
+ async signRawNetworkAuthorization(input, binding) {
20828
+ binding?.graph.assertActive();
20214
20829
  if (!this.wasmBindings.invokeAny) {
20215
20830
  throw new Error("WASM binding does not support raw-resource invokeAny");
20216
20831
  }
20217
20832
  if (!this.wasmBindings.computeCid) {
20218
20833
  throw new Error("WASM binding does not support invocation CID computation");
20219
20834
  }
20220
- const session = this.requireServiceSession();
20835
+ const session = binding?.session ?? this.requireEncryptionSession();
20221
20836
  const headers = this.invokeAnyWithRuntimePermissions(
20222
20837
  session,
20223
20838
  [
@@ -20236,6 +20851,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20236
20851
  input.targetNode,
20237
20852
  session.jwk
20238
20853
  );
20854
+ binding?.graph.assertActive();
20239
20855
  return {
20240
20856
  authorization: audienceBound,
20241
20857
  invocationCid: this.wasmBindings.computeCid(
@@ -20244,25 +20860,55 @@ var _TinyCloudNode = class _TinyCloudNode {
20244
20860
  )
20245
20861
  };
20246
20862
  }
20247
- createEncryptionService() {
20863
+ async fetchEncryptionNetworkAt(host, networkId, fetchFn) {
20864
+ const response = await fetchFn(
20865
+ `${host}/encryption/networks/${encodeURIComponent(networkId)}`
20866
+ );
20867
+ if (response.status === 404) return null;
20868
+ if (!response.ok) {
20869
+ throw new Error(
20870
+ `Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
20871
+ );
20872
+ }
20873
+ const body = await response.json();
20874
+ return "descriptor" in body && body.descriptor ? body.descriptor : body;
20875
+ }
20876
+ createEncryptionService(binding) {
20877
+ const graph = binding?.graph ?? this._serviceGraph;
20878
+ const host = binding?.host ?? this.config.host;
20879
+ const session = binding?.session ?? this.requireEncryptionSession();
20880
+ const did = binding?.did ?? this.did;
20881
+ const address = binding?.address ?? this._address;
20882
+ const chainId = binding?.chainId ?? this._chainId;
20248
20883
  const crypto2 = this.createEncryptionCrypto();
20249
20884
  const transport = {
20250
- postDecrypt: async ({ networkId, authorization, canonicalBody }) => {
20251
- const response = await fetch(
20252
- `${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
20885
+ postDecrypt: async ({ networkId, authorization, canonicalBody, signal }) => {
20886
+ graph.assertActive();
20887
+ const response = await graph.fetch(
20888
+ `${host}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
20253
20889
  {
20254
20890
  method: "POST",
20255
20891
  headers: {
20256
20892
  Authorization: authorization,
20257
20893
  "Content-Type": "application/json"
20258
20894
  },
20259
- body: canonicalBody
20895
+ body: canonicalBody,
20896
+ signal
20260
20897
  }
20261
20898
  );
20899
+ graph.assertActive();
20262
20900
  if (!response.ok) {
20263
- throw new Error(
20264
- `decrypt failed ${response.status}: ${await response.text()}`
20265
- );
20901
+ let permissionHint;
20902
+ if (response.status === 401 || response.status === 403) {
20903
+ try {
20904
+ const body = await response.json();
20905
+ const record = typeof body === "object" && body !== null ? body : void 0;
20906
+ const nested = typeof record?.error === "object" && record.error !== null ? record.error : void 0;
20907
+ permissionHint = (0, import_sdk_services.parsePermissionHint)(record?.permissionHint) ?? (0, import_sdk_services.parsePermissionHint)(nested?.permissionHint);
20908
+ } catch {
20909
+ }
20910
+ }
20911
+ throw new import_sdk_core7.DecryptTransportResponseError(response.status, permissionHint);
20266
20912
  }
20267
20913
  return await response.json();
20268
20914
  }
@@ -20271,12 +20917,14 @@ var _TinyCloudNode = class _TinyCloudNode {
20271
20917
  crypto: crypto2,
20272
20918
  signer: {
20273
20919
  signDecryptInvocation: async (input) => {
20920
+ graph.assertActive();
20274
20921
  const signed2 = await this.signRawNetworkAuthorization({
20275
20922
  targetNode: input.targetNode,
20276
20923
  networkId: input.networkId,
20277
20924
  action: DECRYPT_ACTION2,
20278
20925
  facts: input.facts
20279
- });
20926
+ }, { graph, session });
20927
+ graph.assertActive();
20280
20928
  return {
20281
20929
  ...signed2,
20282
20930
  canonicalBody: (0, import_sdk_core7.canonicalizeEncryptionJson)(
@@ -20287,25 +20935,35 @@ var _TinyCloudNode = class _TinyCloudNode {
20287
20935
  },
20288
20936
  transport,
20289
20937
  node: {
20290
- fetchByNetworkId: (networkId) => this.getEncryptionNetwork(networkId)
20938
+ fetchByNetworkId: async (networkId) => {
20939
+ graph.assertActive();
20940
+ const descriptor = await this.fetchEncryptionNetworkAt(host, networkId, graph.fetch);
20941
+ graph.assertActive();
20942
+ return descriptor;
20943
+ }
20291
20944
  },
20292
20945
  wellKnown: {
20293
20946
  fetchWellKnown: async (principal, discoveryKey) => {
20294
- if (!this._address || !didPrincipalMatches2(principal, this.did)) {
20295
- return null;
20296
- }
20297
- if (!this.config.host) {
20947
+ graph.assertActive();
20948
+ if (!address || !didPrincipalMatches2(principal, did)) {
20298
20949
  return null;
20299
20950
  }
20300
- const publicSpaceId = (0, import_sdk_core7.makePublicSpaceId)(this._address, this._chainId);
20301
- const result = await import_sdk_core7.TinyCloud.readPublicSpace(this.config.host, publicSpaceId, discoveryKey);
20302
- if (!result.ok) {
20951
+ const publicSpaceId = (0, import_sdk_core7.makePublicSpaceId)(address, chainId);
20952
+ const encodedKey = discoveryKey.split("/").map(encodeURIComponent).join("/");
20953
+ const response = await graph.fetch(
20954
+ `${host}/public/${encodeURIComponent(publicSpaceId)}/kv/${encodedKey}`,
20955
+ { method: "GET" }
20956
+ );
20957
+ graph.assertActive();
20958
+ if (!response.ok) {
20303
20959
  return null;
20304
20960
  }
20305
- const body = result.data;
20961
+ const body = await response.json();
20962
+ graph.assertActive();
20306
20963
  return "descriptor" in body && body.descriptor ? body.descriptor : body;
20307
20964
  }
20308
- }
20965
+ },
20966
+ assertActive: () => graph.assertActive()
20309
20967
  });
20310
20968
  }
20311
20969
  getEncryptionService() {
@@ -20319,8 +20977,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20319
20977
  }
20320
20978
  return this._encryption;
20321
20979
  }
20322
- createVaultService(spaceId, kv) {
20980
+ createVaultService(spaceId, kv, encryptionService = this.getEncryptionService(), nodeContext) {
20323
20981
  const wasm = this.wasmBindings;
20982
+ const serviceGraph = nodeContext?.serviceGraph ?? this._serviceGraph;
20324
20983
  const vaultCrypto = (0, import_sdk_core7.createVaultCrypto)({
20325
20984
  vault_encrypt: wasm.vault_encrypt,
20326
20985
  vault_decrypt: wasm.vault_decrypt,
@@ -20331,12 +20990,17 @@ var _TinyCloudNode = class _TinyCloudNode {
20331
20990
  vault_sha256: wasm.vault_sha256
20332
20991
  });
20333
20992
  const self2 = this;
20993
+ const did = nodeContext?.did ?? this.did;
20994
+ const address = nodeContext?.address ?? this._address;
20995
+ const chainId = nodeContext?.chainId ?? this._chainId;
20996
+ const host = nodeContext?.host ?? this.config.host;
20997
+ const ownerDid = this.ownerDidFromSpaceId(spaceId) ?? did;
20334
20998
  return new import_sdk_core7.DataVaultService({
20335
20999
  spaceId,
20336
21000
  crypto: vaultCrypto,
20337
21001
  encryption: {
20338
- networkId: this.getEncryptionNetworkIdForSpace(spaceId),
20339
- service: this.getEncryptionService(),
21002
+ networkId: `urn:tinycloud:encryption:${ownerDid}:${DEFAULT_ENCRYPTION_NETWORK_NAME}`,
21003
+ service: encryptionService,
20340
21004
  decryptCapabilityProof: () => ({
20341
21005
  proofs: [this.requireServiceSession().delegationCid]
20342
21006
  })
@@ -20345,6 +21009,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20345
21009
  kv,
20346
21010
  ensurePublicSpace: async () => {
20347
21011
  try {
21012
+ serviceGraph.assertActive();
20348
21013
  await self2.ensurePublicSpace();
20349
21014
  return { ok: true, data: void 0 };
20350
21015
  } catch (error) {
@@ -20352,14 +21017,15 @@ var _TinyCloudNode = class _TinyCloudNode {
20352
21017
  }
20353
21018
  },
20354
21019
  get publicKV() {
21020
+ serviceGraph.assertActive();
20355
21021
  return self2._publicKV ?? self2.tc.publicKV;
20356
21022
  },
20357
- readPublicSpace: (host, targetSpaceId, key2) => import_sdk_core7.TinyCloud.readPublicSpace(host, targetSpaceId, key2),
21023
+ readPublicSpace: (host2, targetSpaceId, key2) => import_sdk_core7.TinyCloud.readPublicSpace(host2, targetSpaceId, key2),
20358
21024
  makePublicSpaceId: import_sdk_core7.TinyCloud.makePublicSpaceId,
20359
- did: this.did,
20360
- address: this._address ?? "",
20361
- chainId: this._chainId,
20362
- hosts: [this.config.host]
21025
+ did,
21026
+ address: address ?? "",
21027
+ chainId,
21028
+ hosts: [host]
20363
21029
  }
20364
21030
  });
20365
21031
  }
@@ -20368,6 +21034,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20368
21034
  * @internal
20369
21035
  */
20370
21036
  initializeV2Services(serviceSession) {
21037
+ const graph = this._serviceGraph;
20371
21038
  this._capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
20372
21039
  const tcSession = this.auth?.tinyCloudSession;
20373
21040
  if (tcSession && this._address) {
@@ -20410,22 +21077,25 @@ var _TinyCloudNode = class _TinyCloudNode {
20410
21077
  }
20411
21078
  this._delegationManager = new import_sdk_core7.DelegationManager({
20412
21079
  hosts: [this.config.host],
21080
+ accountSpaceId: this.accountSpaceId,
20413
21081
  session: serviceSession,
20414
- invoke: this.invokeWithRuntimePermissions,
20415
- invokeAny: this.invokeAnyWithRuntimePermissions,
20416
- fetch: globalThis.fetch.bind(globalThis)
21082
+ invoke: graph.invoke,
21083
+ invokeAny: graph.invokeAny,
21084
+ fetch: graph.fetch
20417
21085
  });
20418
21086
  this._spaceService = new import_sdk_core7.SpaceService({
20419
21087
  hosts: [this.config.host],
20420
21088
  session: serviceSession,
20421
- invoke: this.wasmBindings.invoke,
20422
- fetch: globalThis.fetch.bind(globalThis),
21089
+ invoke: graph.invoke,
21090
+ fetch: graph.fetch,
20423
21091
  capabilityRegistry: this._capabilityRegistry,
20424
21092
  userDid: this.did,
20425
21093
  createKVService: (spaceId) => {
21094
+ graph.assertActive();
20426
21095
  return this.createSpaceScopedKVService(spaceId);
20427
21096
  },
20428
21097
  createVaultService: (spaceId) => {
21098
+ graph.assertActive();
20429
21099
  const kvService = this.createSpaceScopedKVService(spaceId);
20430
21100
  const vaultService = this.createVaultService(spaceId, kvService);
20431
21101
  if (this._serviceContext) {
@@ -20434,11 +21104,13 @@ var _TinyCloudNode = class _TinyCloudNode {
20434
21104
  return vaultService;
20435
21105
  },
20436
21106
  createSecretsService: (spaceId) => {
21107
+ graph.assertActive();
20437
21108
  return this.secretsForSpace(spaceId);
20438
21109
  },
20439
21110
  // Enable space.delegations.create() via SIWE-based delegation
20440
21111
  createDelegation: async (params) => {
20441
21112
  try {
21113
+ graph.assertActive();
20442
21114
  const portableDelegation = await this.createDelegation({
20443
21115
  delegateDID: params.delegateDID,
20444
21116
  path: params.path,
@@ -20472,18 +21144,50 @@ var _TinyCloudNode = class _TinyCloudNode {
20472
21144
  }
20473
21145
  },
20474
21146
  onSpaceRegistered: async (space) => {
21147
+ graph.assertActive();
20475
21148
  await this.account.spaces.register(space);
20476
21149
  }
20477
21150
  });
20478
- this._sharingService.updateConfig({
21151
+ this._sharingService = new import_sdk_core7.SharingService({
21152
+ hosts: [this.config.host],
20479
21153
  session: serviceSession,
21154
+ invoke: graph.invoke,
21155
+ fetch: graph.fetch,
21156
+ assertActive: () => graph.assertActive(),
21157
+ keyProvider: this._keyProvider,
21158
+ registry: this._capabilityRegistry,
20480
21159
  delegationManager: this._delegationManager,
20481
21160
  sessionExpiry: this.getSessionExpiry(),
20482
- // WASM-based delegation creation (preferred - no server roundtrip)
20483
- createDelegationWasm: (params) => this.createDelegationWrapper(params),
20484
- // Root delegation for long-lived share links (bypasses session expiry)
20485
- // In node-sdk we have direct signer access, so no popup needed
20486
- onRootDelegationNeeded: this.signer ? async (params) => this.createRootDelegationForSharing(params) : void 0
21161
+ createDelegationWasm: (params) => {
21162
+ graph.assertActive();
21163
+ return this.createDelegationWrapper(params);
21164
+ },
21165
+ computeCid: (data, codec) => {
21166
+ if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
21167
+ return this.wasmBindings.computeCid(data, codec);
21168
+ },
21169
+ createKVService: (config) => {
21170
+ graph.assertActive();
21171
+ const service = new import_sdk_core7.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
21172
+ const context = graph.track(new import_sdk_core7.ServiceContext({
21173
+ invoke: config.invoke,
21174
+ fetch: config.fetch ?? graph.fetch,
21175
+ hosts: config.hosts,
21176
+ telemetry: this.config.telemetry
21177
+ }));
21178
+ context.setSession(config.session);
21179
+ service.initialize(context);
21180
+ return service;
21181
+ },
21182
+ onRootDelegationNeeded: this.signer ? async (params) => {
21183
+ graph.assertActive();
21184
+ const delegation = await this.createRootDelegationForSharing(
21185
+ params,
21186
+ () => graph.assertActive()
21187
+ );
21188
+ graph.assertActive();
21189
+ return delegation;
21190
+ } : void 0
20487
21191
  });
20488
21192
  this._spaceService.updateConfig({
20489
21193
  sharingService: this._sharingService
@@ -20550,7 +21254,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20550
21254
  * with expiry longer than the current session.
20551
21255
  * @internal
20552
21256
  */
20553
- async createOwnerDelegation(params) {
21257
+ async createOwnerDelegation(params, assertActive) {
21258
+ const assertOwnerGraphActive = assertActive ?? this._serviceGraph.assertActive.bind(this._serviceGraph);
21259
+ assertOwnerGraphActive();
20554
21260
  if (!params.delegateDid.startsWith("did:key:") || params.actions.length === 0 || params.path.length === 0) {
20555
21261
  throw new Error("Owner delegation requires an external did:key audience and bounded capabilities");
20556
21262
  }
@@ -20575,8 +21281,10 @@ var _TinyCloudNode = class _TinyCloudNode {
20575
21281
  delegateUri: params.delegateDid
20576
21282
  });
20577
21283
  const signature2 = await this.signer.signMessage(prepared.siwe);
21284
+ assertOwnerGraphActive();
20578
21285
  const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature: signature2 });
20579
21286
  const activation = await (0, import_sdk_core7.activateSessionWithHost)(host, delegationSession.delegationHeader);
21287
+ assertOwnerGraphActive();
20580
21288
  if (!activation.success) {
20581
21289
  throw new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim());
20582
21290
  }
@@ -20604,7 +21312,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20604
21312
  }
20605
21313
  };
20606
21314
  }
20607
- async createRootDelegationForSharing(params) {
21315
+ async createRootDelegationForSharing(params, assertActive) {
20608
21316
  try {
20609
21317
  return (await this.createOwnerDelegation({
20610
21318
  delegateDid: params.shareKeyDID,
@@ -20612,8 +21320,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20612
21320
  path: params.path,
20613
21321
  actions: params.actions,
20614
21322
  expiresAt: params.requestedExpiry
20615
- })).delegation;
21323
+ }, assertActive)).delegation;
20616
21324
  } catch {
21325
+ assertActive?.();
20617
21326
  return void 0;
20618
21327
  }
20619
21328
  }
@@ -20685,13 +21394,13 @@ var _TinyCloudNode = class _TinyCloudNode {
20685
21394
  throw new Error("Not signed in. Call signIn() first.");
20686
21395
  }
20687
21396
  const sql = new import_sdk_core7.SQLService({});
20688
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
21397
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20689
21398
  invoke: this._serviceContext.invoke,
20690
21399
  invokeAny: this._serviceContext.invokeAny,
20691
21400
  fetch: this._serviceContext.fetch,
20692
21401
  hosts: this._serviceContext.hosts,
20693
21402
  telemetry: this.config.telemetry
20694
- });
21403
+ }));
20695
21404
  spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
20696
21405
  sql.initialize(spaceScopedContext);
20697
21406
  return sql;
@@ -20715,12 +21424,12 @@ var _TinyCloudNode = class _TinyCloudNode {
20715
21424
  throw new Error("Not signed in. Call signIn() first.");
20716
21425
  }
20717
21426
  const kv = new import_sdk_core7.KVService({});
20718
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
21427
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20719
21428
  invoke: this._serviceContext.invoke,
20720
21429
  invokeAny: this._serviceContext.invokeAny,
20721
21430
  fetch: this._serviceContext.fetch,
20722
21431
  hosts: this._serviceContext.hosts
20723
- });
21432
+ }));
20724
21433
  spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
20725
21434
  kv.initialize(spaceScopedContext);
20726
21435
  return kv;
@@ -20756,19 +21465,11 @@ var _TinyCloudNode = class _TinyCloudNode {
20756
21465
  }
20757
21466
  async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
20758
21467
  const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
20759
- const response = await fetch(
20760
- `${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}`
21468
+ return this.fetchEncryptionNetworkAt(
21469
+ this.config.host,
21470
+ networkId,
21471
+ globalThis.fetch.bind(globalThis)
20761
21472
  );
20762
- if (response.status === 404) {
20763
- return null;
20764
- }
20765
- if (!response.ok) {
20766
- throw new Error(
20767
- `Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
20768
- );
20769
- }
20770
- const body = await response.json();
20771
- return "descriptor" in body && body.descriptor ? body.descriptor : body;
20772
21473
  }
20773
21474
  async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
20774
21475
  const targetNode = await this.fetchNodeId();
@@ -20862,6 +21563,38 @@ var _TinyCloudNode = class _TinyCloudNode {
20862
21563
  }
20863
21564
  return secrets;
20864
21565
  }
21566
+ /**
21567
+ * Read a secret from an explicit target space without requesting or
21568
+ * auto-signing authority. Active runtime delegations are selected by the
21569
+ * normal KV and encryption invocation paths.
21570
+ */
21571
+ async readSecret(input) {
21572
+ const resolved = (0, import_sdk_core7.resolveSecretPath)(input.name, { scope: input.scope });
21573
+ const targetSpace = input.space.startsWith("tinycloud:") ? input.space : this.ownedSpaceId(input.space);
21574
+ const result = await this.getBaseVault(targetSpace).readNetworkEncrypted(
21575
+ resolved.vaultKey
21576
+ );
21577
+ if (result.status !== "ok") {
21578
+ if (result.status === "permission_required") {
21579
+ const hint = (0, import_sdk_services.parsePermissionHint)(result.hint);
21580
+ if (hint === void 0) return { status: "read_failed" };
21581
+ return {
21582
+ status: "permission_required",
21583
+ hint: {
21584
+ service: hint.service,
21585
+ ...hint.space === void 0 ? {} : { space: hint.space },
21586
+ path: hint.path,
21587
+ actions: [...hint.actions]
21588
+ }
21589
+ };
21590
+ }
21591
+ return { status: result.status };
21592
+ }
21593
+ if (!isSecretPayload(result.entry.value)) {
21594
+ return { status: "invalid_payload" };
21595
+ }
21596
+ return { status: "ok", value: result.entry.value.value };
21597
+ }
20865
21598
  getBaseSecrets(spaceId) {
20866
21599
  if (!this._spaceService) {
20867
21600
  throw new Error("Not signed in. Call signIn() first.");
@@ -20869,16 +21602,29 @@ var _TinyCloudNode = class _TinyCloudNode {
20869
21602
  const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
20870
21603
  let secrets = this._baseSecrets.get(resolvedSpace);
20871
21604
  if (!secrets) {
20872
- const kvService = this.createSpaceScopedKVService(resolvedSpace);
20873
- const vaultService = this.createVaultService(resolvedSpace, kvService);
20874
- if (this._serviceContext) {
20875
- vaultService.initialize(this._serviceContext);
20876
- }
20877
- secrets = new import_sdk_core7.SecretsService(() => vaultService);
21605
+ secrets = new import_sdk_core7.SecretsService(() => this.getBaseVault(resolvedSpace));
20878
21606
  this._baseSecrets.set(resolvedSpace, secrets);
20879
21607
  }
20880
21608
  return secrets;
20881
21609
  }
21610
+ getBaseVault(spaceId) {
21611
+ if (!this._spaceService) {
21612
+ throw new Error("Not signed in. Call signIn() first.");
21613
+ }
21614
+ const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
21615
+ let vault = this._baseVaults.get(resolvedSpace);
21616
+ if (!vault) {
21617
+ vault = this.createVaultService(
21618
+ resolvedSpace,
21619
+ this.createSpaceScopedKVService(resolvedSpace)
21620
+ );
21621
+ if (this._serviceContext) {
21622
+ vault.initialize(this._serviceContext);
21623
+ }
21624
+ this._baseVaults.set(resolvedSpace, vault);
21625
+ }
21626
+ return vault;
21627
+ }
20882
21628
  /**
20883
21629
  * Hooks write stream subscription API.
20884
21630
  */
@@ -20983,6 +21729,63 @@ var _TinyCloudNode = class _TinyCloudNode {
20983
21729
  (grant) => grant.delegation
20984
21730
  );
20985
21731
  }
21732
+ /**
21733
+ * Return the effective capabilities of installed runtime grants.
21734
+ *
21735
+ * The result is projected from the SDK's activated, expiry-pruned grant
21736
+ * operations rather than from PortableDelegation transport metadata. Base
21737
+ * session authority is intentionally omitted; callers that need the full
21738
+ * live authority must combine this with {@link getVerifiedSessionCapabilities}.
21739
+ */
21740
+ getEffectiveRuntimePermissionEntries() {
21741
+ const session = this.currentTinyCloudSession();
21742
+ if (!session) return [];
21743
+ this.pruneExpiredRuntimePermissionGrants();
21744
+ const grouped = /* @__PURE__ */ new Map();
21745
+ for (const grant of this.runtimePermissionGrants) {
21746
+ if (grant.provenance === "primary") continue;
21747
+ for (const operation of grant.operations) {
21748
+ const service = import_sdk_core7.SERVICE_SHORT_TO_LONG[operation.service];
21749
+ if (service === void 0 || typeof operation.path !== "string" || typeof operation.action !== "string") {
21750
+ continue;
21751
+ }
21752
+ let space;
21753
+ if (service !== "tinycloud.encryption") {
21754
+ if (typeof operation.spaceId !== "string") continue;
21755
+ try {
21756
+ space = this.resolvePermissionSpace(operation.spaceId, session);
21757
+ } catch {
21758
+ continue;
21759
+ }
21760
+ }
21761
+ const caveats = operation.caveats === void 0 || operation.caveats.length === 0 ? void 0 : cloneRecapCaveats(operation.caveats);
21762
+ const identity = JSON.stringify({
21763
+ service,
21764
+ ...space === void 0 ? {} : { space },
21765
+ path: operation.path,
21766
+ caveats: (0, import_sdk_core7.canonicalizeRecapCaveats)(caveats)
21767
+ });
21768
+ const existing = grouped.get(identity);
21769
+ if (existing === void 0) {
21770
+ grouped.set(identity, {
21771
+ service,
21772
+ ...space === void 0 ? {} : { space },
21773
+ path: operation.path,
21774
+ actions: [operation.action],
21775
+ ...caveats === void 0 ? {} : { caveats }
21776
+ });
21777
+ continue;
21778
+ }
21779
+ if (!existing.actions.includes(operation.action)) {
21780
+ existing.actions.push(operation.action);
21781
+ existing.actions.sort();
21782
+ }
21783
+ }
21784
+ }
21785
+ return [...grouped.values()].sort(
21786
+ (left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0"))
21787
+ );
21788
+ }
20986
21789
  /**
20987
21790
  * Install a portable runtime permission delegation into this SDK instance so
20988
21791
  * matching service calls and downstream `delegateTo()` calls can use it.
@@ -21051,6 +21854,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21051
21854
  "grantRuntimePermissions requires wallet mode with a signer or privateKey."
21052
21855
  );
21053
21856
  }
21857
+ this.assertDelegationCaveatsPreservable(expanded);
21054
21858
  const rawEntries = expanded.filter(
21055
21859
  (entry) => this.isEncryptionPermissionEntry(entry)
21056
21860
  );
@@ -21312,12 +22116,12 @@ var _TinyCloudNode = class _TinyCloudNode {
21312
22116
  }
21313
22117
  if (this._serviceContext) {
21314
22118
  const publicKV = new import_sdk_core7.KVService({ prefix: "" });
21315
- const publicContext = new import_sdk_core7.ServiceContext({
21316
- invoke: this.invokeWithRuntimePermissions,
21317
- fetch: this._serviceContext.fetch,
22119
+ const publicContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
22120
+ invoke: this._serviceGraph.invoke,
22121
+ fetch: this._serviceGraph.fetch,
21318
22122
  hosts: this._serviceContext.hosts,
21319
22123
  telemetry: this.config.telemetry
21320
- });
22124
+ }));
21321
22125
  publicContext.setSession({
21322
22126
  delegationHeader: delegationSession.delegationHeader,
21323
22127
  delegationCid: delegationSession.delegationCid,
@@ -21384,13 +22188,14 @@ var _TinyCloudNode = class _TinyCloudNode {
21384
22188
  async getDelegationStatus(cid) {
21385
22189
  return this.delegationManager.status(cid);
21386
22190
  }
21387
- /** Compute the canonical CID of a compact delegation authorization. */
22191
+ /** Compute the canonical CID of a compact UCAN or DAG-CBOR delegation authorization. */
21388
22192
  computeDelegationCid(authorization) {
21389
22193
  if (!authorization || !this.wasmBindings.computeCid) {
21390
22194
  throw new Error("Delegation CID computation is unavailable");
21391
22195
  }
22196
+ const compact = authorization.replace(/^Bearer /i, "");
21392
22197
  return this.wasmBindings.computeCid(
21393
- new TextEncoder().encode(authorization),
22198
+ compact.includes(".") ? new TextEncoder().encode(compact) : decodeAuthorizationBytes(authorization),
21394
22199
  0x55n
21395
22200
  );
21396
22201
  }
@@ -21482,6 +22287,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21482
22287
  "delegateTo with forceWalletSign=true supports at most one PermissionEntry. Multi-entry requests must go through the session-key UCAN path (drop forceWalletSign) or the legacy createDelegation method."
21483
22288
  );
21484
22289
  }
22290
+ this.assertDelegationCaveatsPreservable(expandedEntries);
21485
22291
  const delegation2 = await this.createDelegationLegacyWalletPath(
21486
22292
  did,
21487
22293
  expandedEntries[0],
@@ -21490,13 +22296,14 @@ var _TinyCloudNode = class _TinyCloudNode {
21490
22296
  return { delegation: delegation2, prompted: true };
21491
22297
  }
21492
22298
  const granted = (0, import_sdk_core7.parseRecapCapabilities)(
21493
- (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
22299
+ (siwe) => this.parseRecapWithCaveats(siwe),
21494
22300
  session.siwe
21495
22301
  );
21496
22302
  const { subset, missing } = (0, import_sdk_core7.isCapabilitySubset)(expandedEntries, granted);
21497
22303
  if (!subset) {
22304
+ const runtimeOperations = this.permissionEntriesToOperations(expandedEntries, session);
21498
22305
  const runtimeGrant = this.findGrantForOperations(
21499
- this.permissionEntriesToOperations(expandedEntries, session),
22306
+ runtimeOperations,
21500
22307
  { excludePrimary: true }
21501
22308
  );
21502
22309
  if (runtimeGrant) {
@@ -21509,7 +22316,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21509
22316
  did,
21510
22317
  expandedEntries,
21511
22318
  runtimeExpiration,
21512
- runtimeGrant
22319
+ runtimeGrant,
22320
+ runtimeOperations
21513
22321
  );
21514
22322
  return { delegation: delegation2, prompted: false };
21515
22323
  }
@@ -21579,6 +22387,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21579
22387
  "createDelegationViaWasmPath requires a non-empty entries array"
21580
22388
  );
21581
22389
  }
22390
+ this.assertDelegationCaveatsPreservable(entries);
21582
22391
  const resolvedSpaces = /* @__PURE__ */ new Set();
21583
22392
  for (const entry of entries) {
21584
22393
  if (this.isEncryptionPermissionEntry(entry)) {
@@ -21659,7 +22468,9 @@ var _TinyCloudNode = class _TinyCloudNode {
21659
22468
  host: this.config.host
21660
22469
  };
21661
22470
  }
21662
- async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
22471
+ async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations) {
22472
+ this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
22473
+ this.assertDelegationCaveatsPreservable(entries);
21663
22474
  const result = this.createDelegationWrapper({
21664
22475
  session: grant.session,
21665
22476
  delegateDID: did,
@@ -21713,6 +22524,74 @@ var _TinyCloudNode = class _TinyCloudNode {
21713
22524
  expandPermissionEntries(permissions) {
21714
22525
  return (0, import_sdk_core7.expandPermissionEntries)(permissions);
21715
22526
  }
22527
+ /**
22528
+ * The current WASM child-delegation APIs accept action-only maps. Refuse any
22529
+ * constrained branch rather than signing a broader action-only child UCAN.
22530
+ */
22531
+ assertDelegationCaveatsPreservable(entries) {
22532
+ const caveated = entries.filter(
22533
+ (entry) => !(0, import_sdk_core7.recapCaveatsEqual)(entry.caveats, void 0)
22534
+ );
22535
+ if (caveated.length > 0) {
22536
+ throw new import_sdk_core7.CaveatedDelegationUnsupportedError(caveated);
22537
+ }
22538
+ }
22539
+ /**
22540
+ * Runtime grant selection intentionally allows an uncaveated operation to
22541
+ * select a caveated grant so invocation can restore the signed caveat before
22542
+ * crossing the caveat-aware WASM boundary. Child delegation cannot do that:
22543
+ * it only accepts action maps, so reject the selected constrained branch.
22544
+ */
22545
+ assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant) {
22546
+ let operationIndex = 0;
22547
+ const caveated = [];
22548
+ for (const entry of entries) {
22549
+ for (const action of entry.actions) {
22550
+ const requested = requestedOperations[operationIndex++];
22551
+ if (!requested) continue;
22552
+ const constrained = grant.operations.find(
22553
+ (granted) => this.operationCovers(granted, requested) && !(0, import_sdk_core7.recapCaveatsEqual)(granted.caveats, void 0)
22554
+ );
22555
+ if (constrained) {
22556
+ caveated.push({
22557
+ ...entry,
22558
+ actions: [action],
22559
+ caveats: cloneRecapCaveats(constrained.caveats)
22560
+ });
22561
+ }
22562
+ }
22563
+ }
22564
+ if (caveated.length > 0) {
22565
+ throw new import_sdk_core7.CaveatedDelegationUnsupportedError(caveated);
22566
+ }
22567
+ }
22568
+ /** Reject caveated parent branches before action-only child signing. */
22569
+ assertPortableDelegationCaveatsPreservable(delegation) {
22570
+ const entries = [];
22571
+ const add3 = (service, space, path, actions, caveats) => {
22572
+ if ((0, import_sdk_core7.recapCaveatsEqual)(caveats, void 0)) return;
22573
+ entries.push({
22574
+ service: service.startsWith("tinycloud.") ? service : `tinycloud.${service}`,
22575
+ space,
22576
+ path,
22577
+ actions: [...actions],
22578
+ caveats: cloneRecapCaveats(caveats)
22579
+ });
22580
+ };
22581
+ add3(
22582
+ delegation.actions[0]?.split("/", 1)[0] ?? "tinycloud.unknown",
22583
+ delegation.spaceId,
22584
+ delegation.path,
22585
+ delegation.actions,
22586
+ delegation.caveats
22587
+ );
22588
+ for (const resource of delegation.resources ?? []) {
22589
+ add3(resource.service, resource.space, resource.path, resource.actions, resource.caveats);
22590
+ }
22591
+ if (entries.length > 0) {
22592
+ throw new import_sdk_core7.CaveatedDelegationUnsupportedError(entries);
22593
+ }
22594
+ }
21716
22595
  shortServiceName(service) {
21717
22596
  const short = import_sdk_core7.SERVICE_LONG_TO_SHORT[service];
21718
22597
  if (short === void 0) {
@@ -21767,14 +22646,15 @@ var _TinyCloudNode = class _TinyCloudNode {
21767
22646
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
21768
22647
  service,
21769
22648
  path: entry.path,
21770
- action
22649
+ action,
22650
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21771
22651
  }));
21772
22652
  });
21773
22653
  }
21774
22654
  sessionCoversPermissionEntries(session, entries) {
21775
22655
  try {
21776
22656
  const granted = (0, import_sdk_core7.parseRecapCapabilities)(
21777
- (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
22657
+ (siwe) => this.parseRecapWithCaveats(siwe),
21778
22658
  session.siwe
21779
22659
  );
21780
22660
  return (0, import_sdk_core7.isCapabilitySubset)(entries, granted).subset;
@@ -21790,7 +22670,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21790
22670
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
21791
22671
  service,
21792
22672
  path: entry.path,
21793
- action
22673
+ action,
22674
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21794
22675
  }));
21795
22676
  });
21796
22677
  }
@@ -21866,7 +22747,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21866
22747
  service: this.shortServiceName(entry.service),
21867
22748
  space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
21868
22749
  path: entry.path,
21869
- actions: [...entry.actions]
22750
+ actions: [...entry.actions],
22751
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21870
22752
  }));
21871
22753
  }
21872
22754
  operationsFromDelegation(delegation) {
@@ -21877,7 +22759,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21877
22759
  ...this.isEncryptionNetworkOperation(service, resource.path) ? { resource: resource.path } : { spaceId: resource.space },
21878
22760
  service,
21879
22761
  path: resource.path,
21880
- action
22762
+ action,
22763
+ caveats: cloneRecapCaveats(resource.caveats)
21881
22764
  }));
21882
22765
  });
21883
22766
  }
@@ -21893,7 +22776,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21893
22776
  service,
21894
22777
  space: delegation.spaceId,
21895
22778
  path: delegation.path,
21896
- actions
22779
+ actions,
22780
+ ...delegation.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(delegation.caveats) }
21897
22781
  }));
21898
22782
  }
21899
22783
  /**
@@ -21994,6 +22878,9 @@ var _TinyCloudNode = class _TinyCloudNode {
21994
22878
  if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
21995
22879
  return false;
21996
22880
  }
22881
+ if (requested.caveats !== void 0 && !(0, import_sdk_core7.recapCaveatsEqual)(granted.caveats, requested.caveats)) {
22882
+ return false;
22883
+ }
21997
22884
  if (granted.resource !== void 0 || requested.resource !== void 0) {
21998
22885
  return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
21999
22886
  }
@@ -22028,6 +22915,10 @@ var _TinyCloudNode = class _TinyCloudNode {
22028
22915
  invocationServiceName(service) {
22029
22916
  return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
22030
22917
  }
22918
+ /** Prefer the v2 caveat-preserving parser while retaining old custom WASM. */
22919
+ parseRecapWithCaveats(siwe) {
22920
+ return this.wasmBindings.parseVerifiedRecapFromSiwe?.(siwe) ?? this.wasmBindings.parseRecapFromSiwe(siwe);
22921
+ }
22031
22922
  isEncryptionNetworkOperation(service, path) {
22032
22923
  return service === "encryption" && path.startsWith("urn:tinycloud:encryption:");
22033
22924
  }
@@ -22038,7 +22929,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22038
22929
  resource: entry.resource,
22039
22930
  service,
22040
22931
  path: entry.path,
22041
- action: entry.action
22932
+ action: entry.action,
22933
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22042
22934
  };
22043
22935
  }
22044
22936
  if (this.isEncryptionNetworkOperation(service, entry.path)) {
@@ -22046,7 +22938,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22046
22938
  resource: entry.path,
22047
22939
  service,
22048
22940
  path: entry.path,
22049
- action: entry.action
22941
+ action: entry.action,
22942
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22050
22943
  };
22051
22944
  }
22052
22945
  if (typeof entry.spaceId === "string") {
@@ -22054,7 +22947,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22054
22947
  spaceId: entry.spaceId,
22055
22948
  service,
22056
22949
  path: entry.path,
22057
- action: entry.action
22950
+ action: entry.action,
22951
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22058
22952
  };
22059
22953
  }
22060
22954
  return void 0;
@@ -22394,6 +23288,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22394
23288
  * @returns A portable delegation for the sub-delegate
22395
23289
  */
22396
23290
  async createSubDelegation(parentDelegation, params) {
23291
+ this.assertPortableDelegationCaveatsPreservable(parentDelegation);
22397
23292
  if (!this.signer) {
22398
23293
  throw new Error("Cannot createSubDelegation() in session-only mode. Requires wallet mode.");
22399
23294
  }
@@ -22492,8 +23387,8 @@ TinyCloudNode.registerNodeDefaults({
22492
23387
  });
22493
23388
 
22494
23389
  // src/index.ts
22495
- var import_sdk_core9 = require("@tinycloud/sdk-core");
22496
23390
  var import_sdk_core10 = require("@tinycloud/sdk-core");
23391
+ var import_sdk_core11 = require("@tinycloud/sdk-core");
22497
23392
 
22498
23393
  // src/storage/FileSessionStorage.ts
22499
23394
  var import_sdk_core8 = require("@tinycloud/sdk-core");
@@ -22616,9 +23511,279 @@ var FileSessionStorage = class {
22616
23511
  };
22617
23512
 
22618
23513
  // src/index.ts
22619
- var import_sdk_core11 = require("@tinycloud/sdk-core");
23514
+ var import_sdk_core12 = require("@tinycloud/sdk-core");
22620
23515
 
22621
23516
  // src/delegation.ts
23517
+ var import_sdk_core9 = require("@tinycloud/sdk-core");
23518
+ var SERVICE_BY_SHORT_NAME = {
23519
+ kv: "tinycloud.kv",
23520
+ sql: "tinycloud.sql",
23521
+ duckdb: "tinycloud.duckdb",
23522
+ hooks: "tinycloud.hooks"
23523
+ };
23524
+ function authorizationWithoutBearer(authorization) {
23525
+ return authorization.replace(/^Bearer /i, "");
23526
+ }
23527
+ function normalizedHost(host) {
23528
+ if (typeof host !== "string" || host.length === 0) {
23529
+ throw new Error("Validated runtime delegation requires a non-empty host.");
23530
+ }
23531
+ return host.replace(/\/+$/, "");
23532
+ }
23533
+ function didPrincipalsMatch(left, right) {
23534
+ try {
23535
+ return (0, import_sdk_core9.principalDidEquals)(left, right);
23536
+ } catch {
23537
+ return left === right;
23538
+ }
23539
+ }
23540
+ function compactUcanPayload(authorization) {
23541
+ const compact = authorizationWithoutBearer(authorization);
23542
+ const parts = compact.split(".");
23543
+ if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
23544
+ throw new Error(
23545
+ "Validated runtime delegation requires a compact UCAN authorization so its signed authority can be derived."
23546
+ );
23547
+ }
23548
+ try {
23549
+ const payload = JSON.parse(
23550
+ Buffer.from(parts[1], "base64url").toString("utf8")
23551
+ );
23552
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
23553
+ throw new Error("payload is not an object");
23554
+ }
23555
+ return payload;
23556
+ } catch {
23557
+ throw new Error(
23558
+ "Validated runtime delegation authorization has an invalid compact UCAN payload."
23559
+ );
23560
+ }
23561
+ }
23562
+ function canonicalPermissionEntries(permissions) {
23563
+ return permissions.map((permission) => ({
23564
+ ...permission,
23565
+ actions: [...permission.actions].sort()
23566
+ })).sort(
23567
+ (left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0")) || (0, import_sdk_core9.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core9.canonicalizeRecapCaveats)(right.caveats))
23568
+ );
23569
+ }
23570
+ function signedCaveats(value) {
23571
+ if (!Array.isArray(value) || value.some(
23572
+ (caveat) => caveat === null || typeof caveat !== "object" || Array.isArray(caveat)
23573
+ )) {
23574
+ throw new Error("Validated runtime delegation has malformed signed ReCap caveats.");
23575
+ }
23576
+ const cloned = JSON.parse(JSON.stringify(value));
23577
+ return (0, import_sdk_core9.canonicalizeRecapCaveats)(cloned) === (0, import_sdk_core9.canonicalizeRecapCaveats)(void 0) ? void 0 : cloned;
23578
+ }
23579
+ function groupedSignedEntries(service, space, path, abilities) {
23580
+ const groups = /* @__PURE__ */ new Map();
23581
+ for (const [action, rawCaveats] of Object.entries(abilities)) {
23582
+ const caveats = signedCaveats(rawCaveats);
23583
+ const identity = (0, import_sdk_core9.canonicalizeRecapCaveats)(caveats);
23584
+ const group = groups.get(identity) ?? { actions: [], caveats };
23585
+ group.actions.push(action);
23586
+ groups.set(identity, group);
23587
+ }
23588
+ return [...groups.values()].map((group) => ({
23589
+ service,
23590
+ ...space === void 0 ? {} : { space },
23591
+ path,
23592
+ actions: group.actions.sort(),
23593
+ ...group.caveats === void 0 ? {} : { caveats: group.caveats }
23594
+ }));
23595
+ }
23596
+ function signedAuthorityFromCompactUcan(authorization) {
23597
+ const payload = compactUcanPayload(authorization);
23598
+ if (typeof payload.aud !== "string" || payload.aud.length === 0) {
23599
+ throw new Error("Validated runtime delegation is missing a signed audience.");
23600
+ }
23601
+ if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
23602
+ throw new Error("Validated runtime delegation is missing a signed expiry.");
23603
+ }
23604
+ const expiry = new Date(payload.exp * 1e3);
23605
+ if (Number.isNaN(expiry.getTime())) {
23606
+ throw new Error("Validated runtime delegation has an invalid signed expiry.");
23607
+ }
23608
+ if (payload.att === null || typeof payload.att !== "object" || Array.isArray(payload.att)) {
23609
+ throw new Error("Validated runtime delegation is missing a signed attenuation.");
23610
+ }
23611
+ const permissions = [];
23612
+ for (const [resource, abilities] of Object.entries(payload.att)) {
23613
+ if (abilities === null || typeof abilities !== "object" || Array.isArray(abilities)) {
23614
+ throw new Error("Validated runtime delegation has an invalid signed attenuation.");
23615
+ }
23616
+ const abilityEntries = Object.entries(abilities);
23617
+ if (abilityEntries.length === 0) {
23618
+ throw new Error("Validated runtime delegation has an empty signed capability.");
23619
+ }
23620
+ if (resource.startsWith("urn:tinycloud:encryption:")) {
23621
+ permissions.push(...groupedSignedEntries(
23622
+ "tinycloud.encryption",
23623
+ void 0,
23624
+ resource,
23625
+ abilities
23626
+ ));
23627
+ continue;
23628
+ }
23629
+ const match = /^(tinycloud:[^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
23630
+ if (!match) {
23631
+ throw new Error(
23632
+ `Validated runtime delegation has an unsupported signed resource '${resource}'.`
23633
+ );
23634
+ }
23635
+ const [, space, shortService, path] = match;
23636
+ const service = SERVICE_BY_SHORT_NAME[shortService];
23637
+ if (service === void 0) {
23638
+ throw new Error(
23639
+ `Validated runtime delegation has an unsupported signed service '${shortService}'.`
23640
+ );
23641
+ }
23642
+ permissions.push(...groupedSignedEntries(
23643
+ service,
23644
+ space,
23645
+ path,
23646
+ abilities
23647
+ ));
23648
+ }
23649
+ if (permissions.length === 0) {
23650
+ throw new Error("Validated runtime delegation has no signed capabilities.");
23651
+ }
23652
+ const canonicalPermissions = canonicalPermissionEntries(permissions);
23653
+ const canonicalResources = canonicalPermissions.map((permission) => ({
23654
+ service: permission.service === "tinycloud.encryption" ? "encryption" : permission.service.slice("tinycloud.".length),
23655
+ space: permission.service === "tinycloud.encryption" ? "encryption" : permission.space,
23656
+ path: permission.path,
23657
+ actions: [...permission.actions],
23658
+ ...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
23659
+ }));
23660
+ return {
23661
+ audience: payload.aud,
23662
+ expiry,
23663
+ permissions: canonicalPermissions,
23664
+ resources: canonicalResources
23665
+ };
23666
+ }
23667
+ function canonicalResourcesFromPortableDelegation(delegation) {
23668
+ if (delegation.resources !== void 0 && delegation.resources.length > 0) {
23669
+ return delegation.resources.map((resource) => ({ ...resource, actions: [...resource.actions].sort() })).sort(
23670
+ (left, right) => left.service.localeCompare(right.service) || left.space.localeCompare(right.space) || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0")) || (0, import_sdk_core9.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core9.canonicalizeRecapCaveats)(right.caveats))
23671
+ );
23672
+ }
23673
+ const byService = /* @__PURE__ */ new Map();
23674
+ for (const action of delegation.actions) {
23675
+ const [service] = action.split("/", 1);
23676
+ const shortService = service.replace(/^tinycloud\./, "");
23677
+ const values = byService.get(shortService) ?? [];
23678
+ values.push(action);
23679
+ byService.set(shortService, values);
23680
+ }
23681
+ return [...byService.entries()].map(([service, actions]) => ({
23682
+ service,
23683
+ space: service === "encryption" ? "encryption" : delegation.spaceId,
23684
+ path: delegation.path,
23685
+ actions: [...new Set(actions)].sort(),
23686
+ ...delegation.caveats === void 0 ? {} : { caveats: delegation.caveats }
23687
+ })).sort(
23688
+ (left, right) => left.service.localeCompare(right.service) || left.space.localeCompare(right.space) || left.path.localeCompare(right.path)
23689
+ );
23690
+ }
23691
+ function resourcesMatch(actual, expected) {
23692
+ const comparable = (resource) => ({
23693
+ ...resource,
23694
+ caveats: (0, import_sdk_core9.canonicalizeRecapCaveats)(resource.caveats)
23695
+ });
23696
+ return JSON.stringify(actual.map(comparable)) === JSON.stringify(expected.map(comparable));
23697
+ }
23698
+ async function activateValidatedRuntimeDelegation(node, delegation, options) {
23699
+ const host = normalizedHost(options.host);
23700
+ if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
23701
+ throw new Error(
23702
+ `Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
23703
+ );
23704
+ }
23705
+ if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
23706
+ throw new Error("Runtime delegation has an invalid expiry.");
23707
+ }
23708
+ if (delegation.expiry.getTime() <= Date.now()) {
23709
+ throw new Error("Runtime delegation is expired.");
23710
+ }
23711
+ const authorization = delegation.delegationHeader?.Authorization;
23712
+ if (typeof authorization !== "string" || authorization.length === 0) {
23713
+ throw new Error("Runtime delegation is missing authorization bytes.");
23714
+ }
23715
+ const cid = node.computeDelegationCid(authorization);
23716
+ if (cid !== delegation.cid) {
23717
+ throw new Error("Runtime delegation CID does not match authorization bytes.");
23718
+ }
23719
+ const signed2 = signedAuthorityFromCompactUcan(authorization);
23720
+ if (signed2.expiry.getTime() <= Date.now()) {
23721
+ throw new Error("Runtime delegation is expired.");
23722
+ }
23723
+ if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
23724
+ throw new Error("Runtime delegation expiry does not match signed authority.");
23725
+ }
23726
+ if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
23727
+ throw new Error(
23728
+ `Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
23729
+ );
23730
+ }
23731
+ if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
23732
+ throw new Error("Runtime delegation audience does not match signed authority.");
23733
+ }
23734
+ const declaredResources = canonicalResourcesFromPortableDelegation(delegation);
23735
+ if (!resourcesMatch(declaredResources, signed2.resources)) {
23736
+ throw new Error("Runtime delegation resources do not match signed authority.");
23737
+ }
23738
+ const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
23739
+ if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
23740
+ throw new Error(
23741
+ "A different authorization is already installed for this runtime delegation CID."
23742
+ );
23743
+ }
23744
+ const primary = signed2.resources[0];
23745
+ const signedSpace = signed2.permissions.find(
23746
+ (permission) => permission.service !== "tinycloud.encryption"
23747
+ )?.space;
23748
+ const installedCandidate = {
23749
+ cid,
23750
+ delegationHeader: { Authorization: authorization },
23751
+ ownerAddress: delegation.ownerAddress,
23752
+ chainId: delegation.chainId,
23753
+ spaceId: signedSpace ?? delegation.spaceId,
23754
+ path: primary.path,
23755
+ actions: [...primary.actions],
23756
+ ...primary.caveats === void 0 ? {} : { caveats: primary.caveats },
23757
+ resources: signed2.resources.map((resource) => ({
23758
+ ...resource,
23759
+ actions: [...resource.actions]
23760
+ })),
23761
+ expiry: new Date(signed2.expiry),
23762
+ delegateDID: signed2.audience,
23763
+ host
23764
+ };
23765
+ await node.useRuntimeDelegation(installedCandidate);
23766
+ const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
23767
+ if (!installed) {
23768
+ throw new Error("Runtime delegation activation did not install the validated authority.");
23769
+ }
23770
+ if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
23771
+ canonicalResourcesFromPortableDelegation(installed),
23772
+ signed2.resources
23773
+ ) || normalizedHost(installed.host ?? "") !== host) {
23774
+ throw new Error(
23775
+ "Runtime delegation activation installed authority that differs from the validated authority."
23776
+ );
23777
+ }
23778
+ return {
23779
+ cid,
23780
+ delegation: installed,
23781
+ effectivePermissions: signed2.permissions,
23782
+ expiry: new Date(signed2.expiry),
23783
+ audience: signed2.audience,
23784
+ host: normalizedHost(installed.host ?? host)
23785
+ };
23786
+ }
22622
23787
  async function grantAuthRequest(authority, request, options) {
22623
23788
  if (request.kind !== "tinycloud.auth.request") {
22624
23789
  throw new Error(
@@ -22661,7 +23826,6 @@ function deserializeDelegation(data) {
22661
23826
  }
22662
23827
 
22663
23828
  // src/index.ts
22664
- var import_sdk_core12 = require("@tinycloud/sdk-core");
22665
23829
  var import_sdk_core13 = require("@tinycloud/sdk-core");
22666
23830
  var import_sdk_core14 = require("@tinycloud/sdk-core");
22667
23831
  var import_sdk_core15 = require("@tinycloud/sdk-core");
@@ -22672,6 +23836,7 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
22672
23836
  var import_sdk_core20 = require("@tinycloud/sdk-core");
22673
23837
  var import_sdk_core21 = require("@tinycloud/sdk-core");
22674
23838
  var import_sdk_core22 = require("@tinycloud/sdk-core");
23839
+ var import_sdk_core23 = require("@tinycloud/sdk-core");
22675
23840
  // Annotate the CommonJS export names for ESM import in node:
22676
23841
  0 && (module.exports = {
22677
23842
  ACCOUNT_REGISTRY_PATH,
@@ -22680,6 +23845,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22680
23845
  AutoApproveSpaceCreationHandler,
22681
23846
  CapabilityKeyRegistry,
22682
23847
  CapabilityKeyRegistryErrorCodes,
23848
+ CaveatedDelegationUnsupportedError,
22683
23849
  DECRYPT_ACTION,
22684
23850
  DECRYPT_FACT_TYPE,
22685
23851
  DECRYPT_RESULT_TYPE,
@@ -22690,6 +23856,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22690
23856
  DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
22691
23857
  DataVaultService,
22692
23858
  DatabaseHandle,
23859
+ DecryptTransportResponseError,
22693
23860
  DelegatedAccess,
22694
23861
  DelegationErrorCodes,
22695
23862
  DelegationManager,
@@ -22730,11 +23897,13 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22730
23897
  TinyCloudDebugLogger,
22731
23898
  TinyCloudNode,
22732
23899
  UnsupportedFeatureError,
23900
+ UnsupportedSessionRestoreError,
22733
23901
  VAULT_PERMISSION_SERVICE,
22734
23902
  VaultHeaders,
22735
23903
  VaultPublicSpaceKVActions,
22736
23904
  VersionCheckError,
22737
23905
  WasmKeyProvider,
23906
+ activateValidatedRuntimeDelegation,
22738
23907
  addressStorageKey,
22739
23908
  buildCanonicalDecryptRequest,
22740
23909
  buildDecryptAttenuation,