@tinycloud/node-sdk 2.7.0-beta.3 → 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
  */
@@ -19183,6 +19418,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19183
19418
  this._hooks = void 0;
19184
19419
  this._vault = void 0;
19185
19420
  this._encryption = void 0;
19421
+ this._baseVaults.clear();
19186
19422
  this._baseSecrets.clear();
19187
19423
  this._secrets.clear();
19188
19424
  this._spaceService = void 0;
@@ -19190,6 +19426,10 @@ var _TinyCloudNode = class _TinyCloudNode {
19190
19426
  this.runtimePermissionGrants = [];
19191
19427
  await this.tc.signIn(options);
19192
19428
  this.syncResolvedHostFromAuth();
19429
+ const oldGraph = this._serviceGraph;
19430
+ this._serviceGraph = this.createServiceGraphLifetime();
19431
+ oldGraph.retire();
19432
+ this.tc.retireServices();
19193
19433
  const signedInSession = this.currentTinyCloudSession();
19194
19434
  if (signedInSession) {
19195
19435
  this.sessionKeyId = signedInSession.sessionKey;
@@ -19474,7 +19714,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19474
19714
  }
19475
19715
  let operations = [];
19476
19716
  try {
19477
- const entries = this.wasmBindings.parseRecapFromSiwe(siwe);
19717
+ const entries = this.parseRecapWithCaveats(siwe);
19478
19718
  if (Array.isArray(entries)) {
19479
19719
  operations = entries.flatMap((entry) => {
19480
19720
  const service = this.invocationServiceName(entry.service);
@@ -19482,7 +19722,8 @@ var _TinyCloudNode = class _TinyCloudNode {
19482
19722
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
19483
19723
  service,
19484
19724
  path: entry.path,
19485
- action
19725
+ action,
19726
+ caveats: cloneRecapCaveats(entry.caveats)
19486
19727
  }));
19487
19728
  });
19488
19729
  }
@@ -19835,86 +20076,441 @@ var _TinyCloudNode = class _TinyCloudNode {
19835
20076
  */
19836
20077
  async restoreSession(sessionData) {
19837
20078
  await this.wasmBindings.ensureInitialized?.();
19838
- this._kv = void 0;
19839
- this._sql = void 0;
19840
- this._duckdb = void 0;
19841
- this._hooks = void 0;
19842
- this._vault = void 0;
19843
- this._encryption = void 0;
19844
- this._baseSecrets.clear();
19845
- this._secrets.clear();
19846
- this._spaceService = void 0;
19847
- this._serviceContext = void 0;
19848
- this.runtimePermissionGrants = [];
19849
- const restoredAddress = sessionData.address ? (0, import_sdk_core7.canonicalizeAddress)(sessionData.address) : void 0;
19850
- if (restoredAddress) {
19851
- 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.");
19852
20112
  }
19853
- if (sessionData.chainId) {
19854
- 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);
19855
20172
  }
19856
20173
  const resolvedHost = await this.resolveRestoredHost(
19857
20174
  sessionData.tinycloudHosts,
19858
20175
  restoredAddress,
19859
20176
  sessionData.chainId
19860
20177
  );
19861
- if (resolvedHost) {
19862
- this.config.host = resolvedHost;
19863
- }
19864
- this._serviceContext = new import_sdk_core7.ServiceContext({
19865
- invoke: this.invokeWithRuntimePermissions,
19866
- invokeAny: this.invokeAnyWithRuntimePermissions,
19867
- fetch: globalThis.fetch.bind(globalThis),
19868
- hosts: [this.config.host],
19869
- telemetry: this.config.telemetry
19870
- });
19871
- this._kv = new import_sdk_core7.KVService({});
19872
- this._kv.initialize(this._serviceContext);
19873
- this._serviceContext.registerService("kv", this._kv);
19874
- this._sql = new import_sdk_core7.SQLService({});
19875
- this._sql.initialize(this._serviceContext);
19876
- this._serviceContext.registerService("sql", this._sql);
19877
- this._duckdb = new import_sdk_core7.DuckDbService({});
19878
- this._duckdb.initialize(this._serviceContext);
19879
- this._serviceContext.registerService("duckdb", this._duckdb);
19880
- this._hooks = new import_sdk_core7.HooksService({});
19881
- this._hooks.initialize(this._serviceContext);
19882
- 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;
19883
20182
  const serviceSession = {
19884
20183
  delegationHeader: sessionData.delegationHeader,
19885
20184
  delegationCid: sessionData.delegationCid,
19886
20185
  spaceId: sessionData.spaceId,
19887
- verificationMethod: sessionData.verificationMethod,
19888
- jwk: sessionData.jwk
20186
+ verificationMethod: restoredVerificationMethod,
20187
+ jwk: stagedJwk
19889
20188
  };
19890
- this._serviceContext.setSession(serviceSession);
19891
- this._vault = this.createVaultService(sessionData.spaceId, this._kv);
19892
- this._vault.initialize(this._serviceContext);
19893
- this._serviceContext.registerService("vault", this._vault);
19894
- this.initializeV2Services(serviceSession);
19895
- if (sessionData.siwe && restoredAddress && sessionData.chainId) {
19896
- const tcSession = {
19897
- address: restoredAddress,
19898
- chainId: sessionData.chainId,
19899
- sessionKey: JSON.stringify(sessionData.jwk),
19900
- spaceId: sessionData.spaceId,
19901
- delegationCid: sessionData.delegationCid,
19902
- delegationHeader: sessionData.delegationHeader,
19903
- verificationMethod: sessionData.verificationMethod,
19904
- jwk: sessionData.jwk,
19905
- siwe: sessionData.siwe,
19906
- signature: sessionData.signature ?? ""
19907
- };
19908
- if (this.auth) {
19909
- this.auth.setRestoredTinyCloudSession(
19910
- tcSession,
19911
- 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()
19912
20424
  );
19913
- } else {
19914
- 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);
19915
20510
  }
19916
- this.registerPrimarySessionGrant(tcSession);
19917
- }
20511
+ });
20512
+ spaceService.updateConfig({ sharingService });
20513
+ return { core, graph, serviceContext, kv, sql, duckdb, hooks, vault, encryption, capabilityRegistry, keyProvider, sharingService, delegationManager, spaceService };
19918
20514
  }
