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

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.cjs CHANGED
@@ -20,55 +20,64 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/core.ts
21
21
  var core_exports = {};
22
22
  __export(core_exports, {
23
- AutoApproveSpaceCreationHandler: () => import_sdk_core6.AutoApproveSpaceCreationHandler,
24
- CapabilityKeyRegistry: () => import_sdk_core12.CapabilityKeyRegistry,
25
- CapabilityKeyRegistryErrorCodes: () => import_sdk_core12.CapabilityKeyRegistryErrorCodes,
26
- DataVaultService: () => import_sdk_core10.DataVaultService,
27
- DatabaseHandle: () => import_sdk_core8.DatabaseHandle,
23
+ AutoApproveSpaceCreationHandler: () => import_sdk_core7.AutoApproveSpaceCreationHandler,
24
+ CapabilityKeyRegistry: () => import_sdk_core14.CapabilityKeyRegistry,
25
+ CapabilityKeyRegistryErrorCodes: () => import_sdk_core14.CapabilityKeyRegistryErrorCodes,
26
+ DataVaultService: () => import_sdk_core12.DataVaultService,
27
+ DatabaseHandle: () => import_sdk_core10.DatabaseHandle,
28
28
  DelegatedAccess: () => DelegatedAccess,
29
- DelegationErrorCodes: () => import_sdk_core11.DelegationErrorCodes,
30
- DelegationManager: () => import_sdk_core11.DelegationManager,
31
- DuckDbAction: () => import_sdk_core9.DuckDbAction,
32
- DuckDbDatabaseHandle: () => import_sdk_core9.DuckDbDatabaseHandle,
33
- DuckDbService: () => import_sdk_core9.DuckDbService,
29
+ DelegationErrorCodes: () => import_sdk_core13.DelegationErrorCodes,
30
+ DelegationManager: () => import_sdk_core13.DelegationManager,
31
+ DuckDbAction: () => import_sdk_core11.DuckDbAction,
32
+ DuckDbDatabaseHandle: () => import_sdk_core11.DuckDbDatabaseHandle,
33
+ DuckDbService: () => import_sdk_core11.DuckDbService,
34
34
  FileSessionStorage: () => FileSessionStorage,
35
- KVService: () => import_sdk_core7.KVService,
35
+ KVService: () => import_sdk_core9.KVService,
36
+ ManifestValidationError: () => import_sdk_core8.ManifestValidationError,
36
37
  MemorySessionStorage: () => MemorySessionStorage,
37
38
  NodeUserAuthorization: () => NodeUserAuthorization,
38
- PrefixedKVService: () => import_sdk_core7.PrefixedKVService,
39
- ProtocolMismatchError: () => import_sdk_core14.ProtocolMismatchError,
40
- SQLAction: () => import_sdk_core8.SQLAction,
41
- SQLService: () => import_sdk_core8.SQLService,
42
- ServiceContext: () => import_sdk_core15.ServiceContext,
43
- SharingService: () => import_sdk_core11.SharingService,
44
- SilentNotificationHandler: () => import_sdk_core6.SilentNotificationHandler,
45
- Space: () => import_sdk_core13.Space,
46
- SpaceErrorCodes: () => import_sdk_core13.SpaceErrorCodes,
47
- SpaceService: () => import_sdk_core13.SpaceService,
48
- TinyCloud: () => import_sdk_core5.TinyCloud,
39
+ PermissionNotInManifestError: () => import_sdk_core8.PermissionNotInManifestError,
40
+ PrefixedKVService: () => import_sdk_core9.PrefixedKVService,
41
+ ProtocolMismatchError: () => import_sdk_core16.ProtocolMismatchError,
42
+ SQLAction: () => import_sdk_core10.SQLAction,
43
+ SQLService: () => import_sdk_core10.SQLService,
44
+ ServiceContext: () => import_sdk_core17.ServiceContext,
45
+ SessionExpiredError: () => import_sdk_core8.SessionExpiredError,
46
+ SharingService: () => import_sdk_core13.SharingService,
47
+ SilentNotificationHandler: () => import_sdk_core7.SilentNotificationHandler,
48
+ Space: () => import_sdk_core15.Space,
49
+ SpaceErrorCodes: () => import_sdk_core15.SpaceErrorCodes,
50
+ SpaceService: () => import_sdk_core15.SpaceService,
51
+ TinyCloud: () => import_sdk_core6.TinyCloud,
49
52
  TinyCloudNode: () => TinyCloudNode,
50
- UnsupportedFeatureError: () => import_sdk_core14.UnsupportedFeatureError,
51
- VaultHeaders: () => import_sdk_core10.VaultHeaders,
52
- VaultPublicSpaceKVActions: () => import_sdk_core10.VaultPublicSpaceKVActions,
53
- VersionCheckError: () => import_sdk_core14.VersionCheckError,
53
+ UnsupportedFeatureError: () => import_sdk_core16.UnsupportedFeatureError,
54
+ VaultHeaders: () => import_sdk_core12.VaultHeaders,
55
+ VaultPublicSpaceKVActions: () => import_sdk_core12.VaultPublicSpaceKVActions,
56
+ VersionCheckError: () => import_sdk_core16.VersionCheckError,
54
57
  WasmKeyProvider: () => WasmKeyProvider,
55
- buildSpaceUri: () => import_sdk_core13.buildSpaceUri,
56
- checkNodeInfo: () => import_sdk_core14.checkNodeInfo,
57
- createCapabilityKeyRegistry: () => import_sdk_core12.createCapabilityKeyRegistry,
58
- createSharingService: () => import_sdk_core11.createSharingService,
59
- createSpaceService: () => import_sdk_core13.createSpaceService,
60
- createVaultCrypto: () => import_sdk_core10.createVaultCrypto,
58
+ buildSpaceUri: () => import_sdk_core15.buildSpaceUri,
59
+ checkNodeInfo: () => import_sdk_core16.checkNodeInfo,
60
+ createCapabilityKeyRegistry: () => import_sdk_core14.createCapabilityKeyRegistry,
61
+ createSharingService: () => import_sdk_core13.createSharingService,
62
+ createSpaceService: () => import_sdk_core15.createSpaceService,
63
+ createVaultCrypto: () => import_sdk_core12.createVaultCrypto,
61
64
  createWasmKeyProvider: () => createWasmKeyProvider,
62
65
  defaultSignStrategy: () => defaultSignStrategy,
63
- defaultSpaceCreationHandler: () => import_sdk_core6.defaultSpaceCreationHandler,
66
+ defaultSpaceCreationHandler: () => import_sdk_core7.defaultSpaceCreationHandler,
64
67
  deserializeDelegation: () => deserializeDelegation,
65
- makePublicSpaceId: () => import_sdk_core13.makePublicSpaceId,
66
- parseSpaceUri: () => import_sdk_core13.parseSpaceUri,
67
- serializeDelegation: () => serializeDelegation
68
+ expandActionShortNames: () => import_sdk_core8.expandActionShortNames,
69
+ isCapabilitySubset: () => import_sdk_core8.isCapabilitySubset,
70
+ loadManifest: () => import_sdk_core8.loadManifest,
71
+ makePublicSpaceId: () => import_sdk_core15.makePublicSpaceId,
72
+ parseExpiry: () => import_sdk_core8.parseExpiry,
73
+ parseSpaceUri: () => import_sdk_core15.parseSpaceUri,
74
+ resolveManifest: () => import_sdk_core8.resolveManifest,
75
+ serializeDelegation: () => serializeDelegation,
76
+ validateManifest: () => import_sdk_core8.validateManifest
68
77
  });
