@tinycloud/node-sdk 2.2.0-beta.10 → 2.2.0-beta.12

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.
@@ -321,6 +321,19 @@ declare class NodeUserAuthorization implements IUserAuthorization {
321
321
  * Includes spaceId, delegationHeader, and delegationCid.
322
322
  */
323
323
  get tinyCloudSession(): TinyCloudSession | undefined;
324
+ /**
325
+ * Rehydrate the auth-layer session from previously-persisted delegation
326
+ * data. Used by {@link TinyCloudNode.restoreSession} so that downstream
327
+ * surfaces that read from `tinyCloudSession` (notably
328
+ * `grantRuntimePermissions`, which extracts the SIWE expiry from it) work
329
+ * without re-running the full sign-in flow.
330
+ *
331
+ * Caller must supply the same fields that `signIn` would have written —
332
+ * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
+ * undefined for missing SIWEs and the SDK then treats the session as
334
+ * expired-at-epoch-zero.
335
+ */
336
+ setRestoredTinyCloudSession(session: TinyCloudSession): void;
324
337
  private resolveTinyCloudHostsForSignIn;
325
338
  private requireTinyCloudHosts;
326
339
  private get primaryTinyCloudHost();
@@ -793,6 +806,13 @@ declare class TinyCloudNode {
793
806
  private _delegationManager?;
794
807
  private _spaceService?;
795
808
  private runtimePermissionGrants;
809
+ /**
810
+ * TinyCloudSession captured by {@link restoreSession} when there's no
811
+ * auth-layer signer available (session-only mode used by OpenKey-backed
812
+ * CLI restores, public-space replays, …). Read by
813
+ * {@link currentTinyCloudSession} as a fallback for `auth.tinyCloudSession`.
814
+ */
815
+ private _restoredTcSession?;
796
816
  private get nodeFeatures();
797
817
  /** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
798
818
  private get siweDomain();
@@ -909,7 +929,28 @@ declare class TinyCloudNode {
909
929
  verificationMethod: string;
910
930
  address?: string;
911
931
  chainId?: number;
932
+ /**
933
+ * The SIWE message that authorized this session. Required for
934
+ * downstream operations that need the session's expiry (e.g.
935
+ * {@link grantRuntimePermissions}). When omitted the SDK can still
936
+ * invoke services with the existing delegation, but anything that
937
+ * reads `auth.tinyCloudSession.siwe` will treat the session as
938
+ * expired-at-epoch-zero.
939
+ */
940
+ siwe?: string;
941
+ /**
942
+ * The wallet/OpenKey signature over `siwe`. Optional because the
943
+ * runtime doesn't re-verify it — it's persisted alongside the SIWE
944
+ * for callers that need to round-trip the full session shape.
945
+ */
946
+ signature?: string;
912
947
  }): Promise<void>;
948
+ /**
949
+ * Resolve the currently-active TinyCloudSession, preferring the auth
950
+ * layer's value (wallet mode) and falling back to the node-level
951
+ * rehydration set by {@link restoreSession} (session-only mode).
952
+ */
953
+ private currentTinyCloudSession;
913
954
  /**
914
955
  * Connect a wallet to upgrade from session-only mode to wallet mode.
915
956
  *
@@ -1011,6 +1052,21 @@ declare class TinyCloudNode {
1011
1052
  * SQL database operations on this user's space.
1012
1053
  */
1013
1054
  get sql(): ISQLService;
1055
+ /**
1056
+ * Get an SQL service scoped to a specific space.
1057
+ *
1058
+ * Mirrors {@link SpaceService}'s per-space KV factory: clones the active
1059
+ * service context and overrides its session's spaceId so that subsequent
1060
+ * `sql/<dbName>/<action>` invocations route to that space. Useful when
1061
+ * the caller already holds a delegation covering the target space (e.g.
1062
+ * via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
1063
+ * but the SDK's per-space SQL surface isn't otherwise exposed.
1064
+ *
1065
+ * Does NOT auto-create the space.
1066
+ *
1067
+ * @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
1068
+ */
1069
+ sqlForSpace(spaceId: string): ISQLService;
1014
1070
  /**
1015
1071
  * DuckDB database operations on this user's space.
1016
1072
  */