19919
20515
  /**
19920
20516
  * Resolve the host a restored session should target.
@@ -20076,14 +20672,19 @@ var _TinyCloudNode = class _TinyCloudNode {
20076
20672
  if (!session) {
20077
20673
  return;
20078
20674
  }
20079
- this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
20080
- this._serviceContext = new import_sdk_core7.ServiceContext({
20081
- invoke: this.invokeWithRuntimePermissions,
20082
- invokeAny: this.invokeAnyWithRuntimePermissions,
20083
- 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,
20084
20685
  hosts: [this.config.host],
20085
20686
  telemetry: this.config.telemetry
20086
- });
20687
+ }));
20087
20688
  this._kv = new import_sdk_core7.KVService({});
20088
20689
  this._kv.initialize(this._serviceContext);
20089
20690
  this._serviceContext.registerService("kv", this._kv);
@@ -20118,12 +20719,12 @@ var _TinyCloudNode = class _TinyCloudNode {
20118
20719
  createSpaceScopedKVService(spaceId) {
20119
20720
  const kvService = new import_sdk_core7.KVService({});
20120
20721
  if (this._serviceContext) {
20121
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
20722
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20122
20723
  invoke: this._serviceContext.invoke,
20123
20724
  fetch: this._serviceContext.fetch,
20124
20725
  hosts: this._serviceContext.hosts,
20125
20726
  telemetry: this.config.telemetry
20126
- });
20727
+ }));
20127
20728
  const session = this._serviceContext.session;
20128
20729
  if (session) {
20129
20730
  spaceScopedContext.setSession({ ...session, spaceId });
@@ -20156,6 +20757,18 @@ var _TinyCloudNode = class _TinyCloudNode {
20156
20757
  }
20157
20758
  return session;
20158
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
+ }
20159
20772
  createEncryptionCrypto() {
20160
20773
  const wasm = this.wasmBindings;
20161
20774
  const columnEncrypt = (key2, plaintext) => {
@@ -20211,14 +20824,15 @@ var _TinyCloudNode = class _TinyCloudNode {
20211
20824
  }
20212
20825
  return info.nodeId;
20213
20826
  }
20214
- async signRawNetworkAuthorization(input) {
20827
+ async signRawNetworkAuthorization(input, binding) {
20828
+ binding?.graph.assertActive();
20215
20829
  if (!this.wasmBindings.invokeAny) {
20216
20830
  throw new Error("WASM binding does not support raw-resource invokeAny");
20217
20831
  }
20218
20832
  if (!this.wasmBindings.computeCid) {
20219
20833
  throw new Error("WASM binding does not support invocation CID computation");
20220
20834
  }
20221
- const session = this.requireServiceSession();
20835
+ const session = binding?.session ?? this.requireEncryptionSession();
20222
20836
  const headers = this.invokeAnyWithRuntimePermissions(
20223
20837
  session,
20224
20838
  [
@@ -20237,6 +20851,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20237
20851
  input.targetNode,
20238
20852
  session.jwk
20239
20853
  );
20854
+ binding?.graph.assertActive();
20240
20855
  return {
20241
20856
  authorization: audienceBound,
20242
20857
  invocationCid: this.wasmBindings.computeCid(
@@ -20245,25 +20860,55 @@ var _TinyCloudNode = class _TinyCloudNode {
20245
20860
  )
20246
20861
  };
20247
20862
  }
20248
- 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;
20249
20883
  const crypto2 = this.createEncryptionCrypto();
20250
20884
  const transport = {
20251
- postDecrypt: async ({ networkId, authorization, canonicalBody }) => {
20252
- const response = await fetch(
20253
- `${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`,
20254
20889
  {
20255
20890
  method: "POST",
20256
20891
  headers: {
20257
20892
  Authorization: authorization,
20258
20893
  "Content-Type": "application/json"
20259
20894
  },
20260
- body: canonicalBody
20895
+ body: canonicalBody,
20896
+ signal
20261
20897
  }
20262
20898
  );
20899
+ graph.assertActive();
20263
20900
  if (!response.ok) {
20264
- throw new Error(
20265
- `decrypt failed ${response.status}: ${await response.text()}`
20266
- );
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);
20267
20912
  }
20268
20913
  return await response.json();
20269
20914
  }
@@ -20272,12 +20917,14 @@ var _TinyCloudNode = class _TinyCloudNode {
20272
20917
  crypto: crypto2,
20273
20918
  signer: {
20274
20919
  signDecryptInvocation: async (input) => {
20920
+ graph.assertActive();
20275
20921
  const signed2 = await this.signRawNetworkAuthorization({
20276
20922
  targetNode: input.targetNode,
20277
20923
  networkId: input.networkId,
20278
20924
  action: DECRYPT_ACTION2,
20279
20925
  facts: input.facts
20280
- });
20926
+ }, { graph, session });
20927
+ graph.assertActive();
20281
20928
  return {
20282
20929
  ...signed2,
20283
20930
  canonicalBody: (0, import_sdk_core7.canonicalizeEncryptionJson)(
@@ -20288,25 +20935,35 @@ var _TinyCloudNode = class _TinyCloudNode {
20288
20935
  },
20289
20936
  transport,
20290
20937
  node: {
20291
- 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
+ }
20292
20944
  },
20293
20945
  wellKnown: {
20294
20946
  fetchWellKnown: async (principal, discoveryKey) => {
20295
- if (!this._address || !didPrincipalMatches2(principal, this.did)) {
20296
- return null;
20297
- }
20298
- if (!this.config.host) {
20947
+ graph.assertActive();
20948
+ if (!address || !didPrincipalMatches2(principal, did)) {
20299
20949
  return null;
20300
20950
  }
20301
- const publicSpaceId = (0, import_sdk_core7.makePublicSpaceId)(this._address, this._chainId);
20302
- const result = await import_sdk_core7.TinyCloud.readPublicSpace(this.config.host, publicSpaceId, discoveryKey);
20303
- 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) {
20304
20959
  return null;
20305
20960
  }
20306
- const body = result.data;
20961
+ const body = await response.json();
20962
+ graph.assertActive();
20307
20963
  return "descriptor" in body && body.descriptor ? body.descriptor : body;
20308
20964
  }
20309
- }
20965
+ },
20966
+ assertActive: () => graph.assertActive()
20310
20967
  });
20311
20968
  }
20312
20969
  getEncryptionService() {
@@ -20320,8 +20977,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20320
20977
  }
20321
20978
  return this._encryption;
20322
20979
  }
20323
- createVaultService(spaceId, kv) {
20980
+ createVaultService(spaceId, kv, encryptionService = this.getEncryptionService(), nodeContext) {
20324
20981
  const wasm = this.wasmBindings;
20982
+ const serviceGraph = nodeContext?.serviceGraph ?? this._serviceGraph;
20325
20983
  const vaultCrypto = (0, import_sdk_core7.createVaultCrypto)({
20326
20984
  vault_encrypt: wasm.vault_encrypt,
20327
20985
  vault_decrypt: wasm.vault_decrypt,
@@ -20332,12 +20990,17 @@ var _TinyCloudNode = class _TinyCloudNode {
20332
20990
  vault_sha256: wasm.vault_sha256
20333
20991
  });
20334
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;
20335
20998
  return new import_sdk_core7.DataVaultService({
20336
20999
  spaceId,
20337
21000
  crypto: vaultCrypto,
20338
21001
  encryption: {
20339
- networkId: this.getEncryptionNetworkIdForSpace(spaceId),
20340
- service: this.getEncryptionService(),
21002
+ networkId: `urn:tinycloud:encryption:${ownerDid}:${DEFAULT_ENCRYPTION_NETWORK_NAME}`,
21003
+ service: encryptionService,
20341
21004
  decryptCapabilityProof: () => ({
20342
21005
  proofs: [this.requireServiceSession().delegationCid]
20343
21006
  })
@@ -20346,6 +21009,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20346
21009
  kv,
20347
21010
  ensurePublicSpace: async () => {
20348
21011
  try {
21012
+ serviceGraph.assertActive();
20349
21013
  await self2.ensurePublicSpace();
20350
21014
  return { ok: true, data: void 0 };
20351
21015
  } catch (error) {
@@ -20353,14 +21017,15 @@ var _TinyCloudNode = class _TinyCloudNode {
20353
21017
  }
20354
21018
  },
20355
21019
  get publicKV() {
21020
+ serviceGraph.assertActive();
20356
21021
  return self2._publicKV ?? self2.tc.publicKV;
20357
21022
  },
20358
- 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),
20359
21024
  makePublicSpaceId: import_sdk_core7.TinyCloud.makePublicSpaceId,
20360
- did: this.did,
20361
- address: this._address ?? "",
20362
- chainId: this._chainId,
20363
- hosts: [this.config.host]
21025
+ did,
21026
+ address: address ?? "",
21027
+ chainId,
21028
+ hosts: [host]
20364
21029
  }
20365
21030
  });
20366
21031
  }
@@ -20369,6 +21034,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20369
21034
  * @internal
20370
21035
  */
