@tinycloud/node-sdk 3.1.0-beta.8 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.d.cts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, AccountApplication, AccountApplicationListOptions, AccountApplicationRegisterOptions, AccountDelegation, AccountDelegationListOptions, AccountDelegationRevokeOptions, AccountIndexEnsureResult, AccountIndexRebuildResult, AccountIndexStatus, AccountIndexedReadOptions, AccountService, AccountServiceConfig, AccountSpace, AccountSpaceListOptions, AccountStatus, AutoApproveSpaceCreationHandler, AutoRejectStrategy, AutoSignStrategy, BatchOptions, BatchResponse, CallbackStrategy, CanonicalAddress, CanonicalParsedNetworkId, CapabilityEntry, CapabilityKeyRegistry, CapabilityKeyRegistryErrorCode, CapabilityKeyRegistryErrorCodes, CaveatedDelegationUnsupportedError, ClientSession, ColumnInfo, ComposeManifestOptions, ComposedManifestRequest, CreateDelegationParams, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DataVaultConfig, DataVaultService, DatabaseHandle, DelegateReceivedShareParams, DelegatedShareAccess, Delegation, DelegationChain, DelegationChainV2, DelegationDirection, DelegationError, DelegationErrorCode, DelegationErrorCodes, DelegationFilters, DelegationManager, DelegationManagerConfig, DelegationRecord, DelegationResult, DidCacheKeyOptions, DidEqualsOptions, DuckDbAction, DuckDbActionType, DuckDbBatchOptions, DuckDbBatchResponse, DuckDbDatabaseHandle, DuckDbExecuteOptions, DuckDbExecuteResponse, DuckDbOptions, DuckDbQueryOptions, DuckDbQueryResponse, DuckDbService, DuckDbServiceConfig, DuckDbStatement, DuckDbValue, EncodedShareData, ExecuteOptions, ExecuteResponse, Extension, FetchFunction, GenerateShareParams, ICapabilityKeyRegistry, IDataVaultService, IDatabaseHandle, IDuckDbDatabaseHandle, IDuckDbService, IENSResolver, IKVService, INotificationHandler, IPrefixedKVService, ISQLService, ISecretsService, ISessionManager, ISessionStorage, ISharingService, ISigner, ISpace, ISpaceCreationHandler, ISpaceScopedDelegations, ISpaceScopedSharing, ISpaceService, IUserAuthorization, IWasmBindings, IdentityParseError, IngestOptions, InvokeFunction, JWK, KVBatchReadResponse, KVCreateSignedReadUrlOptions, KVResponse, KVService, KVServiceConfig, KVSignedReadUrlResponse, KeyInfo, KeyProvider, KeyType, Manifest, ManifestDefaults, ManifestRegistryRecord, ManifestSecretActions, ManifestValidationError, OpenKeyCallbackStrategy, OpenKeySigningRequestBody, OpenKeySigningResponseBody, OpenKeySigningStrategyOptions, ParsedSecretCatalogKey, PermissionEntry, PermissionNotInManifestError, PersistedSessionData, PkhDidParts, PrefixedKVService, ProtocolMismatchError, QueryOptions, QueryResponse, ReceiveOptions, RegisterBatchSuccess, RegisterPolicyV3Input, RegisterPolicyV3Receipt, ResolvedCapabilities, ResolvedDelegate, ResolvedSecretPath, ResourceCapability, SECRET_NAME_RE, SQLAction, SQLActionType, SQLService, SQLServiceConfig, SchemaInfo, SecretCatalogEntry, SecretPayload, SecretScopeOptions, SecretsError, SecretsService, ServiceContext, ServiceContextConfig, ServiceSession, SessionExpiredError, ShareAccess, ShareLink, ShareLinkData, ShareSchema, SharingService, SharingServiceConfig, SignCallback, SignInOptions, SignRequest, SignResponse, SilentNotificationHandler, Space, SpaceAbilitiesMap, SpaceConfig, SpaceCreationContext, SpaceErrorCode, SpaceErrorCodes, SpaceInfo, SpaceOwnership, SpaceService, SpaceServiceConfig, SqlStatement, SqlValue, StoredDelegationChain, TableInfo, TelemetryConfig, TelemetryEventHandler, TinyCloud, TinyCloudConfig, TinyCloudDebugEnableOptions, TinyCloudDebugEvent, TinyCloudDebugLevel, TinyCloudDebugLogger, TinyCloudDebugTimer, TinyCloudSession, UnsupportedFeatureError, VAULT_PERMISSION_SERVICE, VaultCrypto, VaultEntry, VaultError, VaultGetOptions, VaultGrantOptions, VaultHeaders, VaultListOptions, VaultNetworkReadResult, VaultPublicSpaceKVActions, VaultPutOptions, VersionCheckError, ViewInfo, WasmVaultFunctions, addressStorageKey, buildSpaceUri, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeSecretScope, checkNodeInfo, clearTinyCloudDebugLogs, composeManifestRequest, createCapabilityKeyRegistry, createOpenKeyCallbackSigningStrategy, createSharingService, createSpaceService, createVaultCrypto, defaultSpaceCreationHandler, didCacheKey, didEquals, disableTinyCloudDebug, enableTinyCloudDebug, expandActionShortNames, expandPermissionEntries, expandPermissionEntry, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isCapabilitySubset, isEvmAddress, loadManifest, makePkhSpaceId, makePublicSpaceId, parseCanonicalNetworkId, parseExpiry, parsePkhDid, parseSecretCatalogKey, parseSpaceUri, pkhDid, principalDid, principalDidEquals, resolveManifest, resolveSecretListPrefix, resolveSecretPath, resourceCapabilitiesToSpaceAbilitiesMap, tinyCloudDebugLogger, validateManifest } from '@tinycloud/sdk-core';
2
- export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, F as FileSessionStorage, I as InvalidRestoredSessionError, M as MemorySessionStorage, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, k as NodeUserAuthorizationConfig, O as OwnerDelegationReceipt, P as PortableDelegation, p as RuntimePermissionGrantOptions, S as SecretPermissionHint, q as SecretReadInput, r as SecretReadResult, t as SignStrategy, T as TinyCloudNode, u as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, v as UnifiedOwnerRootReceipt, w as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, W as WasmKeyProvider, y as WasmKeyProviderConfig, z as activateCompactRuntimeDelegation, H as createWasmKeyProvider, J as defaultSignStrategy, K as deserializeDelegation, Q as serializeDelegation } from './core-CC7uDKZP.cjs';
2
+ export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, F as FileSessionStorage, I as InvalidRestoredSessionError, M as MemorySessionStorage, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, k as NodeUserAuthorizationConfig, O as OwnerDelegationReceipt, P as PortableDelegation, p as RuntimePermissionGrantOptions, S as SecretPermissionHint, q as SecretReadInput, r as SecretReadResult, t as SignStrategy, T as TinyCloudNode, u as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, v as UnifiedOwnerRootReceipt, w as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, W as WasmKeyProvider, y as WasmKeyProviderConfig, z as activateCompactRuntimeDelegation, H as createWasmKeyProvider, J as defaultSignStrategy, K as deserializeDelegation, Q as serializeDelegation } from './core-AEx5vAa8.cjs';
3
3
  import 'events';