69
78
  module.exports = __toCommonJS(core_exports);
70
- var import_sdk_core5 = require("@tinycloud/sdk-core");
71
79
  var import_sdk_core6 = require("@tinycloud/sdk-core");
80
+ var import_sdk_core7 = require("@tinycloud/sdk-core");
72
81
 
73
82
  // src/storage/MemorySessionStorage.ts
74
83
  var MemorySessionStorage = class {
@@ -862,7 +871,7 @@ var NodeUserAuthorization = class {
862
871
  };
863
872
 
864
873
  // src/TinyCloudNode.ts
865
- var import_sdk_core4 = require("@tinycloud/sdk-core");
874
+ var import_sdk_core5 = require("@tinycloud/sdk-core");
866
875
 
867
876
  // src/DelegatedAccess.ts
868
877
  var import_sdk_core3 = require("@tinycloud/sdk-core");
@@ -1017,9 +1026,69 @@ function createWasmKeyProvider(sessionManager) {
1017
1026
  return new WasmKeyProvider({ sessionManager });
1018
1027
  }
1019
1028
 
1029
+ // src/delegateToHelpers.ts
1030
+ var import_sdk_core4 = require("@tinycloud/sdk-core");
1031
+ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
1032
+ const byService = /* @__PURE__ */ new Map();
1033
+ for (const a of actions) {
1034
+ const slashIdx = a.indexOf("/");
1035
+ if (slashIdx === -1) {
1036
+ continue;
1037
+ }
1038
+ const service = a.slice(0, slashIdx);
1039
+ if (!service.startsWith("tinycloud.")) {
1040
+ continue;
1041
+ }
1042
+ const list = byService.get(service);
1043
+ if (list === void 0) {
1044
+ byService.set(service, [a]);
1045
+ } else {
1046
+ list.push(a);
1047
+ }
1048
+ }
1049
+ const space = spaceIdOverride ?? "default";
1050
+ const entries = [];
1051
+ for (const [service, actionList] of byService) {
1052
+ entries.push({
1053
+ service,
1054
+ space,
1055
+ path,
1056
+ actions: actionList
1057
+ });
1058
+ }
1059
+ return entries;
1060
+ }
1061
+ function resolveExpiryMs(expiry) {
1062
+ if (expiry === void 0) {
1063
+ return 60 * 60 * 1e3;
1064
+ }
1065
+ if (typeof expiry === "number") {
1066
+ if (!Number.isFinite(expiry) || expiry <= 0) {
1067
+ throw new Error(
1068
+ `delegateTo expiry must be a positive finite number (got ${expiry})`
1069
+ );
1070
+ }
1071
+ return expiry;
1072
+ }
1073
+ return (0, import_sdk_core4.parseExpiry)(expiry);
1074
+ }
1075
+ function extractSiweExpiration(siwe) {
1076
+ const parsed = new import_sdk_core4.SiweMessage(siwe);
1077
+ if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
1078
+ return void 0;
1079
+ }
1080
+ const d = new Date(parsed.expirationTime);
1081
+ if (Number.isNaN(d.getTime())) {
1082
+ throw new Error(
1083
+ `Session SIWE has unparseable expirationTime: ${parsed.expirationTime}`
1084
+ );
1085
+ }
1086
+ return d;
1087
+ }
1088
+
1020
1089
  // src/TinyCloudNode.ts