20371
21036
  initializeV2Services(serviceSession) {
21037
+ const graph = this._serviceGraph;
20372
21038
  this._capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
20373
21039
  const tcSession = this.auth?.tinyCloudSession;
20374
21040
  if (tcSession && this._address) {
@@ -20413,21 +21079,23 @@ var _TinyCloudNode = class _TinyCloudNode {
20413
21079
  hosts: [this.config.host],
20414
21080
  accountSpaceId: this.accountSpaceId,
20415
21081
  session: serviceSession,
20416
- invoke: this.invokeWithRuntimePermissions,
20417
- invokeAny: this.invokeAnyWithRuntimePermissions,
20418
- fetch: globalThis.fetch.bind(globalThis)
21082
+ invoke: graph.invoke,
21083
+ invokeAny: graph.invokeAny,
21084
+ fetch: graph.fetch
20419
21085
  });
20420
21086
  this._spaceService = new import_sdk_core7.SpaceService({
20421
21087
  hosts: [this.config.host],
20422
21088
  session: serviceSession,
20423
- invoke: this.wasmBindings.invoke,
20424
- fetch: globalThis.fetch.bind(globalThis),
21089
+ invoke: graph.invoke,
21090
+ fetch: graph.fetch,
20425
21091
  capabilityRegistry: this._capabilityRegistry,
20426
21092
  userDid: this.did,
20427
21093
  createKVService: (spaceId) => {
21094
+ graph.assertActive();
20428
21095
  return this.createSpaceScopedKVService(spaceId);
20429
21096
  },
20430
21097
  createVaultService: (spaceId) => {
21098
+ graph.assertActive();
20431
21099
  const kvService = this.createSpaceScopedKVService(spaceId);
20432
21100
  const vaultService = this.createVaultService(spaceId, kvService);
20433
21101
  if (this._serviceContext) {
@@ -20436,11 +21104,13 @@ var _TinyCloudNode = class _TinyCloudNode {
20436
21104
  return vaultService;
20437
21105
  },
20438
21106
  createSecretsService: (spaceId) => {
21107
+ graph.assertActive();
20439
21108
  return this.secretsForSpace(spaceId);
20440
21109
  },
20441
21110
  // Enable space.delegations.create() via SIWE-based delegation
20442
21111
  createDelegation: async (params) => {
20443
21112
  try {
21113
+ graph.assertActive();
20444
21114
  const portableDelegation = await this.createDelegation({
20445
21115
  delegateDID: params.delegateDID,
20446
21116
  path: params.path,
@@ -20474,18 +21144,50 @@ var _TinyCloudNode = class _TinyCloudNode {
20474
21144
  }
20475
21145
  },
20476
21146
  onSpaceRegistered: async (space) => {
21147
+ graph.assertActive();
20477
21148
  await this.account.spaces.register(space);
20478
21149
  }
20479
21150
  });
20480
- this._sharingService.updateConfig({
21151
+ this._sharingService = new import_sdk_core7.SharingService({
21152
+ hosts: [this.config.host],
20481
21153
  session: serviceSession,
21154
+ invoke: graph.invoke,
21155
+ fetch: graph.fetch,
21156
+ assertActive: () => graph.assertActive(),
21157
+ keyProvider: this._keyProvider,
21158
+ registry: this._capabilityRegistry,
20482
21159
  delegationManager: this._delegationManager,
20483
21160
  sessionExpiry: this.getSessionExpiry(),
20484
- // WASM-based delegation creation (preferred - no server roundtrip)
20485
- createDelegationWasm: (params) => this.createDelegationWrapper(params),
20486
- // Root delegation for long-lived share links (bypasses session expiry)
20487
- // In node-sdk we have direct signer access, so no popup needed
20488
- 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
20489
21191
  });
20490
21192
  this._spaceService.updateConfig({
20491
21193
  sharingService: this._sharingService
@@ -20552,7 +21254,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20552
21254
  * with expiry longer than the current session.
20553
21255
  * @internal
20554
21256
  */
20555
- async createOwnerDelegation(params) {
21257
+ async createOwnerDelegation(params, assertActive) {
21258
+ const assertOwnerGraphActive = assertActive ?? this._serviceGraph.assertActive.bind(this._serviceGraph);
21259
+ assertOwnerGraphActive();
20556
21260
  if (!params.delegateDid.startsWith("did:key:") || params.actions.length === 0 || params.path.length === 0) {
20557
21261
  throw new Error("Owner delegation requires an external did:key audience and bounded capabilities");
20558
21262
  }
@@ -20577,8 +21281,10 @@ var _TinyCloudNode = class _TinyCloudNode {
20577
21281
  delegateUri: params.delegateDid
20578
21282
  });
20579
21283
  const signature2 = await this.signer.signMessage(prepared.siwe);
21284
+ assertOwnerGraphActive();
20580
21285
  const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature: signature2 });
20581
21286
  const activation = await (0, import_sdk_core7.activateSessionWithHost)(host, delegationSession.delegationHeader);
21287
+ assertOwnerGraphActive();
20582
21288
  if (!activation.success) {
20583
21289
  throw new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim());
20584
21290
  }
@@ -20606,7 +21312,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20606
21312
  }
20607
21313
  };
20608
21314
  }
20609
- async createRootDelegationForSharing(params) {
21315
+ async createRootDelegationForSharing(params, assertActive) {
20610
21316
  try {
20611
21317
  return (await this.createOwnerDelegation({
20612
21318
  delegateDid: params.shareKeyDID,
@@ -20614,8 +21320,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20614
21320
  path: params.path,
20615
21321
  actions: params.actions,
20616
21322
  expiresAt: params.requestedExpiry
20617
- })).delegation;
21323
+ }, assertActive)).delegation;
20618
21324
  } catch {
21325
+ assertActive?.();
20619
21326
  return void 0;
20620
21327
  }
20621
21328
  }
@@ -20687,13 +21394,13 @@ var _TinyCloudNode = class _TinyCloudNode {
20687
21394
  throw new Error("Not signed in. Call signIn() first.");
20688
21395
  }
20689
21396
  const sql = new import_sdk_core7.SQLService({});
20690
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
21397
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20691
21398
  invoke: this._serviceContext.invoke,
20692
21399
  invokeAny: this._serviceContext.invokeAny,
20693
21400
  fetch: this._serviceContext.fetch,
20694
21401
  hosts: this._serviceContext.hosts,
20695
21402
  telemetry: this.config.telemetry
20696
- });
21403
+ }));
20697
21404
  spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