@@ -321,6 +321,19 @@ declare class NodeUserAuthorization implements IUserAuthorization {
321
321
  * Includes spaceId, delegationHeader, and delegationCid.
322
322
  */
323
323
  get tinyCloudSession(): TinyCloudSession | undefined;
324
+ /**
325
+ * Rehydrate the auth-layer session from previously-persisted delegation
326
+ * data. Used by {@link TinyCloudNode.restoreSession} so that downstream
327
+ * surfaces that read from `tinyCloudSession` (notably
328
+ * `grantRuntimePermissions`, which extracts the SIWE expiry from it) work
329
+ * without re-running the full sign-in flow.
330
+ *
331
+ * Caller must supply the same fields that `signIn` would have written —
332
+ * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
+ * undefined for missing SIWEs and the SDK then treats the session as
334
+ * expired-at-epoch-zero.
335
+ */
336
+ setRestoredTinyCloudSession(session: TinyCloudSession): void;
324
337
  private resolveTinyCloudHostsForSignIn;
325
338
  private requireTinyCloudHosts;
326
339
  private get primaryTinyCloudHost();
@@ -793,6 +806,13 @@ declare class TinyCloudNode {
793
806
  private _delegationManager?;
794
807
  private _spaceService?;
795
808
  private runtimePermissionGrants;
809
+ /**
810
+ * TinyCloudSession captured by {@link restoreSession} when there's no
811
+ * auth-layer signer available (session-only mode used by OpenKey-backed
812
+ * CLI restores, public-space replays, …). Read by
813
+ * {@link currentTinyCloudSession} as a fallback for `auth.tinyCloudSession`.
814
+ */
815
+ private _restoredTcSession?;
796
816
  private get nodeFeatures();
797
817
  /** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
798
818
  private get siweDomain();
@@ -909,7 +929,28 @@ declare class TinyCloudNode {
909
929
  verificationMethod: string;
910
930
  address?: string;
911
931
  chainId?: number;
932
+ /**
933
+ * The SIWE message that authorized this session. Required for
934
+ * downstream operations that need the session's expiry (e.g.
935
+ * {@link grantRuntimePermissions}). When omitted the SDK can still
936
+ * invoke services with the existing delegation, but anything that
937
+ * reads `auth.tinyCloudSession.siwe` will treat the session as
938
+ * expired-at-epoch-zero.
939
+ */
940
+ siwe?: string;
941
+ /**
942
+ * The wallet/OpenKey signature over `siwe`. Optional because the
943
+ * runtime doesn't re-verify it — it's persisted alongside the SIWE
944
+ * for callers that need to round-trip the full session shape.
945
+ */
946
+ signature?: string;
912
947
  }): Promise<void>;
948
+ /**
949
+ * Resolve the currently-active TinyCloudSession, preferring the auth
950
+ * layer's value (wallet mode) and falling back to the node-level
951
+ * rehydration set by {@link restoreSession} (session-only mode).
952
+ */
953
+ private currentTinyCloudSession;
913
954
  /**
914
955
  * Connect a wallet to upgrade from session-only mode to wallet mode.
915
956
  *
@@ -1011,6 +1052,21 @@ declare class TinyCloudNode {
1011
1052
  * SQL database operations on this user's space.
1012
1053
  */
1013
1054
  get sql(): ISQLService;
1055
+ /**
1056
+ * Get an SQL service scoped to a specific space.
1057
+ *
1058
+ * Mirrors {@link SpaceService}'s per-space KV factory: clones the active
1059
+ * service context and overrides its session's spaceId so that subsequent
1060
+ * `sql/<dbName>/<action>` invocations route to that space. Useful when
1061
+ * the caller already holds a delegation covering the target space (e.g.
1062
+ * via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
1063
+ * but the SDK's per-space SQL surface isn't otherwise exposed.
1064
+ *
1065
+ * Does NOT auto-create the space.
1066
+ *
1067
+ * @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
1068
+ */
1069
+ sqlForSpace(spaceId: string): ISQLService;
1014
1070
  /**
1015
1071
  * DuckDB database operations on this user's space.
1016
1072
  */
package/dist/core.cjs CHANGED
@@ -27,6 +27,7 @@ __export(core_exports, {
27
27
  CapabilityKeyRegistryErrorCodes: () => import_sdk_core15.CapabilityKeyRegistryErrorCodes,
28
28
  DEFAULT_MANIFEST_SPACE: () => import_sdk_core9.DEFAULT_MANIFEST_SPACE,
29
29
  DEFAULT_MANIFEST_VERSION: () => import_sdk_core9.DEFAULT_MANIFEST_VERSION,
30
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core10.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
30
31
  DataVaultService: () => import_sdk_core13.DataVaultService,
31
32
  DatabaseHandle: () => import_sdk_core11.DatabaseHandle,
32
33
  DelegatedAccess: () => DelegatedAccess,
@@ -343,7 +344,7 @@ var NodeUserAuthorization = class {
343
344
  ]
344
345
  }
345
346
  };
346
- this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
347
+ this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core2.EXPIRY.SESSION_MS;
347
348
  this.autoCreateSpace = config.autoCreateSpace ?? false;
348
349
  this.spaceCreationHandler = config.spaceCreationHandler;
349
350
  this.tinycloudHosts = config.tinycloudHosts;