1021
1090
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
1022
- var TinyCloudNode = class _TinyCloudNode {
1091
+ var _TinyCloudNode = class _TinyCloudNode {
1023
1092
  /**
1024
1093
  * Create a new TinyCloudNode instance.
1025
1094
  *
@@ -1074,12 +1143,12 @@ var TinyCloudNode = class _TinyCloudNode {
1074
1143
  throw new Error("Failed to get session key JWK");
1075
1144
  }
1076
1145
  this.sessionKeyJwk = JSON.parse(jwkStr);
1077
- this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
1146
+ this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
1078
1147
  this._keyProvider = new WasmKeyProvider({
1079
1148
  sessionManager: this.sessionManager
1080
1149
  });
1081
- this.notificationHandler = config.notificationHandler ?? new import_sdk_core4.SilentNotificationHandler();
1082
- this._sharingService = new import_sdk_core4.SharingService({
1150
+ this.notificationHandler = config.notificationHandler ?? new import_sdk_core5.SilentNotificationHandler();
1151
+ this._sharingService = new import_sdk_core5.SharingService({
1083
1152
  hosts: [this.config.host],
1084
1153
  // session: undefined - not needed for receive()
1085
1154
  invoke: this.wasmBindings.invoke,
@@ -1089,8 +1158,8 @@ var TinyCloudNode = class _TinyCloudNode {
1089
1158
  // delegationManager: undefined - not needed for receive()
1090
1159
  createKVService: (config2) => {
1091
1160
  const prefix = config2.pathPrefix?.replace(/\/$/, "");
1092
- const kvService = new import_sdk_core4.KVService({ prefix });
1093
- const kvContext = new import_sdk_core4.ServiceContext({
1161
+ const kvService = new import_sdk_core5.KVService({ prefix });
1162
+ const kvContext = new import_sdk_core5.ServiceContext({
1094
1163
  invoke: config2.invoke,
1095
1164
  fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
1096
1165
  hosts: config2.hosts
@@ -1145,7 +1214,7 @@ var TinyCloudNode = class _TinyCloudNode {
1145
1214
  nonce: config.nonce,
1146
1215
  siweConfig: config.siweConfig
1147
1216
  });
1148
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
1217
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
1149
1218
  invokeAny: this.wasmBindings.invokeAny
1150
1219
  });
1151
1220
  }
@@ -1244,22 +1313,22 @@ var TinyCloudNode = class _TinyCloudNode {
1244
1313
  if (sessionData.chainId) {
1245
1314
  this._chainId = sessionData.chainId;
1246
1315
  }
1247
- this._serviceContext = new import_sdk_core4.ServiceContext({
1316
+ this._serviceContext = new import_sdk_core5.ServiceContext({
1248
1317
  invoke: this.wasmBindings.invoke,
1249
1318
  invokeAny: this.wasmBindings.invokeAny,
1250
1319
  fetch: globalThis.fetch.bind(globalThis),
1251
1320
  hosts: [this.config.host]
1252
1321
  });
1253
- this._kv = new import_sdk_core4.KVService({});
1322
+ this._kv = new import_sdk_core5.KVService({});
1254
1323
  this._kv.initialize(this._serviceContext);
1255
1324
  this._serviceContext.registerService("kv", this._kv);
1256
- this._sql = new import_sdk_core4.SQLService({});
1325
+ this._sql = new import_sdk_core5.SQLService({});
1257
1326
  this._sql.initialize(this._serviceContext);
1258
1327
  this._serviceContext.registerService("sql", this._sql);
1259
- this._duckdb = new import_sdk_core4.DuckDbService({});
1328
+ this._duckdb = new import_sdk_core5.DuckDbService({});
1260
1329
  this._duckdb.initialize(this._serviceContext);
1261
1330
  this._serviceContext.registerService("duckdb", this._duckdb);
1262
- this._hooks = new import_sdk_core4.HooksService({});
1331
+ this._hooks = new import_sdk_core5.HooksService({});
1263
1332
  this._hooks.initialize(this._serviceContext);
1264
1333
  this._serviceContext.registerService("hooks", this._hooks);
1265
1334
  const serviceSession = {
@@ -1271,7 +1340,7 @@ var TinyCloudNode = class _TinyCloudNode {
1271
1340
  };
1272
1341
  this._serviceContext.setSession(serviceSession);
1273
1342
  const wasm = this.wasmBindings;
1274
- const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
1343
+ const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
1275
1344
  vault_encrypt: wasm.vault_encrypt,
1276
1345
  vault_decrypt: wasm.vault_decrypt,
1277
1346
  vault_derive_key: wasm.vault_derive_key,
@@ -1281,7 +1350,7 @@ var TinyCloudNode = class _TinyCloudNode {
1281
1350
  vault_sha256: wasm.vault_sha256
1282
1351
  });
1283
1352
  const self = this;
1284
- this._vault = new import_sdk_core4.DataVaultService({
1353
+ this._vault = new import_sdk_core5.DataVaultService({
1285
1354
  spaceId: sessionData.spaceId,
1286
1355
  crypto: vaultCrypto,
1287
1356
  tc: {
@@ -1297,8 +1366,8 @@ var TinyCloudNode = class _TinyCloudNode {
1297
1366
  get publicKV() {
1298
1367
  return self._publicKV ?? self.tc.publicKV;
1299
1368
  },
1300
- readPublicSpace: (host, spaceId, key) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key),
1301
- makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
1369
+ readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
1370
+ makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
1302
1371
  did: this.did,
1303
1372
  address: sessionData.address ?? this._address ?? "",
1304
1373
  chainId: sessionData.chainId ?? this._chainId,
@@ -1361,7 +1430,7 @@ var TinyCloudNode = class _TinyCloudNode {
1361
1430
  nonce: this.config.nonce,
1362
1431
  siweConfig: this.config.siweConfig
1363
1432
  });
1364
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
1433
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
1365
1434
  invokeAny: this.wasmBindings.invokeAny
1366
1435
  });
1367
1436
  this.config.prefix = prefix;
@@ -1401,7 +1470,7 @@ var TinyCloudNode = class _TinyCloudNode {
1401
1470
  nonce: this.config.nonce,
1402
1471
  siweConfig: this.config.siweConfig
1403
1472
  });
1404
- this.tc = new import_sdk_core4.TinyCloud(this.auth, {
1473
+ this.tc = new import_sdk_core5.TinyCloud(this.auth, {
1405
1474
  invokeAny: this.wasmBindings.invokeAny
1406
1475
  });
1407
1476
  this.config.prefix = prefix;
@@ -1416,27 +1485,27 @@ var TinyCloudNode = class _TinyCloudNode {
1416
1485
  return;
1417
1486
  }
1418
1487
  this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
1419
- this._serviceContext = new import_sdk_core4.ServiceContext({
1488
+ this._serviceContext = new import_sdk_core5.ServiceContext({
1420
1489
  invoke: this.wasmBindings.invoke,
1421
1490
  invokeAny: this.wasmBindings.invokeAny,
1422
1491
  fetch: globalThis.fetch.bind(globalThis),
1423
1492
  hosts: [this.config.host]
1424
1493
  });
1425
- this._kv = new import_sdk_core4.KVService({});
1494
+ this._kv = new import_sdk_core5.KVService({});
1426
1495
  this._kv.initialize(this._serviceContext);
1427
1496
  this._serviceContext.registerService("kv", this._kv);
1428
1497
  const features = this.nodeFeatures;
1429
1498
  if (features.length === 0 || features.includes("sql")) {
1430
- this._sql = new import_sdk_core4.SQLService({});
1499
+ this._sql = new import_sdk_core5.SQLService({});
1431
1500
  this._sql.initialize(this._serviceContext);
1432
1501
  this._serviceContext.registerService("sql", this._sql);
1433
1502
  }
1434
1503
  if (features.length === 0 || features.includes("duckdb")) {
1435
- this._duckdb = new import_sdk_core4.DuckDbService({});
1504
+ this._duckdb = new import_sdk_core5.DuckDbService({});
1436
1505
  this._duckdb.initialize(this._serviceContext);
1437
1506
  this._serviceContext.registerService("duckdb", this._duckdb);
1438
1507
  }
1439
- this._hooks = new import_sdk_core4.HooksService({});
1508
+ this._hooks = new import_sdk_core5.HooksService({});
1440
1509
  this._hooks.initialize(this._serviceContext);
1441
1510
  this._serviceContext.registerService("hooks", this._hooks);
1442
1511
  const serviceSession = {
@@ -1449,7 +1518,7 @@ var TinyCloudNode = class _TinyCloudNode {
1449
1518
  this._serviceContext.setSession(serviceSession);
1450
1519
  this.tc.serviceContext.setSession(serviceSession);
1451
1520
  const wasm = this.wasmBindings;
1452
- const vaultCrypto = (0, import_sdk_core4.createVaultCrypto)({
1521
+ const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
1453
1522
  vault_encrypt: wasm.vault_encrypt,
1454
1523
  vault_decrypt: wasm.vault_decrypt,
1455
1524
  vault_derive_key: wasm.vault_derive_key,
@@ -1459,7 +1528,7 @@ var TinyCloudNode = class _TinyCloudNode {
1459
1528
  vault_sha256: wasm.vault_sha256
1460
1529
  });
1461
1530
  const self = this;
1462
- this._vault = new import_sdk_core4.DataVaultService({
1531
+ this._vault = new import_sdk_core5.DataVaultService({
1463
1532
  spaceId: session.spaceId,
1464
1533
  crypto: vaultCrypto,
1465
1534
  tc: {
@@ -1475,8 +1544,8 @@ var TinyCloudNode = class _TinyCloudNode {
1475
1544
  get publicKV() {
1476
1545
  return self._publicKV ?? self.tc.publicKV;
1477
1546
  },
1478
- readPublicSpace: (host, spaceId, key) => import_sdk_core4.TinyCloud.readPublicSpace(host, spaceId, key),
1479
- makePublicSpaceId: import_sdk_core4.TinyCloud.makePublicSpaceId,
1547
+ readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
1548
+ makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
1480
1549
  did: this.did,
1481
1550
  address: this._address,
1482
1551
  chainId: this._chainId,
@@ -1492,7 +1561,7 @@ var TinyCloudNode = class _TinyCloudNode {
1492
1561
  * @internal
1493
1562
  */
1494
1563
  initializeV2Services(serviceSession) {
1495
- this._capabilityRegistry = new import_sdk_core4.CapabilityKeyRegistry();
1564
+ this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
1496
1565
  const tcSession = this.auth?.tinyCloudSession;
1497
1566
  if (tcSession && this._address) {
1498
1567
  const sessionKey = {
@@ -1566,13 +1635,13 @@ var TinyCloudNode = class _TinyCloudNode {
1566
1635
  }
1567
1636
  this._capabilityRegistry.registerKey(sessionKey, delegations);
1568
1637
  }
1569
- this._delegationManager = new import_sdk_core4.DelegationManager({
1638
+ this._delegationManager = new import_sdk_core5.DelegationManager({
1570
1639
  hosts: [this.config.host],
1571
1640
  session: serviceSession,
1572
1641
  invoke: this.wasmBindings.invoke,
1573
1642
  fetch: globalThis.fetch.bind(globalThis)
1574
1643
  });
1575
- this._spaceService = new import_sdk_core4.SpaceService({
1644
+ this._spaceService = new import_sdk_core5.SpaceService({
1576
1645
  hosts: [this.config.host],
1577
1646
  session: serviceSession,
1578
1647
  invoke: this.wasmBindings.invoke,
@@ -1580,9 +1649,9 @@ var TinyCloudNode = class _TinyCloudNode {
1580
1649
  capabilityRegistry: this._capabilityRegistry,
1581
1650
  userDid: this.did,
1582
1651
  createKVService: (spaceId) => {
1583
- const kvService = new import_sdk_core4.KVService({});
1652
+ const kvService = new import_sdk_core5.KVService({});
1584
1653
  if (this._serviceContext) {
1585
- const spaceScopedContext = new import_sdk_core4.ServiceContext({
1654
+ const spaceScopedContext = new import_sdk_core5.ServiceContext({
1586
1655
  invoke: this._serviceContext.invoke,
1587
1656
  fetch: this._serviceContext.fetch,
1588
1657
  hosts: this._serviceContext.hosts
@@ -1721,7 +1790,7 @@ var TinyCloudNode = class _TinyCloudNode {
1721
1790
  ...prepared,
1722
1791
  signature
1723
1792
  });
1724
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
1793
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
1725
1794
  host,
1726
1795
  delegationSession.delegationHeader
1727
1796
  );
@@ -1788,7 +1857,7 @@ var TinyCloudNode = class _TinyCloudNode {
1788
1857
  if (!this._sql) {
1789
1858
  const features = this.nodeFeatures;
1790
1859
  if (features.length > 0 && !features.includes("sql")) {
1791
- throw new import_sdk_core4.UnsupportedFeatureError("sql", this.config.host, features);
1860
+ throw new import_sdk_core5.UnsupportedFeatureError("sql", this.config.host, features);
1792
1861
  }
1793
1862
  throw new Error("Not signed in. Call signIn() first.");
1794
1863
  }
@@ -1801,7 +1870,7 @@ var TinyCloudNode = class _TinyCloudNode {
1801
1870
  if (!this._duckdb) {
1802
1871
  const features = this.nodeFeatures;
1803
1872
  if (features.length > 0 && !features.includes("duckdb")) {
1804
- throw new import_sdk_core4.UnsupportedFeatureError("duckdb", this.config.host, features);
1873
+ throw new import_sdk_core5.UnsupportedFeatureError("duckdb", this.config.host, features);
1805
1874
  }
1806
1875
  throw new Error("Not signed in. Call signIn() first.");
1807
1876
  }
@@ -2040,7 +2109,7 @@ var TinyCloudNode = class _TinyCloudNode {
2040
2109
  ...prepared,
2041
2110
  signature
2042
2111
  });
2043
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
2112
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
2044
2113
  this.config.host,
2045
2114
  delegationSession.delegationHeader
2046
2115
  );
@@ -2067,8 +2136,8 @@ var TinyCloudNode = class _TinyCloudNode {
2067
2136
  }]);
2068
2137
  }
2069
2138
  if (this._serviceContext) {
2070
- const publicKV = new import_sdk_core4.KVService({ prefix: "" });
2071
- const publicContext = new import_sdk_core4.ServiceContext({
2139
+ const publicKV = new import_sdk_core5.KVService({ prefix: "" });
2140
+ const publicContext = new import_sdk_core5.ServiceContext({
2072
2141
  invoke: this.wasmBindings.invoke,
2073
2142
  fetch: this._serviceContext.fetch,
2074
2143
  hosts: this._serviceContext.hosts
@@ -2153,6 +2222,150 @@ var TinyCloudNode = class _TinyCloudNode {
2153
2222
  async checkPermission(path, action) {
2154
2223
  return this.delegationManager.checkPermission(path, action);
2155
2224
  }
2225
+ /**
2226
+ * Issue a delegation using the capability-chain flow.
2227
+ *
2228
+ * When the requested permissions are a subset of the current session's
2229
+ * recap, the delegation is signed by the session key via WASM — no wallet
2230
+ * prompt. When they are not, a {@link PermissionNotInManifestError} is
2231
+ * raised so the caller can trigger an escalation flow (e.g.
2232
+ * `TinyCloudWeb.requestPermissions`). Passing `forceWalletSign: true`
2233
+ * bypasses the derivability check and always uses the wallet-signed SIWE
2234
+ * path — used by the legacy `createDelegation` fallback and by callers
2235
+ * that want explicit wallet confirmation.
2236
+ *
2237
+ * Current limitation: exactly one {@link PermissionEntry} per call. For
2238
+ * multi-resource delegation, call `delegateTo` multiple times. This keeps
2239
+ * each delegation a single `(spaceId, path)` grant, which matches the
2240
+ * underlying `PortableDelegation` shape.
2241
+ *
2242
+ * @throws {@link SessionExpiredError} when there is no session or the
2243
+ * current session has expired (or will within the 60s safety margin).
2244
+ * @throws {@link PermissionNotInManifestError} when the requested entries
2245
+ * are not a subset of the granted session capabilities and
2246
+ * `forceWalletSign` is not set.
2247
+ */
2248
+ async delegateTo(did, permissions, options) {
2249
+ const session = this.auth?.tinyCloudSession;
2250
+ if (!session) {
2251
+ throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
2252
+ }
2253
+ const sessionExpiry = extractSiweExpiration(session.siwe);
2254
+ if (sessionExpiry !== void 0) {
2255
+ const now2 = Date.now();
2256
+ const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
2257
+ if (sessionExpiry.getTime() <= now2 + marginMs) {
2258
+ throw new import_sdk_core5.SessionExpiredError(sessionExpiry);
2259
+ }
2260
+ }
2261
+ if (!Array.isArray(permissions) || permissions.length === 0) {
2262
+ throw new Error(
2263
+ "delegateTo requires a non-empty permissions array"
2264
+ );
2265
+ }
2266
+ if (permissions.length > 1) {
2267
+ throw new Error(
2268
+ "delegateTo currently supports one permission entry per call. Call delegateTo multiple times for multi-resource delegation."
2269
+ );
2270
+ }
2271
+ const entry = permissions[0];
2272
+ const expandedEntry = {
2273
+ ...entry,
2274
+ actions: (0, import_sdk_core5.expandActionShortNames)(entry.service, entry.actions)
2275
+ };
2276
+ const now = /* @__PURE__ */ new Date();
2277
+ const expiryMs = resolveExpiryMs(options?.expiry);
2278
+ const expirationTime = new Date(now.getTime() + expiryMs);
2279
+ let effectiveExpiration = expirationTime;
2280
+ if (sessionExpiry !== void 0 && sessionExpiry < expirationTime) {
2281
+ effectiveExpiration = sessionExpiry;
2282
+ }
2283
+ if (options?.forceWalletSign) {
2284
+ const delegation2 = await this.createDelegationLegacyWalletPath(
2285
+ did,
2286
+ expandedEntry,
2287
+ effectiveExpiration
2288
+ );
2289
+ return { delegation: delegation2, prompted: true };
2290
+ }
2291
+ const granted = (0, import_sdk_core5.parseRecapCapabilities)(
2292
+ (siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
2293
+ session.siwe
2294
+ );
2295
+ const requested = [expandedEntry];
2296
+ const { subset, missing } = (0, import_sdk_core5.isCapabilitySubset)(requested, granted);
2297
+ if (!subset) {
2298
+ throw new import_sdk_core5.PermissionNotInManifestError(missing, granted);
2299
+ }
2300
+ const delegation = await this.createDelegationViaWasmPath(
2301
+ did,
2302
+ expandedEntry,
2303
+ effectiveExpiration,
2304
+ session
2305
+ );
2306
+ return { delegation, prompted: false };
2307
+ }
2308
+ /**
2309
+ * Issue a delegation via the session-key UCAN WASM path.
2310
+ *
2311
+ * The caller has already verified the request is derivable from the
2312
+ * current session; we just need to shape the inputs for
2313
+ * {@link createDelegationWrapper}.
2314
+ *
2315
+ * @internal
2316
+ */
2317
+ async createDelegationViaWasmPath(did, entry, expirationTime, session) {
2318
+ const spaceId = entry.space === "default" ? session.spaceId : entry.space;
2319
+ const serviceSession = {
2320
+ delegationHeader: session.delegationHeader,
2321
+ delegationCid: session.delegationCid,
2322
+ jwk: session.jwk,
2323
+ spaceId,
2324
+ verificationMethod: session.verificationMethod
2325
+ };
2326
+ const expirationSecs = Math.floor(expirationTime.getTime() / 1e3);
2327
+ const result = this.createDelegationWrapper({
2328
+ session: serviceSession,
2329
+ delegateDID: did,
2330
+ spaceId,
2331
+ path: entry.path,
2332
+ actions: entry.actions,
2333
+ expirationSecs
2334
+ });
2335
+ return {
2336
+ cid: result.cid,
2337
+ delegationHeader: { Authorization: `Bearer ${result.delegation}` },
2338
+ spaceId,
2339
+ path: entry.path,
2340
+ actions: entry.actions,
2341
+ disableSubDelegation: false,
2342
+ expiry: result.expiry,
2343
+ delegateDID: did,
2344
+ ownerAddress: session.address,
2345
+ chainId: session.chainId,
2346
+ host: this.config.host
2347
+ };
2348
+ }
2349
+ /**
2350
+ * Issue a delegation via the legacy wallet-signed SIWE path for a single
2351
+ * {@link PermissionEntry}. Shares the implementation with the public
2352
+ * `createDelegation` method via {@link createDelegationWalletPath} so
2353
+ * both entry points hit exactly the same SIWE / signer / public-space
2354
+ * logic without mutual recursion.
2355
+ *
2356
+ * @internal
2357
+ */
2358
+ async createDelegationLegacyWalletPath(delegateDID, entry, expirationTime) {
2359
+ const spaceIdOverride = entry.space === "default" ? void 0 : entry.space;
2360
+ return this.createDelegationWalletPath({
2361
+ path: entry.path,
2362
+ actions: entry.actions,
2363
+ delegateDID,
2364
+ includePublicSpace: true,
2365
+ expiryMs: Math.max(0, expirationTime.getTime() - Date.now()),
2366
+ spaceIdOverride
2367
+ });
2368
+ }
2156
2369
  /**
2157
2370
  * Create a delegation from this user to another user.
2158
2371
  *
@@ -2163,6 +2376,51 @@ var TinyCloudNode = class _TinyCloudNode {
2163
2376
  * @returns A portable delegation that can be sent to the recipient
2164
2377
  */
2165
2378
  async createDelegation(params) {
2379
+ if (!this.signer) {
2380
+ throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
2381
+ }
2382
+ if (!this.auth?.tinyCloudSession) {
2383
+ throw new Error("Not signed in. Call signIn() first.");
2384
+ }
2385
+ let resolvedDelegateDID = params.delegateDID;
2386
+ if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
2387
+ const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
2388
+ if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
2389
+ resolvedDelegateDID = `did:pkh:eip155:1:${address}`;
2390
+ }
2391
+ const entries = legacyParamsToPermissionEntries(
2392
+ params.actions,
2393
+ params.path,
2394
+ params.spaceIdOverride
2395
+ );
2396
+ if (entries.length === 1) {
2397
+ try {
2398
+ const result = await this.delegateTo(
2399
+ resolvedDelegateDID,
2400
+ [entries[0]],
2401
+ params.expiryMs !== void 0 ? { expiry: params.expiryMs } : void 0
2402
+ );
2403
+ return result.delegation;
2404
+ } catch (err) {
2405
+ if (err instanceof import_sdk_core5.PermissionNotInManifestError) {
2406
+ } else {
2407
+ throw err;
2408
+ }
2409
+ }
2410
+ }
2411
+ return this.createDelegationWalletPath({
2412
+ ...params,
2413
+ delegateDID: resolvedDelegateDID
2414
+ });
2415
+ }
2416
+ /**
2417
+ * Legacy wallet-signed SIWE delegation path. Lifted from the original
2418
+ * `createDelegation` body verbatim so both the legacy public method and
2419
+ * `delegateTo({ forceWalletSign: true })` hit the same code.
2420
+ *
2421
+ * @internal
2422
+ */
2423
+ async createDelegationWalletPath(params) {
2166
2424
  if (!this.signer) {
2167
2425
  throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
2168
2426
  }
@@ -2170,11 +2428,6 @@ var TinyCloudNode = class _TinyCloudNode {
2170
2428
  if (!session) {
2171
2429
  throw new Error("Not signed in. Call signIn() first.");
2172
2430
  }
2173
- if (params.delegateDID.endsWith(".eth") && this.config.ensResolver) {
2174
- const address = await this.config.ensResolver.resolveAddress(params.delegateDID);
2175
- if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);
2176
- params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };
2177
- }
2178
2431
  const abilities = {};
2179
2432
  const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
2180
2433
  const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
@@ -2207,7 +2460,7 @@ var TinyCloudNode = class _TinyCloudNode {
2207
2460
  ...prepared,
2208
2461
  signature
2209
2462
  });
2210
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
2463
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
2211
2464
  this.config.host,
2212
2465
  delegationSession.delegationHeader
2213
2466
  );
@@ -2229,7 +2482,7 @@ var TinyCloudNode = class _TinyCloudNode {
2229
2482
  };
2230
2483
  const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
2231
2484
  if (hasKvActions && params.includePublicSpace !== false) {
2232
- const publicSpaceId = (0, import_sdk_core4.makePublicSpaceId)(
2485
+ const publicSpaceId = (0, import_sdk_core5.makePublicSpaceId)(
2233
2486
  this.wasmBindings.ensureEip55(session.address),
2234
2487
  session.chainId
2235
2488
  );
@@ -2252,7 +2505,7 @@ var TinyCloudNode = class _TinyCloudNode {
2252
2505
  ...publicPrepared,
2253
2506
  signature: publicSignature
2254
2507
  });
2255
- const publicActivateResult = await (0, import_sdk_core4.activateSessionWithHost)(
2508
+ const publicActivateResult = await (0, import_sdk_core5.activateSessionWithHost)(
2256
2509
  this.config.host,
2257
2510
  publicSession.delegationHeader
2258
2511
  );
@@ -2351,7 +2604,7 @@ var TinyCloudNode = class _TinyCloudNode {
2351
2604
  ...prepared,
2352
2605
  signature
2353
2606
  });
2354
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
2607
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
2355
2608
  targetHost,
2356
2609
  invokerSession.delegationHeader
2357
2610
  );
@@ -2440,7 +2693,7 @@ var TinyCloudNode = class _TinyCloudNode {
2440
2693
  ...prepared,
2441
2694
  signature
2442
2695
  });
2443
- const activateResult = await (0, import_sdk_core4.activateSessionWithHost)(
2696
+ const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
2444
2697
  targetHost,
2445
2698
  subDelegationSession.delegationHeader
2446
2699
  );
@@ -2462,6 +2715,21 @@ var TinyCloudNode = class _TinyCloudNode {
2462
2715
  };
2463
2716
  }
2464
2717
  };
2718
+ // ===========================================================================
2719
+ // Capability-chain delegation (spec: .claude/specs/capability-chain.md)
2720
+ // ===========================================================================
2721
+ /**
2722
+ * Safety margin before the session's own expiry at which {@link delegateTo}
2723
+ * will refuse to issue a derived delegation. Prevents issuing sub-delegations
2724
+ * that would be invalid by the time the recipient used them. Spec: 60 seconds.
2725
+ *
2726
+ * @internal
2727
+ */
2728
+ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
2729
+ var TinyCloudNode = _TinyCloudNode;
2730
+
2731
+ // src/core.ts
2732
+ var import_sdk_core8 = require("@tinycloud/sdk-core");
2465
2733
 
2466
2734
  // src/delegation.ts
2467
2735
  function serializeDelegation(delegation) {
@@ -2480,8 +2748,6 @@ function deserializeDelegation(data) {
2480
2748
  }
2481
2749
 
2482
2750
  // src/core.ts
2483
- var import_sdk_core7 = require("@tinycloud/sdk-core");
2484
- var import_sdk_core8 = require("@tinycloud/sdk-core");
2485
2751
  var import_sdk_core9 = require("@tinycloud/sdk-core");
2486
2752
  var import_sdk_core10 = require("@tinycloud/sdk-core");
2487
2753
  var import_sdk_core11 = require("@tinycloud/sdk-core");
@@ -2489,6 +2755,8 @@ var import_sdk_core12 = require("@tinycloud/sdk-core");
2489
2755
  var import_sdk_core13 = require("@tinycloud/sdk-core");
2490
2756
  var import_sdk_core14 = require("@tinycloud/sdk-core");
2491
2757
  var import_sdk_core15 = require("@tinycloud/sdk-core");
2758
+ var import_sdk_core16 = require("@tinycloud/sdk-core");
2759
+ var import_sdk_core17 = require("@tinycloud/sdk-core");
2492
2760
  // Annotate the CommonJS export names for ESM import in node:
2493
2761
  0 && (module.exports = {
2494
2762
  AutoApproveSpaceCreationHandler,
@@ -2504,13 +2772,16 @@ var import_sdk_core15 = require("@tinycloud/sdk-core");
2504
2772
  DuckDbService,
2505
2773
  FileSessionStorage,
2506
2774
  KVService,
2775
+ ManifestValidationError,
2507
2776
  MemorySessionStorage,
2508
2777
  NodeUserAuthorization,
2778
+ PermissionNotInManifestError,
2509
2779
  PrefixedKVService,
2510
2780
  ProtocolMismatchError,
2511
2781
  SQLAction,
2512
2782
  SQLService,
2513
2783
  ServiceContext,
2784
+ SessionExpiredError,
2514
2785
  SharingService,
2515
2786
  SilentNotificationHandler,
2516
2787
  Space,
@@ -2533,8 +2804,14 @@ var import_sdk_core15 = require("@tinycloud/sdk-core");
2533
2804
  defaultSignStrategy,
2534
2805
  defaultSpaceCreationHandler,
2535
2806
  deserializeDelegation,
2807
+ expandActionShortNames,
2808
+ isCapabilitySubset,
2809
+ loadManifest,
2536
2810
  makePublicSpaceId,
2811
+ parseExpiry,
2537
2812
  parseSpaceUri,
2538
- serializeDelegation
2813
+ resolveManifest,
2814
+ serializeDelegation,
2815
+ validateManifest
2539
2816
  });
2540
2817
  //# sourceMappingURL=core.cjs.map