20698
21405
  sql.initialize(spaceScopedContext);
20699
21406
  return sql;
@@ -20717,12 +21424,12 @@ var _TinyCloudNode = class _TinyCloudNode {
20717
21424
  throw new Error("Not signed in. Call signIn() first.");
20718
21425
  }
20719
21426
  const kv = new import_sdk_core7.KVService({});
20720
- const spaceScopedContext = new import_sdk_core7.ServiceContext({
21427
+ const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
20721
21428
  invoke: this._serviceContext.invoke,
20722
21429
  invokeAny: this._serviceContext.invokeAny,
20723
21430
  fetch: this._serviceContext.fetch,
20724
21431
  hosts: this._serviceContext.hosts
20725
- });
21432
+ }));
20726
21433
  spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
20727
21434
  kv.initialize(spaceScopedContext);
20728
21435
  return kv;
@@ -20758,19 +21465,11 @@ var _TinyCloudNode = class _TinyCloudNode {
20758
21465
  }
20759
21466
  async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
20760
21467
  const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
20761
- const response = await fetch(
20762
- `${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}`
21468
+ return this.fetchEncryptionNetworkAt(
21469
+ this.config.host,
21470
+ networkId,
21471
+ globalThis.fetch.bind(globalThis)
20763
21472
  );
20764
- if (response.status === 404) {
20765
- return null;
20766
- }
20767
- if (!response.ok) {
20768
- throw new Error(
20769
- `Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
20770
- );
20771
- }
20772
- const body = await response.json();
20773
- return "descriptor" in body && body.descriptor ? body.descriptor : body;
20774
21473
  }
20775
21474
  async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
20776
21475
  const targetNode = await this.fetchNodeId();
@@ -20864,6 +21563,38 @@ var _TinyCloudNode = class _TinyCloudNode {
20864
21563
  }
20865
21564
  return secrets;
20866
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
+ }
20867
21598
  getBaseSecrets(spaceId) {
20868
21599
  if (!this._spaceService) {
20869
21600
  throw new Error("Not signed in. Call signIn() first.");
@@ -20871,16 +21602,29 @@ var _TinyCloudNode = class _TinyCloudNode {
20871
21602
  const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
20872
21603
  let secrets = this._baseSecrets.get(resolvedSpace);
20873
21604
  if (!secrets) {
20874
- const kvService = this.createSpaceScopedKVService(resolvedSpace);
20875
- const vaultService = this.createVaultService(resolvedSpace, kvService);
20876
- if (this._serviceContext) {
20877
- vaultService.initialize(this._serviceContext);
20878
- }
20879
- secrets = new import_sdk_core7.SecretsService(() => vaultService);
21605
+ secrets = new import_sdk_core7.SecretsService(() => this.getBaseVault(resolvedSpace));
20880
21606
  this._baseSecrets.set(resolvedSpace, secrets);
20881
21607
  }
20882
21608
  return secrets;
20883
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
+ }
20884
21628
  /**
20885
21629
  * Hooks write stream subscription API.
20886
21630
  */
@@ -20985,6 +21729,63 @@ var _TinyCloudNode = class _TinyCloudNode {
20985
21729
  (grant) => grant.delegation
20986
21730
  );
20987
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
+ }
20988
21789
  /**
20989
21790
  * Install a portable runtime permission delegation into this SDK instance so
20990
21791
  * matching service calls and downstream `delegateTo()` calls can use it.
@@ -21053,6 +21854,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21053
21854
  "grantRuntimePermissions requires wallet mode with a signer or privateKey."
21054
21855
  );
21055
21856
  }
21857
+ this.assertDelegationCaveatsPreservable(expanded);
21056
21858
  const rawEntries = expanded.filter(
21057
21859
  (entry) => this.isEncryptionPermissionEntry(entry)
21058
21860
  );
@@ -21314,12 +22116,12 @@ var _TinyCloudNode = class _TinyCloudNode {
21314
22116
  }
21315
22117
  if (this._serviceContext) {
21316
22118
  const publicKV = new import_sdk_core7.KVService({ prefix: "" });
21317
- const publicContext = new import_sdk_core7.ServiceContext({
21318
- invoke: this.invokeWithRuntimePermissions,
21319
- 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,
21320
22122
  hosts: this._serviceContext.hosts,
21321
22123
  telemetry: this.config.telemetry
21322
- });
22124
+ }));
21323
22125
  publicContext.setSession({
21324
22126
  delegationHeader: delegationSession.delegationHeader,
21325
22127
  delegationCid: delegationSession.delegationCid,
@@ -21386,13 +22188,14 @@ var _TinyCloudNode = class _TinyCloudNode {
21386
22188
  async getDelegationStatus(cid) {
21387
22189
  return this.delegationManager.status(cid);
21388
22190
  }
21389
- /** Compute the canonical CID of a compact delegation authorization. */
22191
+ /** Compute the canonical CID of a compact UCAN or DAG-CBOR delegation authorization. */
21390
22192
  computeDelegationCid(authorization) {
21391
22193
  if (!authorization || !this.wasmBindings.computeCid) {
21392
22194
  throw new Error("Delegation CID computation is unavailable");
21393
22195
  }
22196
+ const compact = authorization.replace(/^Bearer /i, "");
21394
22197
  return this.wasmBindings.computeCid(
21395
- new TextEncoder().encode(authorization),
22198
+ compact.includes(".") ? new TextEncoder().encode(compact) : decodeAuthorizationBytes(authorization),
21396
22199
  0x55n
21397
22200
  );
21398
22201
  }
@@ -21484,6 +22287,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21484
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."
21485
22288
  );
21486
22289
  }
22290
+ this.assertDelegationCaveatsPreservable(expandedEntries);
21487
22291
  const delegation2 = await this.createDelegationLegacyWalletPath(
21488
22292
  did,
21489
22293
  expandedEntries[0],
@@ -21492,13 +22296,14 @@ var _TinyCloudNode = class _TinyCloudNode {
21492
22296
  return { delegation: delegation2, prompted: true };
21493
22297
  }
21494
22298
  const granted = (0, import_sdk_core7.parseRecapCapabilities)(
21495
- (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
22299
+ (siwe) => this.parseRecapWithCaveats(siwe),
21496
22300
  session.siwe
21497
22301
  );
21498
22302
  const { subset, missing } = (0, import_sdk_core7.isCapabilitySubset)(expandedEntries, granted);
21499
22303
  if (!subset) {
22304
+ const runtimeOperations = this.permissionEntriesToOperations(expandedEntries, session);
21500
22305
  const runtimeGrant = this.findGrantForOperations(
21501
- this.permissionEntriesToOperations(expandedEntries, session),
22306
+ runtimeOperations,
21502
22307
  { excludePrimary: true }
21503
22308
  );
21504
22309
  if (runtimeGrant) {
@@ -21511,7 +22316,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21511
22316
  did,
21512
22317
  expandedEntries,
21513
22318
  runtimeExpiration,
21514
- runtimeGrant
22319
+ runtimeGrant,
22320
+ runtimeOperations
21515
22321
  );
21516
22322
  return { delegation: delegation2, prompted: false };
21517
22323
  }
@@ -21581,6 +22387,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21581
22387
  "createDelegationViaWasmPath requires a non-empty entries array"
21582
22388
  );
21583
22389
  }
22390
+ this.assertDelegationCaveatsPreservable(entries);
21584
22391
  const resolvedSpaces = /* @__PURE__ */ new Set();
21585
22392
  for (const entry of entries) {
21586
22393
  if (this.isEncryptionPermissionEntry(entry)) {
@@ -21661,7 +22468,9 @@ var _TinyCloudNode = class _TinyCloudNode {
21661
22468
  host: this.config.host
21662
22469
  };
21663
22470
  }
21664
- async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
22471
+ async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations) {
22472
+ this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
22473
+ this.assertDelegationCaveatsPreservable(entries);
21665
22474
  const result = this.createDelegationWrapper({
21666
22475
  session: grant.session,
21667
22476
  delegateDID: did,
@@ -21715,6 +22524,74 @@ var _TinyCloudNode = class _TinyCloudNode {
21715
22524
  expandPermissionEntries(permissions) {
21716
22525
  return (0, import_sdk_core7.expandPermissionEntries)(permissions);
21717
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
+ }
21718
22595
  shortServiceName(service) {
21719
22596
  const short = import_sdk_core7.SERVICE_LONG_TO_SHORT[service];
21720
22597
  if (short === void 0) {
@@ -21769,14 +22646,15 @@ var _TinyCloudNode = class _TinyCloudNode {
21769
22646
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
21770
22647
  service,
21771
22648
  path: entry.path,
21772
- action
22649
+ action,
22650
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21773
22651
  }));
21774
22652
  });
21775
22653
  }
21776
22654
  sessionCoversPermissionEntries(session, entries) {
21777
22655
  try {
21778
22656
  const granted = (0, import_sdk_core7.parseRecapCapabilities)(
21779
- (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
22657
+ (siwe) => this.parseRecapWithCaveats(siwe),
21780
22658
  session.siwe
21781
22659
  );
21782
22660
  return (0, import_sdk_core7.isCapabilitySubset)(entries, granted).subset;
@@ -21792,7 +22670,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21792
22670
  ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
21793
22671
  service,
21794
22672
  path: entry.path,
21795
- action
22673
+ action,
22674
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21796
22675
  }));
21797
22676
  });
21798
22677
  }
@@ -21868,7 +22747,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21868
22747
  service: this.shortServiceName(entry.service),
21869
22748
  space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
21870
22749
  path: entry.path,
21871
- actions: [...entry.actions]
22750
+ actions: [...entry.actions],
22751
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
21872
22752
  }));
21873
22753
  }
21874
22754
  operationsFromDelegation(delegation) {
@@ -21879,7 +22759,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21879
22759
  ...this.isEncryptionNetworkOperation(service, resource.path) ? { resource: resource.path } : { spaceId: resource.space },
21880
22760
  service,
21881
22761
  path: resource.path,
21882
- action
22762
+ action,
22763
+ caveats: cloneRecapCaveats(resource.caveats)
21883
22764
  }));
21884
22765
  });
21885
22766
  }
@@ -21895,7 +22776,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21895
22776
  service,
21896
22777
  space: delegation.spaceId,
21897
22778
  path: delegation.path,
21898
- actions
22779
+ actions,
22780
+ ...delegation.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(delegation.caveats) }
21899
22781
  }));
21900
22782
  }
21901
22783
  /**
@@ -21996,6 +22878,9 @@ var _TinyCloudNode = class _TinyCloudNode {
21996
22878
  if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
21997
22879
  return false;
21998
22880
  }
22881
+ if (requested.caveats !== void 0 && !(0, import_sdk_core7.recapCaveatsEqual)(granted.caveats, requested.caveats)) {
22882
+ return false;
22883
+ }
21999
22884
  if (granted.resource !== void 0 || requested.resource !== void 0) {
22000
22885
  return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
22001
22886
  }
@@ -22030,6 +22915,10 @@ var _TinyCloudNode = class _TinyCloudNode {
22030
22915
  invocationServiceName(service) {
22031
22916
  return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
22032
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
+ }
22033
22922
  isEncryptionNetworkOperation(service, path) {
22034
22923
  return service === "encryption" && path.startsWith("urn:tinycloud:encryption:");
22035
22924
  }
@@ -22040,7 +22929,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22040
22929
  resource: entry.resource,
22041
22930
  service,
22042
22931
  path: entry.path,
22043
- action: entry.action
22932
+ action: entry.action,
22933
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22044
22934
  };
22045
22935
  }
22046
22936
  if (this.isEncryptionNetworkOperation(service, entry.path)) {
@@ -22048,7 +22938,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22048
22938
  resource: entry.path,
22049
22939
  service,
22050
22940
  path: entry.path,
22051
- action: entry.action
22941
+ action: entry.action,
22942
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22052
22943
  };
22053
22944
  }
22054
22945
  if (typeof entry.spaceId === "string") {
@@ -22056,7 +22947,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22056
22947
  spaceId: entry.spaceId,
22057
22948
  service,
22058
22949
  path: entry.path,
22059
- action: entry.action
22950
+ action: entry.action,
22951
+ ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
22060
22952
  };
22061
22953
  }
22062
22954
  return void 0;
@@ -22396,6 +23288,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22396
23288
  * @returns A portable delegation for the sub-delegate
22397
23289
  */
22398
23290
  async createSubDelegation(parentDelegation, params) {
23291
+ this.assertPortableDelegationCaveatsPreservable(parentDelegation);
22399
23292
  if (!this.signer) {
22400
23293
  throw new Error("Cannot createSubDelegation() in session-only mode. Requires wallet mode.");
22401
23294
  }
@@ -22494,8 +23387,8 @@ TinyCloudNode.registerNodeDefaults({
22494
23387
  });
22495
23388
 
22496
23389
  // src/index.ts
22497
- var import_sdk_core9 = require("@tinycloud/sdk-core");
22498
23390
  var import_sdk_core10 = require("@tinycloud/sdk-core");
23391
+ var import_sdk_core11 = require("@tinycloud/sdk-core");
22499
23392
 
22500
23393
  // src/storage/FileSessionStorage.ts
22501
23394
  var import_sdk_core8 = require("@tinycloud/sdk-core");
@@ -22618,9 +23511,279 @@ var FileSessionStorage = class {
22618
23511
  };
22619
23512
 
22620
23513
  // src/index.ts
22621
- var import_sdk_core11 = require("@tinycloud/sdk-core");
23514
+ var import_sdk_core12 = require("@tinycloud/sdk-core");
22622
23515
 
22623
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
+ }
22624
23787
  async function grantAuthRequest(authority, request, options) {
22625
23788
  if (request.kind !== "tinycloud.auth.request") {
22626
23789
  throw new Error(
@@ -22663,7 +23826,6 @@ function deserializeDelegation(data) {
22663
23826
  }
22664
23827
 
22665
23828
  // src/index.ts
22666
- var import_sdk_core12 = require("@tinycloud/sdk-core");
22667
23829
  var import_sdk_core13 = require("@tinycloud/sdk-core");
22668
23830
  var import_sdk_core14 = require("@tinycloud/sdk-core");
22669
23831
  var import_sdk_core15 = require("@tinycloud/sdk-core");
@@ -22674,6 +23836,7 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
22674
23836
  var import_sdk_core20 = require("@tinycloud/sdk-core");
22675
23837
  var import_sdk_core21 = require("@tinycloud/sdk-core");
22676
23838
  var import_sdk_core22 = require("@tinycloud/sdk-core");
23839
+ var import_sdk_core23 = require("@tinycloud/sdk-core");
22677
23840
  // Annotate the CommonJS export names for ESM import in node:
22678
23841
  0 && (module.exports = {
22679
23842
  ACCOUNT_REGISTRY_PATH,
@@ -22682,6 +23845,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22682
23845
  AutoApproveSpaceCreationHandler,
22683
23846
  CapabilityKeyRegistry,
22684
23847
  CapabilityKeyRegistryErrorCodes,
23848
+ CaveatedDelegationUnsupportedError,
22685
23849
  DECRYPT_ACTION,
22686
23850
  DECRYPT_FACT_TYPE,
22687
23851
  DECRYPT_RESULT_TYPE,
@@ -22692,6 +23856,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22692
23856
  DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
22693
23857
  DataVaultService,
22694
23858
  DatabaseHandle,
23859
+ DecryptTransportResponseError,
22695
23860
  DelegatedAccess,
22696
23861
  DelegationErrorCodes,
22697
23862
  DelegationManager,
@@ -22732,11 +23897,13 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
22732
23897
  TinyCloudDebugLogger,
22733
23898
  TinyCloudNode,
22734
23899
  UnsupportedFeatureError,
23900
+ UnsupportedSessionRestoreError,
22735
23901
  VAULT_PERMISSION_SERVICE,
22736
23902
  VaultHeaders,
22737
23903
  VaultPublicSpaceKVActions,
22738
23904
  VersionCheckError,
22739
23905
  WasmKeyProvider,
23906
+ activateValidatedRuntimeDelegation,
22740
23907
  addressStorageKey,
22741
23908
  buildCanonicalDecryptRequest,
22742
23909
  buildDecryptAttenuation,