4
4
  import '@tinycloud/sdk-services';
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, AccountApplication, AccountApplicationListOptions, AccountApplicationRegisterOptions, AccountDelegation, AccountDelegationListOptions, AccountDelegationRevokeOptions, AccountIndexEnsureResult, AccountIndexRebuildResult, AccountIndexStatus, AccountIndexedReadOptions, AccountService, AccountServiceConfig, AccountSpace, AccountSpaceListOptions, AccountStatus, AutoApproveSpaceCreationHandler, AutoRejectStrategy, AutoSignStrategy, BatchOptions, BatchResponse, CallbackStrategy, CanonicalAddress, CanonicalParsedNetworkId, CapabilityEntry, CapabilityKeyRegistry, CapabilityKeyRegistryErrorCode, CapabilityKeyRegistryErrorCodes, CaveatedDelegationUnsupportedError, ClientSession, ColumnInfo, ComposeManifestOptions, ComposedManifestRequest, CreateDelegationParams, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DataVaultConfig, DataVaultService, DatabaseHandle, DelegateReceivedShareParams, DelegatedShareAccess, Delegation, DelegationChain, DelegationChainV2, DelegationDirection, DelegationError, DelegationErrorCode, DelegationErrorCodes, DelegationFilters, DelegationManager, DelegationManagerConfig, DelegationRecord, DelegationResult, DidCacheKeyOptions, DidEqualsOptions, DuckDbAction, DuckDbActionType, DuckDbBatchOptions, DuckDbBatchResponse, DuckDbDatabaseHandle, DuckDbExecuteOptions, DuckDbExecuteResponse, DuckDbOptions, DuckDbQueryOptions, DuckDbQueryResponse, DuckDbService, DuckDbServiceConfig, DuckDbStatement, DuckDbValue, EncodedShareData, ExecuteOptions, ExecuteResponse, Extension, FetchFunction, GenerateShareParams, ICapabilityKeyRegistry, IDataVaultService, IDatabaseHandle, IDuckDbDatabaseHandle, IDuckDbService, IENSResolver, IKVService, INotificationHandler, IPrefixedKVService, ISQLService, ISecretsService, ISessionManager, ISessionStorage, ISharingService, ISigner, ISpace, ISpaceCreationHandler, ISpaceScopedDelegations, ISpaceScopedSharing, ISpaceService, IUserAuthorization, IWasmBindings, IdentityParseError, IngestOptions, InvokeFunction, JWK, KVBatchReadResponse, KVCreateSignedReadUrlOptions, KVResponse, KVService, KVServiceConfig, KVSignedReadUrlResponse, KeyInfo, KeyProvider, KeyType, Manifest, ManifestDefaults, ManifestRegistryRecord, ManifestSecretActions, ManifestValidationError, OpenKeyCallbackStrategy, OpenKeySigningRequestBody, OpenKeySigningResponseBody, OpenKeySigningStrategyOptions, ParsedSecretCatalogKey, PermissionEntry, PermissionNotInManifestError, PersistedSessionData, PkhDidParts, PrefixedKVService, ProtocolMismatchError, QueryOptions, QueryResponse, ReceiveOptions, RegisterBatchSuccess, RegisterPolicyV3Input, RegisterPolicyV3Receipt, ResolvedCapabilities, ResolvedDelegate, ResolvedSecretPath, ResourceCapability, SECRET_NAME_RE, SQLAction, SQLActionType, SQLService, SQLServiceConfig, SchemaInfo, SecretCatalogEntry, SecretPayload, SecretScopeOptions, SecretsError, SecretsService, ServiceContext, ServiceContextConfig, ServiceSession, SessionExpiredError, ShareAccess, ShareLink, ShareLinkData, ShareSchema, SharingService, SharingServiceConfig, SignCallback, SignInOptions, SignRequest, SignResponse, SilentNotificationHandler, Space, SpaceAbilitiesMap, SpaceConfig, SpaceCreationContext, SpaceErrorCode, SpaceErrorCodes, SpaceInfo, SpaceOwnership, SpaceService, SpaceServiceConfig, SqlStatement, SqlValue, StoredDelegationChain, TableInfo, TelemetryConfig, TelemetryEventHandler, TinyCloud, TinyCloudConfig, TinyCloudDebugEnableOptions, TinyCloudDebugEvent, TinyCloudDebugLevel, TinyCloudDebugLogger, TinyCloudDebugTimer, TinyCloudSession, UnsupportedFeatureError, VAULT_PERMISSION_SERVICE, VaultCrypto, VaultEntry, VaultError, VaultGetOptions, VaultGrantOptions, VaultHeaders, VaultListOptions, VaultNetworkReadResult, VaultPublicSpaceKVActions, VaultPutOptions, VersionCheckError, ViewInfo, WasmVaultFunctions, addressStorageKey, buildSpaceUri, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeSecretScope, checkNodeInfo, clearTinyCloudDebugLogs, composeManifestRequest, createCapabilityKeyRegistry, createOpenKeyCallbackSigningStrategy, createSharingService, createSpaceService, createVaultCrypto, defaultSpaceCreationHandler, didCacheKey, didEquals, disableTinyCloudDebug, enableTinyCloudDebug, expandActionShortNames, expandPermissionEntries, expandPermissionEntry, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isCapabilitySubset, isEvmAddress, loadManifest, makePkhSpaceId, makePublicSpaceId, parseCanonicalNetworkId, parseExpiry, parsePkhDid, parseSecretCatalogKey, parseSpaceUri, pkhDid, principalDid, principalDidEquals, resolveManifest, resolveSecretListPrefix, resolveSecretPath, resourceCapabilitiesToSpaceAbilitiesMap, tinyCloudDebugLogger, validateManifest } from '@tinycloud/sdk-core';
2
- export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, F as FileSessionStorage, I as InvalidRestoredSessionError, M as MemorySessionStorage, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, k as NodeUserAuthorizationConfig, O as OwnerDelegationReceipt, P as PortableDelegation, p as RuntimePermissionGrantOptions, S as SecretPermissionHint, q as SecretReadInput, r as SecretReadResult, t as SignStrategy, T as TinyCloudNode, u as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, v as UnifiedOwnerRootReceipt, w as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, W as WasmKeyProvider, y as WasmKeyProviderConfig, z as activateCompactRuntimeDelegation, H as createWasmKeyProvider, J as defaultSignStrategy, K as deserializeDelegation, Q as serializeDelegation } from './core-CC7uDKZP.js';
2
+ export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, F as FileSessionStorage, I as InvalidRestoredSessionError, M as MemorySessionStorage, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, k as NodeUserAuthorizationConfig, O as OwnerDelegationReceipt, P as PortableDelegation, p as RuntimePermissionGrantOptions, S as SecretPermissionHint, q as SecretReadInput, r as SecretReadResult, t as SignStrategy, T as TinyCloudNode, u as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, v as UnifiedOwnerRootReceipt, w as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, W as WasmKeyProvider, y as WasmKeyProviderConfig, z as activateCompactRuntimeDelegation, H as createWasmKeyProvider, J as defaultSignStrategy, K as deserializeDelegation, Q as serializeDelegation } from './core-AEx5vAa8.js';
3
3
  import 'events';
