@tinycloud/node-sdk 2.1.0-beta.0 → 2.1.0-beta.2

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,54 +17025,63 @@ var require_utils2 = __commonJS({
17025
17025
  // src/index.ts
17026
17026
  var index_exports = {};
17027
17027
  __export(index_exports, {
17028
- AutoApproveSpaceCreationHandler: () => import_sdk_core6.AutoApproveSpaceCreationHandler,
17029
- CapabilityKeyRegistry: () => import_sdk_core13.CapabilityKeyRegistry,
17030
- CapabilityKeyRegistryErrorCodes: () => import_sdk_core13.CapabilityKeyRegistryErrorCodes,
17031
- DataVaultService: () => import_sdk_core10.DataVaultService,
17032
- DatabaseHandle: () => import_sdk_core8.DatabaseHandle,
17028
+ AutoApproveSpaceCreationHandler: () => import_sdk_core7.AutoApproveSpaceCreationHandler,
17029
+ CapabilityKeyRegistry: () => import_sdk_core15.CapabilityKeyRegistry,
17030
+ CapabilityKeyRegistryErrorCodes: () => import_sdk_core15.CapabilityKeyRegistryErrorCodes,
17031
+ DataVaultService: () => import_sdk_core12.DataVaultService,
17032
+ DatabaseHandle: () => import_sdk_core10.DatabaseHandle,
17033
17033
  DelegatedAccess: () => DelegatedAccess,
17034
- DelegationErrorCodes: () => import_sdk_core12.DelegationErrorCodes,
17035
- DelegationManager: () => import_sdk_core12.DelegationManager,
17036
- DuckDbAction: () => import_sdk_core9.DuckDbAction,
17037
- DuckDbDatabaseHandle: () => import_sdk_core9.DuckDbDatabaseHandle,
17038
- DuckDbService: () => import_sdk_core9.DuckDbService,
17034
+ DelegationErrorCodes: () => import_sdk_core14.DelegationErrorCodes,
17035
+ DelegationManager: () => import_sdk_core14.DelegationManager,
17036
+ DuckDbAction: () => import_sdk_core11.DuckDbAction,
17037
+ DuckDbDatabaseHandle: () => import_sdk_core11.DuckDbDatabaseHandle,
17038
+ DuckDbService: () => import_sdk_core11.DuckDbService,
17039
17039
  FileSessionStorage: () => FileSessionStorage,
17040
- HooksService: () => import_sdk_core11.HooksService,
17041
- KVService: () => import_sdk_core7.KVService,
17040
+ HooksService: () => import_sdk_core13.HooksService,
17041
+ KVService: () => import_sdk_core9.KVService,
17042
+ ManifestValidationError: () => import_sdk_core8.ManifestValidationError,
17042
17043
  MemorySessionStorage: () => MemorySessionStorage,
17043
17044
  NodeUserAuthorization: () => NodeUserAuthorization,
17044
17045
  NodeWasmBindings: () => NodeWasmBindings,
17045
- PrefixedKVService: () => import_sdk_core7.PrefixedKVService,
17046
+ PermissionNotInManifestError: () => import_sdk_core8.PermissionNotInManifestError,
17047
+ PrefixedKVService: () => import_sdk_core9.PrefixedKVService,
17046
17048
  PrivateKeySigner: () => PrivateKeySigner,
17047
- ProtocolMismatchError: () => import_sdk_core15.ProtocolMismatchError,
17048
- SQLAction: () => import_sdk_core8.SQLAction,
17049
- SQLService: () => import_sdk_core8.SQLService,
17050
- ServiceContext: () => import_sdk_core16.ServiceContext,
17051
- SharingService: () => import_sdk_core12.SharingService,
17052
- SilentNotificationHandler: () => import_sdk_core6.SilentNotificationHandler,
17053
- Space: () => import_sdk_core14.Space,
17054
- SpaceErrorCodes: () => import_sdk_core14.SpaceErrorCodes,
17055
- SpaceService: () => import_sdk_core14.SpaceService,
17056
- TinyCloud: () => import_sdk_core5.TinyCloud,
17049
+ ProtocolMismatchError: () => import_sdk_core17.ProtocolMismatchError,
17050
+ SQLAction: () => import_sdk_core10.SQLAction,
17051
+ SQLService: () => import_sdk_core10.SQLService,
17052
+ ServiceContext: () => import_sdk_core18.ServiceContext,
17053
+ SessionExpiredError: () => import_sdk_core8.SessionExpiredError,
17054
+ SharingService: () => import_sdk_core14.SharingService,
17055
+ SilentNotificationHandler: () => import_sdk_core7.SilentNotificationHandler,
17056
+ Space: () => import_sdk_core16.Space,
17057
+ SpaceErrorCodes: () => import_sdk_core16.SpaceErrorCodes,
17058
+ SpaceService: () => import_sdk_core16.SpaceService,
17059
+ TinyCloud: () => import_sdk_core6.TinyCloud,
17057
17060
  TinyCloudNode: () => TinyCloudNode,
17058
- UnsupportedFeatureError: () => import_sdk_core15.UnsupportedFeatureError,
17059
- VaultHeaders: () => import_sdk_core10.VaultHeaders,
17060
- VaultPublicSpaceKVActions: () => import_sdk_core10.VaultPublicSpaceKVActions,
17061
- VersionCheckError: () => import_sdk_core15.VersionCheckError,
17061
+ UnsupportedFeatureError: () => import_sdk_core17.UnsupportedFeatureError,
17062
+ VaultHeaders: () => import_sdk_core12.VaultHeaders,
17063
+ VaultPublicSpaceKVActions: () => import_sdk_core12.VaultPublicSpaceKVActions,
17064
+ VersionCheckError: () => import_sdk_core17.VersionCheckError,
17062
17065
  WasmKeyProvider: () => WasmKeyProvider,
17063
- buildSpaceUri: () => import_sdk_core14.buildSpaceUri,
17064
- checkNodeInfo: () => import_sdk_core15.checkNodeInfo,
17065
- createCapabilityKeyRegistry: () => import_sdk_core13.createCapabilityKeyRegistry,
17066
- createSharingService: () => import_sdk_core12.createSharingService,
17067
- createSpaceService: () => import_sdk_core14.createSpaceService,
17068
- createVaultCrypto: () => import_sdk_core10.createVaultCrypto,
17066
+ buildSpaceUri: () => import_sdk_core16.buildSpaceUri,
17067
+ checkNodeInfo: () => import_sdk_core17.checkNodeInfo,
17068
+ createCapabilityKeyRegistry: () => import_sdk_core15.createCapabilityKeyRegistry,
17069
+ createSharingService: () => import_sdk_core14.createSharingService,
17070
+ createSpaceService: () => import_sdk_core16.createSpaceService,
17071
+ createVaultCrypto: () => import_sdk_core12.createVaultCrypto,
17069
17072
  createWasmKeyProvider: () => createWasmKeyProvider,
17070
17073
  defaultSignStrategy: () => defaultSignStrategy,
17071
- defaultSpaceCreationHandler: () => import_sdk_core6.defaultSpaceCreationHandler,
17074
+ defaultSpaceCreationHandler: () => import_sdk_core7.defaultSpaceCreationHandler,
17072
17075
  deserializeDelegation: () => deserializeDelegation,
17073
- makePublicSpaceId: () => import_sdk_core14.makePublicSpaceId,
17074
- parseSpaceUri: () => import_sdk_core14.parseSpaceUri,
17075
- serializeDelegation: () => serializeDelegation
17076
+ expandActionShortNames: () => import_sdk_core8.expandActionShortNames,
17077
+ isCapabilitySubset: () => import_sdk_core8.isCapabilitySubset,
17078
+ loadManifest: () => import_sdk_core8.loadManifest,
17079
+ makePublicSpaceId: () => import_sdk_core16.makePublicSpaceId,
17080
+ parseExpiry: () => import_sdk_core8.parseExpiry,
17081
+ parseSpaceUri: () => import_sdk_core16.parseSpaceUri,
17082
+ resolveManifest: () => import_sdk_core8.resolveManifest,
17083
+ serializeDelegation: () => serializeDelegation,
17084
+ validateManifest: () => import_sdk_core8.validateManifest
17076
17085
  });
17077
17086
  module.exports = __toCommonJS(index_exports);
17078
17087
 
@@ -17087,6 +17096,7 @@ var _NodeWasmBindings = class _NodeWasmBindings {
17087
17096
  this.ensureEip55 = import_node_sdk_wasm.ensureEip55;
17088
17097
  this.makeSpaceId = import_node_sdk_wasm.makeSpaceId;
17089
17098
  this.createDelegation = import_node_sdk_wasm.createDelegation;
17099
+ this.parseRecapFromSiwe = import_node_sdk_wasm.parseRecapFromSiwe;
17090
17100
  this.generateHostSIWEMessage = import_node_sdk_wasm.generateHostSIWEMessage;
17091
17101
  this.siweToDelegationHeaders = import_node_sdk_wasm.siweToDelegationHeaders;
17092
17102
  this.protocolVersion = import_node_sdk_wasm.protocolVersion;
@@ -17175,7 +17185,7 @@ var PrivateKeySigner = class {
17175
17185
  };
17176
17186
 
17177
17187
  // src/TinyCloudNode.ts
17178
- var import_sdk_core3 = require("@tinycloud/sdk-core");
17188
+ var import_sdk_core4 = require("@tinycloud/sdk-core");
17179
17189
 
17180
17190
  // src/authorization/NodeUserAuthorization.ts
17181
17191
  var import_sdk_core = require("@tinycloud/sdk-core");
@@ -17317,8 +17327,25 @@ var NodeUserAuthorization = class {
17317
17327
  this.enablePublicSpace = config.enablePublicSpace ?? true;
17318
17328
  this.nonce = config.nonce;
17319
17329
  this.siweConfig = config.siweConfig;
17330
+ this._manifest = config.manifest;
17320
17331
  this.sessionManager = this.wasm.createSessionManager();
17321
17332
  }
17333
+ /**
17334
+ * Return the manifest currently driving sign-in behavior, or
17335
+ * `undefined` if none is set. Used by TinyCloudWeb/TinyCloudNode
17336
+ * internals to surface the manifest for requestPermissions flows
17337
+ * without forcing the caller to track it separately.
17338
+ */
17339
+ get manifest() {
17340
+ return this._manifest;
17341
+ }
17342
+ /**
17343
+ * Install or replace the stored manifest. Takes effect on the next
17344
+ * `signIn()` call — the current session (if any) is not touched.
17345
+ */
17346
+ setManifest(manifest) {
17347
+ this._manifest = manifest;
17348
+ }
17322
17349
  /**
17323
17350
  * The current active session (web-core compatible).
17324
17351
  */
@@ -17335,6 +17362,39 @@ var NodeUserAuthorization = class {
17335
17362
  get nodeFeatures() {
17336
17363
  return this._nodeFeatures;
17337
17364
  }
17365
+ /**
17366
+ * Compute the `abilities` map the WASM `prepareSession` call should
17367
+ * see at sign-in time.
17368
+ *
17369
+ * When a manifest is installed, we resolve it and union together:
17370
+ * - the app's own `resources` (what it needs at runtime)
17371
+ * - every `additionalDelegates[*].permissions` list (what it will
17372
+ * re-delegate to other DIDs post sign-in)
17373
+ *
17374
+ * into the short-service / path / full-URN-actions shape the WASM
17375
+ * layer expects. This is the key invariant that lets
17376
+ * {@link TinyCloudNode.delegateTo} issue manifest-declared
17377
+ * delegations via the session key (no wallet prompt): the session's
17378
+ * own recap already covers every action those delegations need.
17379
+ *
17380
+ * When no manifest is installed, we fall back to the
17381
+ * {@link defaultActions} table so existing callers see no change.
17382
+ *
17383
+ * This is a pure function of `this._manifest` + `this.defaultActions`
17384
+ * — the manifest resolution performs no I/O and throws a
17385
+ * {@link ManifestValidationError} on structural problems (missing
17386
+ * id/name, unparseable expiry, etc), which will surface at sign-in
17387
+ * rather than being silently swallowed.
17388
+ *
17389
+ * @internal
17390
+ */
17391
+ resolveSignInAbilities() {
17392
+ if (this._manifest === void 0) {
17393
+ return this.defaultActions;
17394
+ }
17395
+ const resolved = (0, import_sdk_core.resolveManifest)(this._manifest);
17396
+ return (0, import_sdk_core.manifestAbilitiesUnion)(resolved);
17397
+ }
17338
17398
  /**
17339
17399
  * Build SIWE overrides from the top-level nonce and siweConfig.
17340
17400
  * - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
@@ -17538,7 +17598,7 @@ var NodeUserAuthorization = class {
17538
17598
  const now = /* @__PURE__ */ new Date();
17539
17599
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
17540
17600
  const prepared = this.wasm.prepareSession({
17541
- abilities: this.defaultActions,
17601
+ abilities: this.resolveSignInAbilities(),
17542
17602
  address,
17543
17603
  chainId,
17544
17604
  domain: this.domain,
@@ -17681,7 +17741,7 @@ var NodeUserAuthorization = class {
17681
17741
  const now = /* @__PURE__ */ new Date();
17682
17742
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
17683
17743
  const prepared = this.wasm.prepareSession({
17684
- abilities: this.defaultActions,
17744
+ abilities: this.resolveSignInAbilities(),
17685
17745
  address,
17686
17746
  chainId,
17687
17747
  domain: this.domain,
@@ -18001,9 +18061,69 @@ function createWasmKeyProvider(sessionManager) {
18001
18061
  return new WasmKeyProvider({ sessionManager });
18002
18062
  }
18003
18063
 
18064
+ // src/delegateToHelpers.ts
18065
+ var import_sdk_core3 = require("@tinycloud/sdk-core");
18066
+ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
18067
+ const byService = /* @__PURE__ */ new Map();
18068
+ for (const a of actions) {
18069
+ const slashIdx = a.indexOf("/");
18070
+ if (slashIdx === -1) {
18071
+ continue;
18072
+ }
18073
+ const service = a.slice(0, slashIdx);
18074
+ if (!service.startsWith("tinycloud.")) {
18075
+ continue;
18076
+ }
18077
+ const list = byService.get(service);
18078
+ if (list === void 0) {
18079
+ byService.set(service, [a]);
18080
+ } else {
18081
+ list.push(a);
18082
+ }
18083
+ }
18084
+ const space = spaceIdOverride ?? "default";
18085
+ const entries = [];
18086
+ for (const [service, actionList] of byService) {
18087
+ entries.push({
18088
+ service,
18089
+ space,
18090
+ path,
18091
+ actions: actionList
18092
+ });
18093
+ }
18094
+ return entries;
18095
+ }
18096
+ function resolveExpiryMs(expiry) {
18097
+ if (expiry === void 0) {
18098
+ return 60 * 60 * 1e3;
18099
+ }
18100
+ if (typeof expiry === "number") {
18101
+ if (!Number.isFinite(expiry) || expiry <= 0) {
18102
+ throw new Error(
18103
+ `delegateTo expiry must be a positive finite number (got ${expiry})`
18104
+ );
18105
+ }
18106
+ return expiry;
18107
+ }
18108
+ return (0, import_sdk_core3.parseExpiry)(expiry);
18109
+ }
18110
+ function extractSiweExpiration(siwe) {
18111
+ const parsed = new import_sdk_core3.SiweMessage(siwe);
18112
+ if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
18113
+ return void 0;
18114
+ }
18115
+ const d = new Date(parsed.expirationTime);
18116
+ if (Number.isNaN(d.getTime())) {
18117
+ throw new Error(
18118
+ `Session SIWE has unparseable expirationTime: ${parsed.expirationTime}`
18119
+ );
18120
+ }
18121
+ return d;
18122
+ }
18123
+
18004
18124
  // src/TinyCloudNode.ts
18005
18125
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
18006
- var TinyCloudNode = class _TinyCloudNode {
18126
+ var _TinyCloudNode = class _TinyCloudNode {
18007
18127
  /**
18008
18128
  * Create a new TinyCloudNode instance.
18009
18129
  *
@@ -18058,12 +18178,12 @@ var TinyCloudNode = class _TinyCloudNode {
18058
18178
  throw new Error("Failed to get session key JWK");
18059
18179
  }
18060
18180
  this.sessionKeyJwk = JSON.parse(jwkStr);
18061
- this._capabilityRegistry = new import_sdk_core3.CapabilityKeyRegistry();
18181
+ this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
18062
18182
  this._keyProvider = new WasmKeyProvider({
18063
18183
  sessionManager: this.sessionManager
18064
18184
  });
18065
- this.notificationHandler = config.notificationHandler ?? new import_sdk_core3.SilentNotificationHandler();
18066
- this._sharingService = new import_sdk_core3.SharingService({
18185
+ this.notificationHandler = config.notificationHandler ?? new import_sdk_core4.SilentNotificationHandler();
18186
+ this._sharingService = new import_sdk_core4.SharingService({
18067
18187
  hosts: [this.config.host],
18068
18188
  // session: undefined - not needed for receive()
18069
18189
  invoke: this.wasmBindings.invoke,
@@ -18073,8 +18193,8 @@ var TinyCloudNode = class _TinyCloudNode {
18073
18193
  // delegationManager: undefined - not needed for receive()
18074
18194
  createKVService: (config2) => {
18075
18195
  const prefix = config2.pathPrefix?.replace(/\/$/, "");
18076
- const kvService = new import_sdk_core3.KVService({ prefix });
18077
- const kvContext = new import_sdk_core3.ServiceContext({
18196
+ const kvService = new import_sdk_core4.KVService({ prefix });
18197
+ const kvContext = new import_sdk_core4.ServiceContext({
18078
18198
  invoke: config2.invoke,
18079
18199
  fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
18080
18200
  hosts: config2.hosts
@@ -18127,12 +18247,35 @@ var TinyCloudNode = class _TinyCloudNode {
18127
18247
  enablePublicSpace: config.enablePublicSpace ?? true,
18128
18248
  spaceCreationHandler: config.spaceCreationHandler,
18129
18249
  nonce: config.nonce,
18130
- siweConfig: config.siweConfig
18250
+ siweConfig: config.siweConfig,
18251
+ manifest: config.manifest
18131
18252
  });
18132
- this.tc = new import_sdk_core3.TinyCloud(this.auth, {
18253
+ this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18133
18254
  invokeAny: this.wasmBindings.invokeAny
18134
18255
  });
18135
18256
  }
18257
+ /**
18258
+ * Install or replace the manifest that drives the SIWE recap at
18259
+ * sign-in. Takes effect on the next `signIn()` call — the current
18260
+ * session (if any) is not touched. Wire this up from a higher
18261
+ * layer (e.g. TinyCloudWeb.setManifest) so the manifest is kept
18262
+ * in sync across the stack.
18263
+ */
18264
+ setManifest(manifest) {
18265
+ if (!this.auth) {
18266
+ throw new Error(
18267
+ "setManifest requires wallet mode. Provide a signer or privateKey in the TinyCloudNode config."
18268
+ );
18269
+ }
18270
+ this.auth.setManifest(manifest);
18271
+ }
18272
+ /**
18273
+ * Return the manifest currently installed on the auth handler,
18274
+ * or `undefined` if none is set.
18275
+ */
18276
+ get manifest() {
18277
+ return this.auth?.manifest;
18278
+ }
18136
18279
  /**
18137
18280
  * Get the primary identity DID for this user.
18138
18281
  * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
@@ -18228,22 +18371,22 @@ var TinyCloudNode = class _TinyCloudNode {
18228
18371
  if (sessionData.chainId) {
18229
18372
  this._chainId = sessionData.chainId;
18230
18373
  }
18231
- this._serviceContext = new import_sdk_core3.ServiceContext({
18374
+ this._serviceContext = new import_sdk_core4.ServiceContext({
18232
18375
  invoke: this.wasmBindings.invoke,
18233
18376
  invokeAny: this.wasmBindings.invokeAny,
18234
18377
  fetch: globalThis.fetch.bind(globalThis),
18235
18378
  hosts: [this.config.host]
18236
18379
  });
18237
- this._kv = new import_sdk_core3.KVService({});
18380
+ this._kv = new import_sdk_core4.KVService({});
18238
18381
  this._kv.initialize(this._serviceContext);
18239
18382
  this._serviceContext.registerService("kv", this._kv);
18240
- this._sql = new import_sdk_core3.SQLService({});
18383
+ this._sql = new import_sdk_core4.SQLService({});
18241
18384
  this._sql.initialize(this._serviceContext);
18242
18385
  this._serviceContext.registerService("sql", this._sql);
18243
- this._duckdb = new import_sdk_core3.DuckDbService({});
18386
+ this._duckdb = new import_sdk_core4.DuckDbService({});
18244
18387
  this._duckdb.initialize(this._serviceContext);
18245
18388
  this._serviceContext.registerService("duckdb", this._duckdb);
18246
- this._hooks = new import_sdk_core3.HooksService({});
18389
+ this._hooks = new import_sdk_core4.HooksService({});
18247
18390
  this._hooks.initialize(this._serviceContext);
18248
18391
  this._serviceContext.registerService("hooks", this._hooks);
18249
18392
  const serviceSession = {
@@ -18255,7 +18398,7 @@ var TinyCloudNode = class _TinyCloudNode {
18255
18398
  };
18256
18399
  this._serviceContext.setSession(serviceSession);
18257
18400
  const wasm = this.wasmBindings;
18258
- const vaultCrypto = (0, import_sdk_core3.createVaultCrypto)({
18401
+ const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
18259
18402
  vault_encrypt: wasm.vault_encrypt,
18260
18403
  vault_decrypt: wasm.vault_decrypt,
18261
18404
  vault_derive_key: wasm.vault_derive_key,
@@ -18265,7 +18408,7 @@ var TinyCloudNode = class _TinyCloudNode {
18265
18408
  vault_sha256: wasm.vault_sha256
18266
18409
  });
18267
18410
  const self2 = this;
18268
- this._vault = new import_sdk_core3.DataVaultService({
18411
+ this._vault = new import_sdk_core4.DataVaultService({
18269
18412
  spaceId: sessionData.spaceId,
18270
18413
  crypto: vaultCrypto,
18271
18414
  tc: {
@@ -18281,8 +18424,8 @@ var TinyCloudNode = class _TinyCloudNode {
18281
18424
  get publicKV() {
18282
18425
  return self2._publicKV ?? self2.tc.publicKV;
18283
18426
  },
18284
- readPublicSpace: (host, spaceId, key2) => import_sdk_core3.TinyCloud.readPublicSpace(host, spaceId, key2),
18285
- makePublicSpaceId: import_sdk_core3.TinyCloud.makePublicSpaceId,
18427
+ readPublicSpace: (host, spaceId, key2) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key2),
18428
+ makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
18286
18429
  did: this.did,
18287
18430
  address: sessionData.address ?? this._address ?? "",
18288
18431
  chainId: sessionData.chainId ?? this._chainId,
@@ -18345,7 +18488,7 @@ var TinyCloudNode = class _TinyCloudNode {
18345
18488
  nonce: this.config.nonce,
18346
18489
  siweConfig: this.config.siweConfig
18347
18490
  });
18348
- this.tc = new import_sdk_core3.TinyCloud(this.auth, {
18491
+ this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18349
18492
  invokeAny: this.wasmBindings.invokeAny
18350
18493
  });
18351
18494
  this.config.prefix = prefix;
@@ -18385,7 +18528,7 @@ var TinyCloudNode = class _TinyCloudNode {
18385
18528
  nonce: this.config.nonce,
18386
18529
  siweConfig: this.config.siweConfig
18387
18530
  });
18388
- this.tc = new import_sdk_core3.TinyCloud(this.auth, {
18531
+ this.tc = new import_sdk_core4.TinyCloud(this.auth, {
18389
18532
  invokeAny: this.wasmBindings.invokeAny
18390
18533
  });
18391
18534
  this.config.prefix = prefix;
@@ -18400,27 +18543,27 @@ var TinyCloudNode = class _TinyCloudNode {
18400
18543
  return;
18401
18544
  }
18402
18545
  this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
18403
- this._serviceContext = new import_sdk_core3.ServiceContext({
18546
+ this._serviceContext = new import_sdk_core4.ServiceContext({
18404
18547
  invoke: this.wasmBindings.invoke,
18405
18548
  invokeAny: this.wasmBindings.invokeAny,
18406
18549
  fetch: globalThis.fetch.bind(globalThis),
18407
18550
  hosts: [this.config.host]
18408
18551
  });
18409
- this._kv = new import_sdk_core3.KVService({});
18552
+ this._kv = new import_sdk_core4.KVService({});
18410
18553
  this._kv.initialize(this._serviceContext);
18411
18554
  this._serviceContext.registerService("kv", this._kv);
18412
18555
  const features = this.nodeFeatures;
18413
18556
  if (features.length === 0 || features.includes("sql")) {
18414
- this._sql = new import_sdk_core3.SQLService({});
18557
+ this._sql = new import_sdk_core4.SQLService({});
18415
18558
  this._sql.initialize(this._serviceContext);
18416
18559
  this._serviceContext.registerService("sql", this._sql);
18417
18560
  }
18418
18561
  if (features.length === 0 || features.includes("duckdb")) {
18419
- this._duckdb = new import_sdk_core3.DuckDbService({});
18562
+ this._duckdb = new import_sdk_core4.DuckDbService({});
18420
18563
  this._duckdb.initialize(this._serviceContext);
18421
18564
  this._serviceContext.registerService("duckdb", this._duckdb);
18422
18565
  }
18423
- this._hooks = new import_sdk_core3.HooksService({});
18566
+ this._hooks = new import_sdk_core4.HooksService({});
18424
18567
  this._hooks.initialize(this._serviceContext);
18425
18568
  this._serviceContext.registerService("hooks", this._hooks);
18426
18569
  const serviceSession = {
@@ -18433,7 +18576,7 @@ var TinyCloudNode = class _TinyCloudNode {
18433
18576
  this._serviceContext.setSession(serviceSession);
18434
18577
  this.tc.serviceContext.setSession(serviceSession);
18435
18578
  const wasm = this.wasmBindings;
18436
- const vaultCrypto = (0, import_sdk_core3.createVaultCrypto)({
18579
+ const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
18437
18580
  vault_encrypt: wasm.vault_encrypt,
18438
18581
  vault_decrypt: wasm.vault_decrypt,
18439
18582
  vault_derive_key: wasm.vault_derive_key,
@@ -18443,7 +18586,7 @@ var TinyCloudNode = class _TinyCloudNode {
18443
18586
  vault_sha256: wasm.vault_sha256
18444
18587
  });
18445
18588
  const self2 = this;
18446
- this._vault = new import_sdk_core3.DataVaultService({
18589
+ this._vault = new import_sdk_core4.DataVaultService({
18447
18590
  spaceId: session.spaceId,
18448
18591
  crypto: vaultCrypto,
18449
18592
  tc: {
@@ -18459,8 +18602,8 @@ var TinyCloudNode = class _TinyCloudNode {
18459
18602
  get publicKV() {
18460
18603
  return self2._publicKV ?? self2.tc.publicKV;
18461
18604
  },
18462
- readPublicSpace: (host, spaceId, key2) => import_sdk_core3.TinyCloud.readPublicSpace(host, spaceId, key2),
18463
- makePublicSpaceId: import_sdk_core3.TinyCloud.makePublicSpaceId,
18605
+ readPublicSpace: (host, spaceId, key2) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key2),
18606
+ makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
18464
18607
  did: this.did,
18465
18608
  address: this._address,
18466
18609
  chainId: this._chainId,
@@ -18476,7 +18619,7 @@ var TinyCloudNode = class _TinyCloudNode {
18476
18619
  * @internal
18477
18620
  */
18478
18621
  initializeV2Services(serviceSession) {
18479
- this._capabilityRegistry = new import_sdk_core3.CapabilityKeyRegistry();
18622
+ this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
18480
18623
  const tcSession = this.auth?.tinyCloudSession;
18481
18624
  if (tcSession && this._address) {
18482
18625
  const sessionKey = {
@@ -18550,13 +18693,13 @@ var TinyCloudNode = class _TinyCloudNode {
18550
18693
  }
18551
18694
  this._capabilityRegistry.registerKey(sessionKey, delegations);
18552
18695
  }
18553
- this._delegationManager = new import_sdk_core3.DelegationManager({
18696
+ this._delegationManager = new import_sdk_core4.DelegationManager({
18554
18697
  hosts: [this.config.host],
18555
18698
  session: serviceSession,
18556
18699
  invoke: this.wasmBindings.invoke,
18557
18700
  fetch: globalThis.fetch.bind(globalThis)
18558
18701
  });
18559
- this._spaceService = new import_sdk_core3.SpaceService({
18702
+ this._spaceService = new import_sdk_core4.SpaceService({
18560
18703
  hosts: [this.config.host],
18561
18704
  session: serviceSession,
18562
18705
  invoke: this.wasmBindings.invoke,
@@ -18564,9 +18707,9 @@ var TinyCloudNode = class _TinyCloudNode {
18564
18707
  capabilityRegistry: this._capabilityRegistry,
18565
18708
  userDid: this.did,
18566
18709
  createKVService: (spaceId) => {
18567
- const kvService = new import_sdk_core3.KVService({});
18710
+ const kvService = new import_sdk_core4.KVService({});
18568
18711
  if (this._serviceContext) {
18569
- const spaceScopedContext = new import_sdk_core3.ServiceContext({
18712
+ const spaceScopedContext = new import_sdk_core4.ServiceContext({
18570
18713
  invoke: this._serviceContext.invoke,
18571
18714
  fetch: this._serviceContext.fetch,
18572
18715
  hosts: this._serviceContext.hosts
@@ -18639,7 +18782,19 @@ var TinyCloudNode = class _TinyCloudNode {
18639
18782
  }
18640
18783
  /**
18641
18784
  * Wrapper for the WASM createDelegation function.
18642
- * Adapts the WASM interface to what SharingService expects.
18785
+ *
18786
+ * The WASM call now takes a multi-resource `abilities` map
18787
+ * (matching `prepareSession`'s shape) and emits ONE UCAN that
18788
+ * covers every `(service, path, actions)` entry. We mirror the raw
18789
+ * result back through `CreateDelegationWasmResult`, converting the
18790
+ * seconds-since-epoch `expiry` to a Date and normalizing the
18791
+ * `delegateDid` → `delegateDID` case.
18792
+ *
18793
+ * Both SharingService (single-entry) and
18794
+ * {@link TinyCloudNode.delegateTo} (multi-entry) drive this through
18795
+ * the same code path so there's exactly one place that touches the
18796
+ * WASM boundary.
18797
+ *
18643
18798
  * @internal
18644
18799
  */
18645
18800
  createDelegationWrapper(params) {
@@ -18654,18 +18809,19 @@ var TinyCloudNode = class _TinyCloudNode {
18654
18809
  wasmSession,
18655
18810
  params.delegateDID,
18656
18811
  params.spaceId,
18657
- params.path,
18658
- params.actions,
18812
+ params.abilities,
18659
18813
  params.expirationSecs,
18660
18814
  params.notBeforeSecs
18661
18815
  );
18662
18816
  return {
18663
18817
  delegation: result.delegation,
18664
18818
  cid: result.cid,
18665
- delegateDID: result.delegateDid,
18666
- path: result.path,
18667
- actions: result.actions,
18668
- expiry: new Date(result.expiry * 1e3)
18819
+ // Rust serde `rename_all = "camelCase"` emits `delegateDid`
18820
+ // (lowercase d); the TypeScript interface uses `delegateDID`
18821
+ // (historical, matches Delegation.delegateDID). Normalize here.
18822
+ delegateDID: result.delegateDid ?? result.delegateDID,
18823
+ expiry: new Date(result.expiry * 1e3),
18824
+ resources: result.resources
18669
18825
  };
18670
18826
  }
18671
18827
  /**
@@ -18705,7 +18861,7 @@ var TinyCloudNode = class _TinyCloudNode {
18705
18861
  ...prepared,
18706
18862
  signature: signature2
18707
18863
  });
18708
- const activateResult = await (0, import_sdk_core3.activateSessionWithHost)(
18864
+ const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
18709
18865
  host,
18710
18866
  delegationSession.delegationHeader
18711
18867
  );
@@ -18772,7 +18928,7 @@ var TinyCloudNode = class _TinyCloudNode {
18772
18928
  if (!this._sql) {
18773
18929
  const features = this.nodeFeatures;
18774
18930
  if (features.length > 0 && !features.includes("sql")) {
18775
- throw new import_sdk_core3.UnsupportedFeatureError("sql", this.config.host, features);
18931
+ throw new import_sdk_core4.UnsupportedFeatureError("sql", this.config.host, features);
18776
18932
  }
18777
18933
  throw new Error("Not signed in. Call signIn() first.");
18778
18934
  }
@@ -18785,7 +18941,7 @@ var TinyCloudNode = class _TinyCloudNode {
18785
18941
  if (!this._duckdb) {
18786
18942
  const features = this.nodeFeatures;
18787
18943
  if (features.length > 0 && !features.includes("duckdb")) {
18788
- throw new import_sdk_core3.UnsupportedFeatureError("duckdb", this.config.host, features);
18944
+ throw new import_sdk_core4.UnsupportedFeatureError("duckdb", this.config.host, features);
18789
18945
  }
18790
18946
  throw new Error("Not signed in. Call signIn() first.");
18791
18947
  }
@@ -19024,7 +19180,7 @@ var TinyCloudNode = class _TinyCloudNode {
19024
19180
  ...prepared,
19025
19181
  signature: signature2
19026
19182
  });
19027
- const activateResult = await (0, import_sdk_core3.activateSessionWithHost)(
19183
+ const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19028
19184
  this.config.host,
19029
19185
  delegationSession.delegationHeader
19030
19186
  );
@@ -19051,8 +19207,8 @@ var TinyCloudNode = class _TinyCloudNode {
19051
19207
  }]);
19052
19208
  }
19053
19209
  if (this._serviceContext) {
19054
- const publicKV = new import_sdk_core3.KVService({ prefix: "" });
19055
- const publicContext = new import_sdk_core3.ServiceContext({
19210
+ const publicKV = new import_sdk_core4.KVService({ prefix: "" });
19211
+ const publicContext = new import_sdk_core4.ServiceContext({
19056
19212
  invoke: this.wasmBindings.invoke,
19057
19213
  fetch: this._serviceContext.fetch,
19058
19214
  hosts: this._serviceContext.hosts
@@ -19137,6 +19293,209 @@ var TinyCloudNode = class _TinyCloudNode {
19137
19293
  async checkPermission(path, action) {
19138
19294
  return this.delegationManager.checkPermission(path, action);
19139
19295
  }
19296
+ /**
19297
+ * Issue a delegation using the capability-chain flow.
19298
+ *
19299
+ * When every requested permission is a subset of the current
19300
+ * session's recap, the delegation is signed by the session key via
19301
+ * WASM — no wallet prompt. When at least one is NOT derivable, a
19302
+ * {@link PermissionNotInManifestError} is raised (carrying the
19303
+ * missing entries) so the caller can trigger an escalation flow
19304
+ * (e.g. `TinyCloudWeb.requestPermissions`). Passing
19305
+ * `forceWalletSign: true` bypasses the derivability check and
19306
+ * always uses the wallet-signed SIWE path — used by the legacy
19307
+ * `createDelegation` fallback and by callers that want explicit
19308
+ * wallet confirmation.
19309
+ *
19310
+ * Multi-entry delegations are now emitted as **one** signed UCAN:
19311
+ * the underlying WASM `createDelegation` takes a full
19312
+ * `HashMap<Service, HashMap<Path, Vec<Ability>>>` abilities map
19313
+ * and produces a single attenuation carrying every
19314
+ * `(service, path, actions)` entry. The returned
19315
+ * {@link DelegateToResult.delegation} is that single blob, and
19316
+ * apps can POST it to their backend exactly like a single-entry
19317
+ * delegation (the server verifies all granted resources from one
19318
+ * UCAN).
19319
+ *
19320
+ * For single-entry requests the `PortableDelegation.path` and
19321
+ * `.actions` fields mirror the one granted entry. For
19322
+ * multi-entry requests they mirror the **first** entry (stable
19323
+ * lexicographic order from the Rust side); consumers that need
19324
+ * the full picture read `PortableDelegation.resources`.
19325
+ *
19326
+ * @throws {@link SessionExpiredError} when there is no session or
19327
+ * the current session has expired (or will within the 60s
19328
+ * safety margin).
19329
+ * @throws {@link PermissionNotInManifestError} when any requested
19330
+ * entry is not a subset of the granted session capabilities and
19331
+ * `forceWalletSign` is not set.
19332
+ */
19333
+ async delegateTo(did, permissions, options) {
19334
+ const session = this.auth?.tinyCloudSession;
19335
+ if (!session) {
19336
+ throw new import_sdk_core4.SessionExpiredError(/* @__PURE__ */ new Date(0));
19337
+ }
19338
+ const sessionExpiry = extractSiweExpiration(session.siwe);
19339
+ if (sessionExpiry !== void 0) {
19340
+ const now2 = Date.now();
19341
+ const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
19342
+ if (sessionExpiry.getTime() <= now2 + marginMs) {
19343
+ throw new import_sdk_core4.SessionExpiredError(sessionExpiry);
19344
+ }
19345
+ }
19346
+ if (!Array.isArray(permissions) || permissions.length === 0) {
19347
+ throw new Error(
19348
+ "delegateTo requires a non-empty permissions array"
19349
+ );
19350
+ }
19351
+ const expandedEntries = permissions.map((entry) => ({
19352
+ ...entry,
19353
+ actions: (0, import_sdk_core4.expandActionShortNames)(entry.service, entry.actions)
19354
+ }));
19355
+ const now = /* @__PURE__ */ new Date();
19356
+ const expiryMs = resolveExpiryMs(options?.expiry);
19357
+ const expirationTime = new Date(now.getTime() + expiryMs);
19358
+ let effectiveExpiration = expirationTime;
19359
+ if (sessionExpiry !== void 0 && sessionExpiry < expirationTime) {
19360
+ effectiveExpiration = sessionExpiry;
19361
+ }
19362
+ if (options?.forceWalletSign) {
19363
+ if (expandedEntries.length > 1) {
19364
+ throw new Error(
19365
+ "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."
19366
+ );
19367
+ }
19368
+ const delegation2 = await this.createDelegationLegacyWalletPath(
19369
+ did,
19370
+ expandedEntries[0],
19371
+ effectiveExpiration
19372
+ );
19373
+ return { delegation: delegation2, prompted: true };
19374
+ }
19375
+ const granted = (0, import_sdk_core4.parseRecapCapabilities)(
19376
+ (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
19377
+ session.siwe
19378
+ );
19379
+ const { subset, missing } = (0, import_sdk_core4.isCapabilitySubset)(expandedEntries, granted);
19380
+ if (!subset) {
19381
+ throw new import_sdk_core4.PermissionNotInManifestError(missing, granted);
19382
+ }
19383
+ const delegation = await this.createDelegationViaWasmPath(
19384
+ did,
19385
+ expandedEntries,
19386
+ effectiveExpiration,
19387
+ session
19388
+ );
19389
+ return { delegation, prompted: false };
19390
+ }
19391
+ /**
19392
+ * Issue a delegation via the session-key UCAN WASM path.
19393
+ *
19394
+ * The caller has already verified every entry is derivable from
19395
+ * the current session; we build one multi-resource abilities map
19396
+ * and emit one signed UCAN covering them all.
19397
+ *
19398
+ * All entries must share the same target space (the UCAN is
19399
+ * scoped to a single space). If they don't, this throws — mixing
19400
+ * spaces in a single delegation is not supported by the underlying
19401
+ * Rust create_delegation call and the resulting UCAN would be
19402
+ * under-specified.
19403
+ *
19404
+ * @internal
19405
+ */
19406
+ async createDelegationViaWasmPath(did, entries, expirationTime, session) {
19407
+ if (entries.length === 0) {
19408
+ throw new Error(
19409
+ "createDelegationViaWasmPath requires a non-empty entries array"
19410
+ );
19411
+ }
19412
+ const resolvedSpaces = /* @__PURE__ */ new Set();
19413
+ for (const entry of entries) {
19414
+ const spaceId2 = entry.space === "default" ? session.spaceId : entry.space;
19415
+ resolvedSpaces.add(spaceId2);
19416
+ }
19417
+ if (resolvedSpaces.size !== 1) {
19418
+ throw new Error(
19419
+ `delegateTo: all permission entries must target the same space, got ${resolvedSpaces.size}: ${JSON.stringify([...resolvedSpaces])}`
19420
+ );
19421
+ }
19422
+ const spaceId = [...resolvedSpaces][0];
19423
+ const abilities = {};
19424
+ for (const entry of entries) {
19425
+ const shortService = import_sdk_core4.SERVICE_LONG_TO_SHORT[entry.service];
19426
+ if (shortService === void 0) {
19427
+ throw new Error(
19428
+ `delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
19429
+ );
19430
+ }
19431
+ if (abilities[shortService] === void 0) {
19432
+ abilities[shortService] = {};
19433
+ }
19434
+ const pathsMap = abilities[shortService];
19435
+ const existing = pathsMap[entry.path];
19436
+ if (existing === void 0) {
19437
+ pathsMap[entry.path] = [...entry.actions];
19438
+ } else {
19439
+ const seen = new Set(existing);
19440
+ for (const action of entry.actions) {
19441
+ if (!seen.has(action)) {
19442
+ existing.push(action);
19443
+ seen.add(action);
19444
+ }
19445
+ }
19446
+ }
19447
+ }
19448
+ const serviceSession = {
19449
+ delegationHeader: session.delegationHeader,
19450
+ delegationCid: session.delegationCid,
19451
+ jwk: session.jwk,
19452
+ spaceId,
19453
+ verificationMethod: session.verificationMethod
19454
+ };
19455
+ const expirationSecs = Math.floor(expirationTime.getTime() / 1e3);
19456
+ const result = this.createDelegationWrapper({
19457
+ session: serviceSession,
19458
+ delegateDID: did,
19459
+ spaceId,
19460
+ abilities,
19461
+ expirationSecs
19462
+ });
19463
+ const primary = result.resources[0];
19464
+ return {
19465
+ cid: result.cid,
19466
+ delegationHeader: { Authorization: `Bearer ${result.delegation}` },
19467
+ spaceId,
19468
+ path: primary.path,
19469
+ actions: primary.actions,
19470
+ resources: result.resources,
19471
+ disableSubDelegation: false,
19472
+ expiry: result.expiry,
19473
+ delegateDID: did,
19474
+ ownerAddress: session.address,
19475
+ chainId: session.chainId,
19476
+ host: this.config.host
19477
+ };
19478
+ }
19479
+ /**
19480
+ * Issue a delegation via the legacy wallet-signed SIWE path for a single
19481
+ * {@link PermissionEntry}. Shares the implementation with the public
19482
+ * `createDelegation` method via {@link createDelegationWalletPath} so
19483
+ * both entry points hit exactly the same SIWE / signer / public-space
19484
+ * logic without mutual recursion.
19485
+ *
19486
+ * @internal
19487
+ */
19488
+ async createDelegationLegacyWalletPath(delegateDID, entry, expirationTime) {
19489
+ const spaceIdOverride = entry.space === "default" ? void 0 : entry.space;
19490
+ return this.createDelegationWalletPath({
19491
+ path: entry.path,
19492
+ actions: entry.actions,
19493
+ delegateDID,
19494
+ includePublicSpace: true,
19495
+ expiryMs: Math.max(0, expirationTime.getTime() - Date.now()),
19496
+ spaceIdOverride
19497
+ });
19498
+ }
19140
19499
  /**
19141
19500
  * Create a delegation from this user to another user.
19142
19501
  *
@@ -19147,6 +19506,49 @@ var TinyCloudNode = class _TinyCloudNode {
19147
19506
  * @returns A portable delegation that can be sent to the recipient
19148
19507
  */
19149
19508
  async createDelegation(params) {
19509
+ if (!this.signer) {
19510
+ throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
19511
+ }
19512
+ if (!this.auth?.tinyCloudSession) {
19513
+ throw new Error("Not signed in. Call signIn() first.");
19514
+ }
19515
+ let resolvedDelegateDID = params.delegateDID;
19516
+ if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
19517
+ const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
19518
+ if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
19519
+ resolvedDelegateDID = `did:pkh:eip155:1:${address}`;
19520
+ }
19521
+ const entries = legacyParamsToPermissionEntries(
19522
+ params.actions,
19523
+ params.path,
19524
+ params.spaceIdOverride
19525
+ );
19526
+ try {
19527
+ const result = await this.delegateTo(
19528
+ resolvedDelegateDID,
19529
+ entries,
19530
+ params.expiryMs !== void 0 ? { expiry: params.expiryMs } : void 0
19531
+ );
19532
+ return result.delegation;
19533
+ } catch (err) {
19534
+ if (err instanceof import_sdk_core4.PermissionNotInManifestError) {
19535
+ } else {
19536
+ throw err;
19537
+ }
19538
+ }
19539
+ return this.createDelegationWalletPath({
19540
+ ...params,
19541
+ delegateDID: resolvedDelegateDID
19542
+ });
19543
+ }
19544
+ /**
19545
+ * Legacy wallet-signed SIWE delegation path. Lifted from the original
19546
+ * `createDelegation` body verbatim so both the legacy public method and
19547
+ * `delegateTo({ forceWalletSign: true })` hit the same code.
19548
+ *
19549
+ * @internal
19550
+ */
19551
+ async createDelegationWalletPath(params) {
19150
19552
  if (!this.signer) {
19151
19553
  throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
19152
19554
  }
@@ -19154,11 +19556,6 @@ var TinyCloudNode = class _TinyCloudNode {
19154
19556
  if (!session) {
19155
19557
  throw new Error("Not signed in. Call signIn() first.");
19156
19558
  }
19157
- if (params.delegateDID.endsWith(".eth") && this.config.ensResolver) {
19158
- const address = await this.config.ensResolver.resolveAddress(params.delegateDID);
19159
- if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);
19160
- params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };
19161
- }
19162
19559
  const abilities = {};
19163
19560
  const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
19164
19561
  const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
@@ -19191,7 +19588,7 @@ var TinyCloudNode = class _TinyCloudNode {
19191
19588
  ...prepared,
19192
19589
  signature: signature2
19193
19590
  });
19194
- const activateResult = await (0, import_sdk_core3.activateSessionWithHost)(
19591
+ const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19195
19592
  this.config.host,
19196
19593
  delegationSession.delegationHeader
19197
19594
  );
@@ -19213,7 +19610,7 @@ var TinyCloudNode = class _TinyCloudNode {
19213
19610
  };
19214
19611
  const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
19215
19612
  if (hasKvActions && params.includePublicSpace !== false) {
19216
- const publicSpaceId = (0, import_sdk_core3.makePublicSpaceId)(
19613
+ const publicSpaceId = (0, import_sdk_core4.makePublicSpaceId)(
19217
19614
  this.wasmBindings.ensureEip55(session.address),
19218
19615
  session.chainId
19219
19616
  );
@@ -19236,7 +19633,7 @@ var TinyCloudNode = class _TinyCloudNode {
19236
19633
  ...publicPrepared,
19237
19634
  signature: publicSignature
19238
19635
  });
19239
- const publicActivateResult = await (0, import_sdk_core3.activateSessionWithHost)(
19636
+ const publicActivateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19240
19637
  this.config.host,
19241
19638
  publicSession.delegationHeader
19242
19639
  );
@@ -19335,7 +19732,7 @@ var TinyCloudNode = class _TinyCloudNode {
19335
19732
  ...prepared,
19336
19733
  signature: signature2
19337
19734
  });
19338
- const activateResult = await (0, import_sdk_core3.activateSessionWithHost)(
19735
+ const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19339
19736
  targetHost,
19340
19737
  invokerSession.delegationHeader
19341
19738
  );
@@ -19424,7 +19821,7 @@ var TinyCloudNode = class _TinyCloudNode {
19424
19821
  ...prepared,
19425
19822
  signature: signature2
19426
19823
  });
19427
- const activateResult = await (0, import_sdk_core3.activateSessionWithHost)(
19824
+ const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
19428
19825
  targetHost,
19429
19826
  subDelegationSession.delegationHeader
19430
19827
  );
@@ -19446,6 +19843,18 @@ var TinyCloudNode = class _TinyCloudNode {
19446
19843
  };
19447
19844
  }
19448
19845
  };
19846
+ // ===========================================================================
19847
+ // Capability-chain delegation (spec: .claude/specs/capability-chain.md)
19848
+ // ===========================================================================
19849
+ /**
19850
+ * Safety margin before the session's own expiry at which {@link delegateTo}
19851
+ * will refuse to issue a derived delegation. Prevents issuing sub-delegations
19852
+ * that would be invalid by the time the recipient used them. Spec: 60 seconds.
19853
+ *
19854
+ * @internal
19855
+ */
19856
+ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
19857
+ var TinyCloudNode = _TinyCloudNode;
19449
19858
 
19450
19859
  // src/nodeDefaults.ts
19451
19860
  TinyCloudNode.registerNodeDefaults({
@@ -19454,11 +19863,11 @@ TinyCloudNode.registerNodeDefaults({
19454
19863
  });
19455
19864
 
19456
19865
  // src/index.ts
19457
- var import_sdk_core5 = require("@tinycloud/sdk-core");
19458
19866
  var import_sdk_core6 = require("@tinycloud/sdk-core");
19867
+ var import_sdk_core7 = require("@tinycloud/sdk-core");
19459
19868
 
19460
19869
  // src/storage/FileSessionStorage.ts
19461
- var import_sdk_core4 = require("@tinycloud/sdk-core");
19870
+ var import_sdk_core5 = require("@tinycloud/sdk-core");
19462
19871
  var import_fs = require("fs");
19463
19872
  var import_path = require("path");
19464
19873
  var FileSessionStorage = class {
@@ -19513,7 +19922,7 @@ var FileSessionStorage = class {
19513
19922
  try {
19514
19923
  const data = (0, import_fs.readFileSync)(filePath, "utf-8");
19515
19924
  const parsed = JSON.parse(data);
19516
- const validation = (0, import_sdk_core4.validatePersistedSessionData)(parsed);
19925
+ const validation = (0, import_sdk_core5.validatePersistedSessionData)(parsed);
19517
19926
  if (!validation.ok) {
19518
19927
  console.warn(`Invalid session data for ${address}:`, validation.error.message);
19519
19928
  (0, import_fs.unlinkSync)(filePath);
@@ -19577,6 +19986,9 @@ var FileSessionStorage = class {
19577
19986
  }
19578
19987
  };
19579
19988
 
19989
+ // src/index.ts
19990
+ var import_sdk_core8 = require("@tinycloud/sdk-core");
19991
+
19580
19992
  // src/delegation.ts
19581
19993
  function serializeDelegation(delegation) {
19582
19994
  return JSON.stringify({
@@ -19594,8 +20006,6 @@ function deserializeDelegation(data) {
19594
20006
  }
19595
20007
 
19596
20008
  // src/index.ts
19597
- var import_sdk_core7 = require("@tinycloud/sdk-core");
19598
- var import_sdk_core8 = require("@tinycloud/sdk-core");
19599
20009
  var import_sdk_core9 = require("@tinycloud/sdk-core");
19600
20010
  var import_sdk_core10 = require("@tinycloud/sdk-core");
19601
20011
  var import_sdk_core11 = require("@tinycloud/sdk-core");
@@ -19604,6 +20014,8 @@ var import_sdk_core13 = require("@tinycloud/sdk-core");
19604
20014
  var import_sdk_core14 = require("@tinycloud/sdk-core");
19605
20015
  var import_sdk_core15 = require("@tinycloud/sdk-core");
19606
20016
  var import_sdk_core16 = require("@tinycloud/sdk-core");
20017
+ var import_sdk_core17 = require("@tinycloud/sdk-core");
20018
+ var import_sdk_core18 = require("@tinycloud/sdk-core");
19607
20019
  // Annotate the CommonJS export names for ESM import in node:
19608
20020
  0 && (module.exports = {
19609
20021
  AutoApproveSpaceCreationHandler,
@@ -19620,15 +20032,18 @@ var import_sdk_core16 = require("@tinycloud/sdk-core");
19620
20032
  FileSessionStorage,
19621
20033
  HooksService,
19622
20034
  KVService,
20035
+ ManifestValidationError,
19623
20036
  MemorySessionStorage,
19624
20037
  NodeUserAuthorization,
19625
20038
  NodeWasmBindings,
20039
+ PermissionNotInManifestError,
19626
20040
  PrefixedKVService,
19627
20041
  PrivateKeySigner,
19628
20042
  ProtocolMismatchError,
19629
20043
  SQLAction,
19630
20044
  SQLService,
19631
20045
  ServiceContext,
20046
+ SessionExpiredError,
19632
20047
  SharingService,
19633
20048
  SilentNotificationHandler,
19634
20049
  Space,
@@ -19651,9 +20066,15 @@ var import_sdk_core16 = require("@tinycloud/sdk-core");
19651
20066
  defaultSignStrategy,
19652
20067
  defaultSpaceCreationHandler,
19653
20068
  deserializeDelegation,
20069
+ expandActionShortNames,
20070
+ isCapabilitySubset,
20071
+ loadManifest,
19654
20072
  makePublicSpaceId,
20073
+ parseExpiry,
19655
20074
  parseSpaceUri,
19656
- serializeDelegation
20075
+ resolveManifest,
20076
+ serializeDelegation,
20077
+ validateManifest
19657
20078
  });
19658
20079
  /*! Bundled license information:
19659
20080