@@ -396,6 +397,23 @@ var NodeUserAuthorization = class {
396
397
  get tinyCloudSession() {
397
398
  return this._tinyCloudSession;
398
399
  }
400
+ /**
401
+ * Rehydrate the auth-layer session from previously-persisted delegation
402
+ * data. Used by {@link TinyCloudNode.restoreSession} so that downstream
403
+ * surfaces that read from `tinyCloudSession` (notably
404
+ * `grantRuntimePermissions`, which extracts the SIWE expiry from it) work
405
+ * without re-running the full sign-in flow.
406
+ *
407
+ * Caller must supply the same fields that `signIn` would have written —
408
+ * `siwe` is the load-bearing one because `extractSiweExpiration` returns
409
+ * undefined for missing SIWEs and the SDK then treats the session as
410
+ * expired-at-epoch-zero.
411
+ */
412
+ setRestoredTinyCloudSession(session) {
413
+ this._tinyCloudSession = session;
414
+ this._address = session.address;
415
+ this._chainId = session.chainId;
416
+ }
399
417
  async resolveTinyCloudHostsForSignIn(address, chainId) {
400
418
  if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
401
419
  return;
@@ -1231,9 +1249,10 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
1231
1249
  }
1232
1250
  return entries;
1233
1251
  }
1252
+ var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core4.EXPIRY.SESSION_MS;
1234
1253
  function resolveExpiryMs(expiry) {
1235
1254
  if (expiry === void 0) {
1236
- return 60 * 60 * 1e3;
1255
+ return DEFAULT_DELEGATION_EXPIRY_MS;
1237
1256
  }
1238
1257
  if (typeof expiry === "number") {
1239
1258
  if (!Number.isFinite(expiry) || expiry <= 0) {
@@ -1403,6 +1422,7 @@ var NodeSecretsService = class {
1403
1422
 
1404
1423
  // src/TinyCloudNode.ts
1405
1424
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
1425
+ var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core6.EXPIRY.SESSION_MS;
1406
1426
  var _TinyCloudNode = class _TinyCloudNode {
1407
1427
  /**
1408
1428
  * Create a new TinyCloudNode instance.
@@ -1545,7 +1565,7 @@ var _TinyCloudNode = class _TinyCloudNode {
1545
1565
  sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
1546
1566
  domain: this.siweDomain,
1547
1567
  spacePrefix: config.prefix,
1548
- sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
1568
+ sessionExpirationMs: config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
1549
1569
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
1550
1570
  tinycloudRegistryUrl: config.tinycloudRegistryUrl,
1551
1571
  tinycloudFallbackHosts: config.tinycloudFallbackHosts,
@@ -1811,6 +1831,33 @@ var _TinyCloudNode = class _TinyCloudNode {
1811
1831
  this._vault.initialize(this._serviceContext);
1812
1832
  this._serviceContext.registerService("vault", this._vault);
1813
1833
  this.initializeV2Services(serviceSession);
1834
+ if (sessionData.siwe && sessionData.address && sessionData.chainId) {
1835
+ const tcSession = {
1836
+ address: sessionData.address,
1837
+ chainId: sessionData.chainId,
1838
+ sessionKey: JSON.stringify(sessionData.jwk),
1839
+ spaceId: sessionData.spaceId,
1840
+ delegationCid: sessionData.delegationCid,
1841
+ delegationHeader: sessionData.delegationHeader,
1842
+ verificationMethod: sessionData.verificationMethod,
1843
+ jwk: sessionData.jwk,
1844
+ siwe: sessionData.siwe,
1845
+ signature: sessionData.signature ?? ""
1846
+ };
1847
+ if (this.auth) {
1848
+ this.auth.setRestoredTinyCloudSession(tcSession);
1849
+ } else {
1850
+ this._restoredTcSession = tcSession;
1851
+ }
1852
+ }
1853
+ }
1854
+ /**
1855
+ * Resolve the currently-active TinyCloudSession, preferring the auth
1856
+ * layer's value (wallet mode) and falling back to the node-level
1857
+ * rehydration set by {@link restoreSession} (session-only mode).
1858
+ */
1859
+ currentTinyCloudSession() {
1860
+ return this.auth?.tinyCloudSession ?? this._restoredTcSession;
1814
1861
  }
1815
1862
  /**
1816
1863
  * Connect a wallet to upgrade from session-only mode to wallet mode.
@@ -1855,7 +1902,7 @@ var _TinyCloudNode = class _TinyCloudNode {
1855
1902
  sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
1856
1903
  domain: this.siweDomain,
1857
1904
  spacePrefix: prefix,
1858
- sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
1905
+ sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
1859
1906
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
1860
1907
  tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
1861
1908
  tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
@@ -1899,7 +1946,7 @@ var _TinyCloudNode = class _TinyCloudNode {
1899
1946
  sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
1900
1947
  domain: this.siweDomain,
1901
1948
  spacePrefix: prefix,
1902
- sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
1949
+ sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
1903
1950
  tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
1904
1951
  tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
1905
1952
  tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
@@ -2175,7 +2222,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2175
2222
  * @internal
2176
2223
  */
2177
2224
  getSessionExpiry() {
2178
- const expirationMs = this.config.sessionExpirationMs ?? 60 * 60 * 1e3;
2225
+ const expirationMs = this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS;
2179
2226
  return new Date(Date.now() + expirationMs);
2180
2227
  }
2181
2228
  /**
@@ -2332,6 +2379,34 @@ var _TinyCloudNode = class _TinyCloudNode {
2332
2379
  }
2333
2380
  return this._sql;
2334
2381
  }
2382
+ /**
2383
+ * Get an SQL service scoped to a specific space.
2384
+ *
2385
+ * Mirrors {@link SpaceService}'s per-space KV factory: clones the active
2386
+ * service context and overrides its session's spaceId so that subsequent
2387
+ * `sql/<dbName>/<action>` invocations route to that space. Useful when
2388
+ * the caller already holds a delegation covering the target space (e.g.
2389
+ * via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
2390
+ * but the SDK's per-space SQL surface isn't otherwise exposed.
2391
+ *
2392
+ * Does NOT auto-create the space.
2393
+ *
2394
+ * @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
2395
+ */
2396
+ sqlForSpace(spaceId) {
2397
+ if (!this._serviceContext || !this._serviceContext.session) {
2398
+ throw new Error("Not signed in. Call signIn() first.");
2399
+ }
2400
+ const sql = new import_sdk_core6.SQLService({});
2401
+ const spaceScopedContext = new import_sdk_core6.ServiceContext({
2402
+ invoke: this._serviceContext.invoke,
2403
+ fetch: this._serviceContext.fetch,
2404
+ hosts: this._serviceContext.hosts
2405
+ });
2406
+ spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
2407
+ sql.initialize(spaceScopedContext);
2408
+ return sql;
2409
+ }
2335
2410
  /**
2336
2411
  * DuckDB database operations on this user's space.
2337
2412
  */
@@ -2457,7 +2532,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2457
2532
  * every requested permission.
2458
2533
  */
2459
2534
  hasRuntimePermissions(permissions) {
2460
- const session = this.auth?.tinyCloudSession;
2535
+ const session = this.currentTinyCloudSession();
2461
2536
  if (!session || !Array.isArray(permissions) || permissions.length === 0) {
2462
2537
  return false;
2463
2538
  }
@@ -2477,7 +2552,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2477
2552
  if (permissions === void 0) {
2478
2553
  return this.runtimePermissionGrants.map((grant) => grant.delegation);
2479
2554
  }
2480
- const session = this.auth?.tinyCloudSession;
2555
+ const session = this.currentTinyCloudSession();
2481
2556
  if (!session || !Array.isArray(permissions) || permissions.length === 0) {
2482
2557
  return [];
2483
2558
  }
@@ -2491,7 +2566,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2491
2566
  * matching service calls and downstream `delegateTo()` calls can use it.
2492
2567
  */
2493
2568
  async useRuntimeDelegation(delegation) {
2494
- const session = this.auth?.tinyCloudSession;
2569
+ const session = this.currentTinyCloudSession();
2495
2570
  if (!session) {
2496
2571
  throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
2497
2572
  }
@@ -2530,7 +2605,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2530
2605
  if (!Array.isArray(permissions) || permissions.length === 0) {
2531
2606
  throw new Error("grantRuntimePermissions requires a non-empty permissions array");
2532
2607
  }
2533
- const session = this.auth?.tinyCloudSession;
2608
+ const session = this.currentTinyCloudSession();
2534
2609
  if (!session) {
2535
2610
  throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
2536
2611
  }
@@ -2758,7 +2833,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2758
2833
  ];
2759
2834
  const abilities = { kv: { "": kvActions } };
2760
2835
  const now = /* @__PURE__ */ new Date();
2761
- const expiryMs = 60 * 60 * 1e3;
2836
+ const expiryMs = import_sdk_core6.EXPIRY.EPHEMERAL_MS;
2762
2837
  const expirationTime = new Date(now.getTime() + expiryMs);
2763
2838
  const prepared = this.wasmBindings.prepareSession({
2764
2839
  abilities,
@@ -3817,6 +3892,7 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
3817
3892
  CapabilityKeyRegistryErrorCodes,
3818
3893
  DEFAULT_MANIFEST_SPACE,
3819
3894
  DEFAULT_MANIFEST_VERSION,
3895
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
3820
3896
  DataVaultService,
3821
3897
  DatabaseHandle,
3822
3898
  DelegatedAccess,