4
4
  import '@tinycloud/sdk-services';
package/dist/core.js CHANGED
@@ -1717,6 +1717,7 @@ import {
1717
1717
  recapCaveatsEqual,
1718
1718
  expandPermissionEntries as expandPermissionEntriesCore,
1719
1719
  isCapabilitySubset,
1720
+ isExplicitOnlyAction,
1720
1721
  parseRecapCapabilities,
1721
1722
  SERVICE_LONG_TO_SHORT,
1722
1723
  SERVICE_SHORT_TO_LONG,
@@ -2707,15 +2708,21 @@ var _TinyCloudNode = class _TinyCloudNode {
2707
2708
  if (!this.wasmBindings.invokeAny) {
2708
2709
  throw new Error("WASM binding does not support invokeAny");
2709
2710
  }
2710
- const operations = entries.flatMap((entry) => {
2711
+ const routedEntries = entries;
2712
+ const operations = routedEntries.flatMap((entry) => {
2711
2713
  const operation = this.operationFromInvokeAnyEntry(entry);
2712
2714
  return operation ? [operation] : [];
2713
2715
  });
2714
- const grant = this.findGrantForOperations(operations);
2715
- const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
2716
- const caveatPreservingEntries = grant ? entries.map((entry) => {
2716
+ const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
2717
+ const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
2718
+ if (authorityCid !== void 0 && !explicitGrant) {
2719
+ throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
2720
+ }
2721
+ const grant = explicitGrant ?? this.findGrantForOperations(operations);
2722
+ const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
2723
+ const caveatPreservingEntries = routedEntries.map(({ revokeAuthorityCid: _cid, ...entry }) => {
2717
2724
  const requested = this.operationFromInvokeAnyEntry(entry);
2718
- const granted = requested && grant.operations.find(
2725
+ const granted = grant && requested && grant.operations.find(
2719
2726
  (candidate) => this.operationCovers(candidate, requested)
2720
2727
  );
2721
2728
  if (!granted?.caveats?.length) {
@@ -2725,7 +2732,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2725
2732
  throw new Error("Invocation caveats do not match signed ReCap authority.");
2726
2733
  }
2727
2734
  return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
2728
- }) : entries;
2735
+ });
2729
2736
  return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
2730
2737
  };
2731
2738
  this.explicitHost = config.host;
@@ -3190,12 +3197,13 @@ var _TinyCloudNode = class _TinyCloudNode {
3190
3197
  if (!auth) {
3191
3198
  throw new Error("Account bootstrap requires an active wallet session");
3192
3199
  }
3200
+ const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
3193
3201
  const skipped = auth.lastActivationSkippedSpaceIds;
3202
+ if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
3194
3203
  if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
3195
- return { action: "run", mode: "fresh" };
3204
+ return { action: "run", mode: "repair" };
3196
3205
  }
3197
3206
  try {
3198
- const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
3199
3207
  const markerPermission = {
3200
3208
  service: "tinycloud.kv",
3201
3209
  space: accountSpaceId,
@@ -3207,7 +3215,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3207
3215
  }
3208
3216
  const marker = await this.readBootstrapCompletionMarker();
3209
3217
  if (marker.ok) {
3210
- if (this.isAcceptedBootstrapCompletionMarker(marker.data.data)) {
3218
+ if (this.isAcceptedBootstrapCompletionMarker(marker.data.data, steps.map((step) => step.id))) {
3211
3219
  return { action: "skip" };
3212
3220
  }
3213
3221
  return { action: "run", mode: "repair" };
@@ -3257,12 +3265,16 @@ var _TinyCloudNode = class _TinyCloudNode {
3257
3265
  );
3258
3266
  }
3259
3267
  }
3260
- isAcceptedBootstrapCompletionMarker(value) {
3268
+ /**
3269
+ * A marker written before a canonical space was added triggers one bounded repair.
3270
+ */
3271
+ isAcceptedBootstrapCompletionMarker(value, canonicalStepIds) {
3261
3272
  if (typeof value !== "object" || value === null) return false;
3262
3273
  const entries = Object.entries(value);
3263
3274
  const markerValue = (name) => entries.find(([key]) => key === name)?.[1];
3264
3275
  const version = markerValue("v");
3265
- return typeof version === "number" && Number.isInteger(version) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version);
3276
+ const stepIds = markerValue("stepIds");
3277
+ return typeof version === "number" && Number.isInteger(version) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version) && Array.isArray(stepIds) && canonicalStepIds.every((stepId) => stepIds.includes(stepId));
3266
3278
  }
3267
3279
  markerReadIsUnhostedSpace(meta) {
3268
3280
  return meta?.status === 404;
@@ -3349,30 +3361,39 @@ var _TinyCloudNode = class _TinyCloudNode {
3349
3361
  }
3350
3362
  }
3351
3363
  if (step.kind === "seed-spaces") {
3352
- const registered = await this.account.spaces.registerBatch(
3353
- step.spaces.map((space) => ({
3354
- spaceId: space.spaceId,
3355
- name: space.name,
3356
- ownerDid: this.did,
3357
- type: "owned",
3358
- permissions: ["*"],
3359
- status: "active"
3360
- }))
3361
- );
3362
- if (!registered.ok) {
3363
- throw Object.assign(
3364
- new Error(`Failed to seed account spaces: ${registered.error.message}`),
3365
- { cause: registered.error }
3366
- );
3367
- }
3368
- const batchError = registered.data.recoveredFromBatchError;
3369
- if (batchError) {
3370
- warnings.push({
3371
- stepId: step.id,
3372
- kind: "batch-write-reconciled",
3373
- code: batchError.code,
3374
- message: batchError.message
3375
- });
3364
+ const inputs = step.spaces.map((space) => ({
3365
+ spaceId: space.spaceId,
3366
+ name: space.name,
3367
+ ownerDid: this.did,
3368
+ type: "owned",
3369
+ permissions: ["*"],
3370
+ status: "active"
3371
+ }));
3372
+ if (mode === "fresh") {
3373
+ const registered = await this.account.spaces.registerBatch(inputs);
3374
+ if (!registered.ok) {
3375
+ throw Object.assign(
3376
+ new Error(`Failed to seed account spaces: ${registered.error.message}`),
3377
+ { cause: registered.error }
3378
+ );
3379
+ }
3380
+ const batchError = registered.data.recoveredFromBatchError;
3381
+ if (batchError) {
3382
+ warnings.push({
3383
+ stepId: step.id,
3384
+ kind: "batch-write-reconciled",
3385
+ code: batchError.code,
3386
+ message: batchError.message
3387
+ });
3388
+ }
3389
+ } else {
3390
+ const ensured = await this.account.spaces.registerMissing(inputs);
3391
+ if (!ensured.ok) {
3392
+ throw Object.assign(
3393
+ new Error(`Failed to seed account spaces: ${ensured.error.message}`),
3394
+ { cause: ensured.error }
3395
+ );
3396
+ }
3376
3397
  }
3377
3398
  }
3378
3399
  if (step.kind === "seed-applications") {
@@ -4057,6 +4078,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4057
4078
  stagedSessionExpiry,
4058
4079
  stagedRecap
4059
4080
  );
4081
+ const stagedAccountSpaceId = stagedAddress ? this.wasmBindings.makeSpaceId(stagedAddress, stagedChainId, ACCOUNT_REGISTRY_SPACE2) : void 0;
4060
4082
  const stagedGraph = this.stageRestoredServiceGraph({
4061
4083
  host: stagedHost,
4062
4084
  manager: stagedManager,
@@ -4065,6 +4087,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4065
4087
  nodeDid: stagedNodeDid,
4066
4088
  address: stagedAddress,
4067
4089
  chainId: stagedChainId,
4090
+ accountSpaceId: stagedAccountSpaceId,
4068
4091
  tinyCloudSession: stagedTcSession,
4069
4092
  sessionExpiry: stagedSessionExpiry,
4070
4093
  recap: stagedRecap
@@ -4230,6 +4253,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4230
4253
  }
4231
4254
  const delegationManager = new DelegationManager({
4232
4255
  hosts: [input.host],
4256
+ accountSpaceId: input.accountSpaceId,
4233
4257
  session: input.serviceSession,
4234
4258
  invoke: graph.invoke,
4235
4259
  invokeAny: graph.invokeAny,
@@ -5934,6 +5958,14 @@ var _TinyCloudNode = class _TinyCloudNode {
5934
5958
  delegation.delegationHeader
5935
5959
  );
5936
5960
  if (!activateResult.success) {
5961
+ if (this.operationsFromDelegation(delegation).some(
5962
+ (operation) => operation.resource?.startsWith("urn:cid:") === true && operation.service === "delegation" && operation.action === "tinycloud.delegation/revoke"
5963
+ ) && activateResult.status === 401 && /Cannot find parent delegation/i.test(activateResult.error ?? "")) {
5964
+ throw Object.assign(
5965
+ new Error("The host cannot activate a root raw-CID revoke authority without a parent delegation."),
5966
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: activateResult }
5967
+ );
5968
+ }
5937
5969
  throw Object.assign(
5938
5970
  new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
5939
5971
  { cause: activateResult }
@@ -5981,10 +6013,10 @@ var _TinyCloudNode = class _TinyCloudNode {
5981
6013
  }
5982
6014
  this.assertDelegationCaveatsPreservable(expanded);
5983
6015
  const rawEntries = expanded.filter(
5984
- (entry) => this.isEncryptionPermissionEntry(entry)
6016
+ (entry) => this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry)
5985
6017
  );
5986
6018
  const spaceEntries = expanded.filter(
5987
- (entry) => !this.isEncryptionPermissionEntry(entry)
6019
+ (entry) => !this.isEncryptionPermissionEntry(entry) && !this.isRawRevocationPermissionEntry(entry)
5988
6020
  );
5989
6021
  const bySpace = /* @__PURE__ */ new Map();
5990
6022
  for (const entry of spaceEntries) {
@@ -6011,17 +6043,29 @@ var _TinyCloudNode = class _TinyCloudNode {
6011
6043
  }
6012
6044
  const delegatedEntries = [...entries, ...rawForDelegation];
6013
6045
  const abilities = this.permissionsToAbilities(entries);
6014
- const prepared = this.wasmBindings.prepareSession({
6015
- abilities,
6016
- ...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
6017
- address: this.wasmBindings.ensureEip55(session.address),
6018
- chainId: session.chainId,
6019
- domain: this.siweDomain,
6020
- issuedAt: now.toISOString(),
6021
- expirationTime: expiresAt.toISOString(),
6022
- spaceId,
6023
- jwk: session.jwk
6024
- });
6046
+ const prepared = (() => {
6047
+ try {
6048
+ return this.wasmBindings.prepareSession({
6049
+ abilities,
6050
+ ...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
6051
+ address: this.wasmBindings.ensureEip55(session.address),
6052
+ chainId: session.chainId,
6053
+ domain: this.siweDomain,
6054
+ issuedAt: now.toISOString(),
6055
+ expirationTime: expiresAt.toISOString(),
6056
+ spaceId,
6057
+ jwk: session.jwk
6058
+ });
6059
+ } catch (error) {
6060
+ if (rawForDelegation.some((entry) => this.isRawRevocationPermissionEntry(entry)) && /invalid ReCap resource URI/i.test(error instanceof Error ? error.message : String(error))) {
6061
+ throw Object.assign(
6062
+ new Error("This WASM build cannot encode raw urn:cid ReCap resources."),
6063
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: error }
6064
+ );
6065
+ }
6066
+ throw error;
6067
+ }
6068
+ })();
6025
6069
  const signature = await this.signer.signMessage(prepared.siwe);
6026
6070
  const delegatedSession = this.wasmBindings.completeSessionSetup({
6027
6071
  ...prepared,
@@ -6032,6 +6076,12 @@ var _TinyCloudNode = class _TinyCloudNode {
6032
6076
  delegatedSession.delegationHeader
6033
6077
  );
6034
6078
  if (!activateResult.success) {
6079
+ if (rawForDelegation.some((entry) => this.isRawRevocationPermissionEntry(entry)) && activateResult.status === 401 && /Cannot find parent delegation/i.test(activateResult.error ?? "")) {
6080
+ throw Object.assign(
6081
+ new Error("The host cannot activate a root raw-CID revoke authority without a parent delegation."),
6082
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: activateResult }
6083
+ );
6084
+ }
6035
6085
  throw Object.assign(
6036
6086
  new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
6037
6087
  { cause: activateResult }
@@ -6384,8 +6434,18 @@ var _TinyCloudNode = class _TinyCloudNode {
6384
6434
  * @throws {@link PermissionNotInManifestError} when any requested
6385
6435
  * entry is not a subset of the granted session capabilities and
6386
6436
  * `forceWalletSign` is not set.
6437
+ * @throws when `onPrepared` is combined with `forceWalletSign: true`,
6438
+ * before anything is signed.
6439
+ * @throws the `onPrepared` rejection, unchanged, without activating the
6440
+ * delegation.
6387
6441
  */
6388
6442
  async delegateTo(did, permissions, options) {
6443
+ const onPrepared = options?.onPrepared;
6444
+ if (onPrepared && options?.forceWalletSign) {
6445
+ throw new Error(
6446
+ "delegateTo: onPrepared cannot be combined with forceWalletSign=true; the wallet-signed path activates the delegation before it could be handed to onPrepared."
6447
+ );
6448
+ }
6389
6449
  const session = this.currentTinyCloudSession();
6390
6450
  if (!session) {
6391
6451
  throw new SessionExpiredError(/* @__PURE__ */ new Date(0));
@@ -6444,7 +6504,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6444
6504
  expandedEntries,
6445
6505
  runtimeExpiration,
6446
6506
  runtimeGrant,
6447
- runtimeOperations
6507
+ runtimeOperations,
6508
+ onPrepared
6448
6509
  );
6449
6510
  return { delegation: delegation2, prompted: false };
6450
6511
  }
@@ -6454,7 +6515,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6454
6515
  did,
6455
6516
  expandedEntries,
6456
6517
  effectiveExpiration,
6457
- session
6518
+ session,
6519
+ onPrepared
6458
6520
  );
6459
6521
  return { delegation, prompted: false };
6460
6522
  }
@@ -6508,7 +6570,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6508
6570
  *
6509
6571
  * @internal
6510
6572
  */
6511
- async createDelegationViaWasmPath(did, entries, expirationTime, session) {
6573
+ async createDelegationViaWasmPath(did, entries, expirationTime, session, onPrepared) {
6512
6574
  if (entries.length === 0) {
6513
6575
  throw new Error(
6514
6576
  "createDelegationViaWasmPath requires a non-empty entries array"
@@ -6571,17 +6633,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6571
6633
  });
6572
6634
  const primary = result.resources[0];
6573
6635
  const delegationHeader = { Authorization: result.delegation };
6574
- const activateResult = await activateSessionWithHost2(
6575
- this.config.host,
6576
- delegationHeader
6577
- );
6578
- if (!activateResult.success) {
6579
- throw Object.assign(
6580
- new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
6581
- { cause: activateResult }
6582
- );
6583
- }
6584
- return {
6636
+ const delegation = {
6585
6637
  cid: result.cid,
6586
6638
  delegationHeader,
6587
6639
  spaceId,
@@ -6595,8 +6647,22 @@ var _TinyCloudNode = class _TinyCloudNode {
6595
6647
  chainId: session.chainId,
6596
6648
  host: this.config.host
6597
6649
  };
6650
+ if (onPrepared) {
6651
+ await onPrepared(delegation);
6652
+ }
6653
+ const activateResult = await activateSessionWithHost2(
6654
+ this.config.host,
6655
+ delegationHeader
6656
+ );
6657
+ if (!activateResult.success) {
6658
+ throw Object.assign(
6659
+ new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
6660
+ { cause: activateResult }
6661
+ );
6662
+ }
6663
+ return delegation;
6598
6664
  }
6599
- async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations) {
6665
+ async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations, onPrepared) {
6600
6666
  this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
6601
6667
  this.assertDelegationCaveatsPreservable(entries);
6602
6668
  const result = this.createDelegationWrapper({
@@ -6609,17 +6675,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6609
6675
  const primary = result.resources[0];
6610
6676
  const delegationHeader = { Authorization: result.delegation };
6611
6677
  const targetHost = grant.delegation.host ?? this.config.host;
6612
- const activateResult = await activateSessionWithHost2(
6613
- targetHost,
6614
- delegationHeader
6615
- );
6616
- if (!activateResult.success) {
6617
- throw Object.assign(
6618
- new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
6619
- { cause: activateResult }
6620
- );
6621
- }
6622
- return {
6678
+ const delegation = {
6623
6679
  cid: result.cid,
6624
6680
  delegationHeader,
6625
6681
  spaceId: grant.session.spaceId,
@@ -6633,6 +6689,20 @@ var _TinyCloudNode = class _TinyCloudNode {
6633
6689
  chainId: grant.delegation.chainId,
6634
6690
  host: targetHost
6635
6691
  };
6692
+ if (onPrepared) {
6693
+ await onPrepared(delegation);
6694
+ }
6695
+ const activateResult = await activateSessionWithHost2(
6696
+ targetHost,
6697
+ delegationHeader
6698
+ );
6699
+ if (!activateResult.success) {
6700
+ throw Object.assign(
6701
+ new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
6702
+ { cause: activateResult }
6703
+ );
6704
+ }
6705
+ return delegation;
6636
6706
  }
6637
6707
  resolvePermissionSpace(space, session) {
6638
6708
  if (space === void 0) {
@@ -6733,6 +6803,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6733
6803
  permissionsToAbilities(entries) {
6734
6804
  const abilities = {};
6735
6805
  for (const entry of entries) {
6806
+ if (this.isRawRevocationPermissionEntry(entry)) continue;
6736
6807
  const service = this.shortServiceName(entry.service);
6737
6808
  abilities[service] ?? (abilities[service] = {});
6738
6809
  const existing = abilities[service][entry.path] ?? [];
@@ -6750,9 +6821,16 @@ var _TinyCloudNode = class _TinyCloudNode {
6750
6821
  isEncryptionPermissionEntry(entry) {
6751
6822
  return entry.service === ENCRYPTION_PERMISSION_SERVICE2 && this.isEncryptionNetworkOperation("encryption", entry.path, entry.space);
6752
6823
  }
6824
+ isRawRevocationPermissionEntry(entry) {
6825
+ return entry.service === "tinycloud.delegation" && entry.path === "" && entry.space?.startsWith("urn:cid:") === true && entry.actions.includes("tinycloud.delegation/revoke");
6826
+ }
6753
6827
  permissionsToRawAbilities(entries) {
6754
6828
  const rawAbilities = {};
6755
6829
  for (const entry of entries) {
6830
+ if (this.isRawRevocationPermissionEntry(entry)) {
6831
+ rawAbilities[entry.space] = [...new Set(entry.actions)];
6832
+ continue;
6833
+ }
6756
6834
  if (!this.isEncryptionPermissionEntry(entry)) {
6757
6835
  continue;
6758
6836
  }
@@ -6772,7 +6850,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6772
6850
  return entries.flatMap((entry) => {
6773
6851
  const service = this.shortServiceName(entry.service);
6774
6852
  return entry.actions.map((action) => ({
6775
- ...this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
6853
+ ...this.isRawRevocationPermissionEntry(entry) ? { resource: entry.space } : this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
6776
6854
  service,
6777
6855
  path: entry.path,
6778
6856
  action,
@@ -6782,11 +6860,13 @@ var _TinyCloudNode = class _TinyCloudNode {
6782
6860
  }
6783
6861
  /** Raw network authority cannot be covered by a nested encryption space. */
6784
6862
  signedCapabilitySubset(requested, granted) {
6785
- const rawGranted = granted.filter((entry) => this.isEncryptionPermissionEntry(entry)).map((entry) => ({ ...entry, space: "encryption" }));
6786
- const spaceGranted = granted.filter((entry) => !this.isEncryptionPermissionEntry(entry));
6863
+ const rawGranted = granted.filter((entry) => this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry)).map((entry) => this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry);
6864
+ const spaceGranted = granted.filter(
6865
+ (entry) => !this.isEncryptionPermissionEntry(entry) && !this.isRawRevocationPermissionEntry(entry)
6866
+ );
6787
6867
  const missing = requested.filter((entry) => {
6788
- const raw = this.isEncryptionPermissionEntry(entry);
6789
- const comparable = raw ? { ...entry, space: "encryption" } : entry;
6868
+ const raw = this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry);
6869
+ const comparable = raw && this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry;
6790
6870
  return !isCapabilitySubset([comparable], raw ? rawGranted : spaceGranted).subset;
6791
6871
  });
6792
6872
  return { subset: missing.length === 0, missing };
@@ -6801,10 +6881,11 @@ var _TinyCloudNode = class _TinyCloudNode {
6801
6881
  }
6802
6882
  permissionEntriesToOperations(entries, session) {
6803
6883
  return entries.flatMap((entry) => {
6804
- const spaceId = this.resolvePermissionSpace(entry.space, session);
6884
+ const rawRevocation = this.isRawRevocationPermissionEntry(entry);
6885
+ const spaceId = rawRevocation ? void 0 : this.resolvePermissionSpace(entry.space, session);
6805
6886
  const service = this.shortServiceName(entry.service);
6806
6887
  return entry.actions.map((action) => ({
6807
- ...this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
6888
+ ...rawRevocation ? { resource: entry.space } : this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
6808
6889
  service,
6809
6890
  path: entry.path,
6810
6891
  action,
@@ -6883,7 +6964,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6883
6964
  delegatedResourcesForEntries(entries, spaceId) {
6884
6965
  return entries.map((entry) => ({
6885
6966
  service: this.shortServiceName(entry.service),
6886
- space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
6967
+ space: this.isRawRevocationPermissionEntry(entry) ? entry.space : this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
6887
6968
  path: entry.path,
6888
6969
  actions: [...entry.actions],
6889
6970
  ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
@@ -6893,8 +6974,9 @@ var _TinyCloudNode = class _TinyCloudNode {
6893
6974
  const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
6894
6975
  return resources.flatMap((resource) => {
6895
6976
  const service = this.invocationServiceName(resource.service);
6977
+ const rawRevocation = service === "delegation" && resource.space.startsWith("urn:cid:") && resource.path === "";
6896
6978
  return resource.actions.map((action) => ({
6897
- ...this.isEncryptionNetworkOperation(service, resource.path, resource.space) ? { resource: resource.path } : { spaceId: resource.space },
6979
+ ...rawRevocation ? { resource: resource.space } : this.isEncryptionNetworkOperation(service, resource.path, resource.space) ? { resource: resource.path } : { spaceId: resource.space },
6898
6980
  service,
6899
6981
  path: resource.path,
6900
6982
  action,
@@ -6940,7 +7022,7 @@ var _TinyCloudNode = class _TinyCloudNode {
6940
7022
  * @internal
6941
7023
  */
6942
7024
  buildActivationAbilities(delegation) {
6943
- var _a, _b, _c;
7025
+ var _a, _b, _c, _d;
6944
7026
  const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
6945
7027
  const abilities = {};
6946
7028
  const rawAbilities = {};
@@ -6960,13 +7042,18 @@ var _TinyCloudNode = class _TinyCloudNode {
6960
7042
  addActions(rawAbilities[resource.path], resource.actions);
6961
7043
  continue;
6962
7044
  }
7045
+ if (service === "delegation" && resource.space.startsWith("urn:cid:") && resource.path === "") {
7046
+ rawAbilities[_b = resource.space] ?? (rawAbilities[_b] = []);
7047
+ addActions(rawAbilities[resource.space], resource.actions);
7048
+ continue;
7049
+ }
6963
7050
  if (resource.space !== delegation.spaceId) {
6964
7051
  throw new Error(
6965
7052
  `useDelegation: resource targets space '${resource.space}' but the delegation activates space '${delegation.spaceId}'. Multi-space delegations cannot be activated in a single useDelegation call.`
6966
7053
  );
6967
7054
  }
6968
7055
  abilities[service] ?? (abilities[service] = {});
6969
- (_b = abilities[service])[_c = resource.path] ?? (_b[_c] = []);
7056
+ (_c = abilities[service])[_d = resource.path] ?? (_c[_d] = []);
6970
7057
  addActions(abilities[service][resource.path], resource.actions);
6971
7058
  }
6972
7059
  return { abilities, rawAbilities };
@@ -7038,6 +7125,9 @@ var _TinyCloudNode = class _TinyCloudNode {
7038
7125
  if (grantedAction === requestedAction) {
7039
7126
  return true;
7040
7127
  }
7128
+ if (isExplicitOnlyAction(requestedAction)) {
7129
+ return false;
7130
+ }
7041
7131
  if (grantedAction.endsWith("/*")) {
7042
7132
  const prefix = grantedAction.slice(0, -2);
7043
7133
  return requestedAction.startsWith(`${prefix}/`);