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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { ISessionStorage, PersistedSessionData, AutoSignStrategy, AutoRejectStrategy, CallbackStrategy, IUserAuthorization, ISigner, ISpaceCreationHandler, IWasmBindings, SiweConfig, Manifest, ComposedManifestRequest, ClientSession, TinyCloudSession, Extension, SignInOptions, Delegation, DelegatedResource, PermissionEntry, TelemetryConfig, IKVService, ISQLService, IDuckDbService, IHooksService, INotificationHandler, IENSResolver, AccountService, IDataVaultService, IEncryptionService, NetworkDescriptor, ISecretsService, ICapabilityKeyRegistry, DelegationManager, ISpaceService, ISpace, ISharingService, CreateDelegationParams, DelegationResult, ResolvedDelegate, KeyProvider, ISessionManager, JWK } from '@tinycloud/sdk-core';
2
2
  import { EventEmitter } from 'events';
3
- import { InvokeFunction } from '@tinycloud/sdk-services';
3
+ import { InvokeFunction, InvokeAnyFunction } from '@tinycloud/sdk-services';
4
4
 
5
5
  /**
6
6
  * In-memory session storage for Node.js.
@@ -230,6 +230,11 @@ interface NodeUserAuthorizationConfig {
230
230
  /** Include implicit account registry permissions when composing `manifest`. Default true. */
231
231
  includeAccountRegistryPermissions?: boolean;
232
232
  }
233
+ interface CreateBootstrapSessionOptions {
234
+ spaceId: string;
235
+ capabilityRequest: ComposedManifestRequest;
236
+ rawAbilities?: Record<string, string[]>;
237
+ }
233
238
  /**
234
239
  * Node.js implementation of IUserAuthorization.
235
240
  *
@@ -296,6 +301,7 @@ declare class NodeUserAuthorization implements IUserAuthorization {
296
301
  private _address?;
297
302
  private _chainId?;
298
303
  private _nodeFeatures;
304
+ private _lastActivationSkippedSpaceIds;
299
305
  constructor(config: NodeUserAuthorizationConfig);
300
306
  /**
301
307
  * Return the manifest currently driving sign-in behavior, or
@@ -332,12 +338,36 @@ declare class NodeUserAuthorization implements IUserAuthorization {
332
338
  * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
339
  * undefined for missing SIWEs and the SDK then treats the session as
334
340
  * expired-at-epoch-zero.
341
+ *
342
+ * @param hosts - The TinyCloud hosts this session was created against,
343
+ * as persisted in {@link PersistedSessionData.tinycloudHosts}. When
344
+ * present (and non-empty) they are adopted directly so the restored
345
+ * session resolves to the same node as the original sign-in without
346
+ * re-running registry/fallback resolution. When absent (old session)
347
+ * hosts are resolved lazily on the first host-needing call via
348
+ * {@link ensureTinyCloudHosts}.
349
+ */
350
+ setRestoredTinyCloudSession(session: TinyCloudSession, hosts?: string[]): void;
351
+ /**
352
+ * Ensure `tinycloudHosts` are resolved before a host-needing call.
353
+ *
354
+ * Fresh sign-in resolves hosts up front; a restored session may not have
355
+ * (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
356
+ * This guard makes a restored session resolve the node exactly like a fresh
357
+ * sign-in — persisted hosts are preferred (already set by
358
+ * {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
359
+ * resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
360
+ * early-returns when hosts are already set.
361
+ *
362
+ * Throws if hosts are unset and the restored session has no address/chainId
363
+ * to resolve from — a real failure that must surface, not be masked.
335
364
  */
336
- setRestoredTinyCloudSession(session: TinyCloudSession): void;
365
+ ensureTinyCloudHosts(): Promise<void>;
337
366
  private resolveTinyCloudHostsForSignIn;
338
367
  private requireTinyCloudHosts;
339
368
  private get primaryTinyCloudHost();
340
369
  get nodeFeatures(): string[];
370
+ get lastActivationSkippedSpaceIds(): string[];
341
371
  /**
342
372
  * Compute the `abilities` map the WASM `prepareSession` call should
343
373
  * see at sign-in time.
@@ -410,6 +440,8 @@ declare class NodeUserAuthorization implements IUserAuthorization {
410
440
  * @throws Error if space creation fails
411
441
  */
412
442
  ensureSpaceExists(): Promise<void>;
443
+ private recordActivationSkippedSpaces;
444
+ createBootstrapSession(options: CreateBootstrapSessionOptions): Promise<TinyCloudSession>;
413
445
  /**
414
446
  * Sign in and create a new session.
415
447
  *
@@ -650,7 +682,7 @@ declare class DelegatedAccess {
650
682
  private _sql;
651
683
  private _duckdb;
652
684
  private _hooks;
653
- constructor(session: TinyCloudSession, delegation: PortableDelegation, host: string, invoke: InvokeFunction, telemetry?: TelemetryConfig);
685
+ constructor(session: TinyCloudSession, delegation: PortableDelegation, host: string, invoke: InvokeFunction, invokeAny?: InvokeAnyFunction, telemetry?: TelemetryConfig);
654
686
  /**
655
687
  * Get the delegation this access was created from.
656
688
  */
@@ -731,6 +763,8 @@ interface TinyCloudNodeConfig {
731
763
  privateKey?: string;
732
764
  /** Custom signer implementation. If provided, takes precedence over privateKey. */
733
765
  signer?: ISigner;
766
+ /** Strategy for root signature requests. Defaults to auto-sign for local keys. */
767
+ signStrategy?: SignStrategy;
734
768
  /** Explicit TinyCloud server URL. When omitted, signIn resolves the user's host. */
735
769
  host?: string;
736
770
  /** TinyCloud location registry URL. Default: https://registry.tinycloud.xyz. */
@@ -786,6 +820,8 @@ interface TinyCloudNodeConfig {
786
820
  capabilityRequest?: ComposedManifestRequest;
787
821
  /** Include implicit account registry permissions when composing `manifest`. Default true. */
788
822
  includeAccountRegistryPermissions?: boolean;
823
+ /** Run canonical first-account bootstrap when fresh account state is detected. Default true. */
824
+ autoBootstrapAccount?: boolean;
789
825
  /** Default-off service telemetry. */
790
826
  telemetry?: TelemetryConfig;
791
827
  }
@@ -915,6 +951,7 @@ declare class TinyCloudNode {
915
951
  * @internal
916
952
  */
917
953
  private setupAuth;
954
+ private shouldUseBootstrapSignInRequest;
918
955
  private syncResolvedHostFromAuth;
919
956
  /**
920
957
  * Install or replace the manifest that drives the SIWE recap at
@@ -985,12 +1022,16 @@ declare class TinyCloudNode {
985
1022
  */
986
1023
  signIn(options?: SignInOptions): Promise<void>;
987
1024
  private ownedSpaceId;
1025
+ private bootstrapAccountIfNeeded;
1026
+ private isFreshBootstrapAccount;
1027
+ private runAccountBootstrap;
1028
+ private registerBootstrapRuntimeGrant;
988
1029
  private writeManifestRegistryRecords;
989
1030
  private scheduleAccountRegistrySync;
990
1031
  private withAccountRegistryRetry;
991
1032
  private requestedEncryptionNetworkIds;
992
1033
  private ensureRequestedEncryptionNetworks;
993
- private ensureOwnedSpaceHosted;
1034
+ private ensureOwnedSpaceHostedById;
994
1035
  /**
995
1036
  * Host one of this user's owned spaces by name (e.g. `"applications"`).
996
1037
  *
@@ -1001,7 +1042,7 @@ declare class TinyCloudNode {
1001
1042
  * caller is the root authority of their own owned spaces, so no additional
1002
1043
  * delegation is required.
1003
1044
  *
1004
- * Unlike {@link ensureOwnedSpaceHosted}, this always submits the host
1045
+ * Unlike {@link ensureOwnedSpaceHostedById}, this always submits the host
1005
1046
  * delegation rather than inferring hosting from session activation: a space
1006
1047
  * the current session has never referenced is reported neither as
1007
1048
  * `activated` nor `skipped`, so activation-based detection would wrongly
@@ -1012,6 +1053,56 @@ declare class TinyCloudNode {
1012
1053
  * @returns The hosted space URI.
1013
1054
  */
1014
1055
  hostOwnedSpace(name: string): Promise<string>;
1056
+ /**
1057
+ * Ensure one of this user's owned spaces (e.g. `"secrets"`) is hosted on the
1058
+ * server.
1059
+ *
1060
+ * At sign-in, a full-authority session auto-hosts the owner's `secrets`
1061
+ * space, but a session created with a manifest / capabilityRequest does not.
1062
+ * Such a session can therefore hold valid `tinycloud.kv/*` capabilities for
1063
+ * the owned `secrets` space yet still fail its first scoped
1064
+ * `secrets.put(...)` with `404 Space not found`, because the space was never
1065
+ * registered on the node.
1066
+ *
1067
+ * Calling this resolves `name` to the owner's owned-space URI
1068
+ * (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`). It first consults the
1069
+ * account-space spaces registry (`account/spaces/{space_id}`, the canonical
1070
+ * KV source of truth, fronted by a best-effort SQLite index): if the space is
1071
+ * already registered/hosted it returns the URI WITHOUT submitting a host
1072
+ * delegation, avoiding a redundant host-SIWE signature prompt for owners who
1073
+ * already use the space. Only when the space is absent — or the registry
1074
+ * check fails for any reason (e.g. a cold SQLite index reporting
1075
+ * `no such table: spaces`) — does it fall through to {@link hostOwnedSpace}.
1076
+ *
1077
+ * The registry check is purely an optimization: any failure falls back to
1078
+ * hosting, and the host SIWE is idempotent server-side, so re-hosting an
1079
+ * existing space remains a safe no-op. Must be called after {@link signIn}.
1080
+ *
1081
+ * @param name - The owned space name (e.g. `"secrets"`).
1082
+ * @returns The hosted owned-space URI.
1083
+ */
1084
+ ensureOwnedSpaceHosted(name: string): Promise<string>;
1085
+ /**
1086
+ * Check whether an owned space is already registered/hosted by consulting the
1087
+ * account spaces registry.
1088
+ *
1089
+ * Source of truth is the canonical KV registry record
1090
+ * `account/spaces/{space_id}`, read here via `account.spaces.get(spaceId)`.
1091
+ * The KV path is used (rather than `syncAccessible()`) because it works under
1092
+ * a manifest/recap session with NO extra prompt: the composed manifest recap
1093
+ * already grants `tinycloud.kv get/list` on the account space `spaces/`
1094
+ * prefix, whereas `syncAccessible()` depends on `tinycloud.space/list`, which
1095
+ * a recap session does not hold. Before reading, it consults the fast SQLite
1096
+ * index (`account.index.spaces.list()`) as a best-effort short-circuit; on a
1097
+ * cold index (`no such table: spaces`) or any other index failure it falls
1098
+ * back to the canonical KV read.
1099
+ *
1100
+ * This is a best-effort optimization. ANY failure of the check path (missing
1101
+ * table, KV error, missing record, thrown exception) resolves to `false` so
1102
+ * the caller falls through to hosting — per the directive, "if it fails in any
1103
+ * way then create the space".
1104
+ */
1105
+ private isOwnedSpaceRegistered;
1015
1106
  /**
1016
1107
  * Restore a previously established session from stored delegation data.
1017
1108
  *
@@ -1046,7 +1137,32 @@ declare class TinyCloudNode {
1046
1137
  * for callers that need to round-trip the full session shape.
1047
1138
  */
1048
1139
  signature?: string;
1140
+ /**
1141
+ * The TinyCloud hosts this session was created against (from
1142
+ * {@link PersistedSessionData.tinycloudHosts}). When present they are
1143
+ * adopted so the restored session targets the same node as the
1144
+ * original sign-in — without this, service calls fall back to the
1145
+ * default host and the auth layer throws "TinyCloud hosts have not
1146
+ * been resolved". When absent (old persisted session) hosts resolve
1147
+ * lazily via the registry/fallback on the first host-needing call.
1148
+ */
1149
+ tinycloudHosts?: string[];
1049
1150
  }): Promise<void>;
1151
+ /**
1152
+ * Resolve the host a restored session should target.
1153
+ *
1154
+ * Mirrors fresh sign-in host resolution but for the restore path:
1155
+ * an explicit/pinned host always wins, then the hosts the session was
1156
+ * persisted with, then a lazy registry/fallback resolution for sessions
1157
+ * that predate the persisted `tinycloudHosts` field. Returns `undefined`
1158
+ * only when there's nothing to resolve from (no explicit host, no
1159
+ * persisted hosts, and no address/chainId) — in which case the existing
1160
+ * `config.host` (default) is left in place.
1161
+ *
1162
+ * Resolution failures are surfaced, not swallowed: a genuinely broken
1163
+ * registry lookup throws rather than silently falling back to a wrong host.
1164
+ */
1165
+ private resolveRestoredHost;
1050
1166
  /**
1051
1167
  * Resolve the currently-active TinyCloudSession, preferring the auth
1052
1168
  * layer's value (wallet mode) and falling back to the node-level
@@ -1,6 +1,6 @@
1
1
  import { ISessionStorage, PersistedSessionData, AutoSignStrategy, AutoRejectStrategy, CallbackStrategy, IUserAuthorization, ISigner, ISpaceCreationHandler, IWasmBindings, SiweConfig, Manifest, ComposedManifestRequest, ClientSession, TinyCloudSession, Extension, SignInOptions, Delegation, DelegatedResource, PermissionEntry, TelemetryConfig, IKVService, ISQLService, IDuckDbService, IHooksService, INotificationHandler, IENSResolver, AccountService, IDataVaultService, IEncryptionService, NetworkDescriptor, ISecretsService, ICapabilityKeyRegistry, DelegationManager, ISpaceService, ISpace, ISharingService, CreateDelegationParams, DelegationResult, ResolvedDelegate, KeyProvider, ISessionManager, JWK } from '@tinycloud/sdk-core';
2
2
  import { EventEmitter } from 'events';
3
- import { InvokeFunction } from '@tinycloud/sdk-services';
3
+ import { InvokeFunction, InvokeAnyFunction } from '@tinycloud/sdk-services';
4
4
 
5
5
  /**
6
6
  * In-memory session storage for Node.js.
@@ -230,6 +230,11 @@ interface NodeUserAuthorizationConfig {
230
230
  /** Include implicit account registry permissions when composing `manifest`. Default true. */
231
231
  includeAccountRegistryPermissions?: boolean;
232
232
  }
233
+ interface CreateBootstrapSessionOptions {
234
+ spaceId: string;
235
+ capabilityRequest: ComposedManifestRequest;
236
+ rawAbilities?: Record<string, string[]>;
237
+ }
233
238
  /**
234
239
  * Node.js implementation of IUserAuthorization.
235
240
  *
@@ -296,6 +301,7 @@ declare class NodeUserAuthorization implements IUserAuthorization {
296
301
  private _address?;
297
302
  private _chainId?;
298
303
  private _nodeFeatures;
304
+ private _lastActivationSkippedSpaceIds;
299
305
  constructor(config: NodeUserAuthorizationConfig);
300
306
  /**
301
307
  * Return the manifest currently driving sign-in behavior, or
@@ -332,12 +338,36 @@ declare class NodeUserAuthorization implements IUserAuthorization {
332
338
  * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
339
  * undefined for missing SIWEs and the SDK then treats the session as
334
340
  * expired-at-epoch-zero.
341
+ *
342
+ * @param hosts - The TinyCloud hosts this session was created against,
343
+ * as persisted in {@link PersistedSessionData.tinycloudHosts}. When
344
+ * present (and non-empty) they are adopted directly so the restored
345
+ * session resolves to the same node as the original sign-in without
346
+ * re-running registry/fallback resolution. When absent (old session)
347
+ * hosts are resolved lazily on the first host-needing call via
348
+ * {@link ensureTinyCloudHosts}.
349
+ */
350
+ setRestoredTinyCloudSession(session: TinyCloudSession, hosts?: string[]): void;
351
+ /**
352
+ * Ensure `tinycloudHosts` are resolved before a host-needing call.
353
+ *
354
+ * Fresh sign-in resolves hosts up front; a restored session may not have
355
+ * (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
356
+ * This guard makes a restored session resolve the node exactly like a fresh
357
+ * sign-in — persisted hosts are preferred (already set by
358
+ * {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
359
+ * resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
360
+ * early-returns when hosts are already set.
361
+ *
362
+ * Throws if hosts are unset and the restored session has no address/chainId
363
+ * to resolve from — a real failure that must surface, not be masked.
335
364
  */
336
- setRestoredTinyCloudSession(session: TinyCloudSession): void;
365
+ ensureTinyCloudHosts(): Promise<void>;
337
366
  private resolveTinyCloudHostsForSignIn;
338
367
  private requireTinyCloudHosts;
339
368
  private get primaryTinyCloudHost();
340
369
  get nodeFeatures(): string[];
370
+ get lastActivationSkippedSpaceIds(): string[];
341
371
  /**
342
372
  * Compute the `abilities` map the WASM `prepareSession` call should
343
373
  * see at sign-in time.
@@ -410,6 +440,8 @@ declare class NodeUserAuthorization implements IUserAuthorization {
410
440
  * @throws Error if space creation fails
411
441
  */
412
442
  ensureSpaceExists(): Promise<void>;
443
+ private recordActivationSkippedSpaces;
444
+ createBootstrapSession(options: CreateBootstrapSessionOptions): Promise<TinyCloudSession>;
413
445
  /**
414
446
  * Sign in and create a new session.
415
447
  *
@@ -650,7 +682,7 @@ declare class DelegatedAccess {
650
682
  private _sql;
651
683
  private _duckdb;
652
684
  private _hooks;
653
- constructor(session: TinyCloudSession, delegation: PortableDelegation, host: string, invoke: InvokeFunction, telemetry?: TelemetryConfig);
685
+ constructor(session: TinyCloudSession, delegation: PortableDelegation, host: string, invoke: InvokeFunction, invokeAny?: InvokeAnyFunction, telemetry?: TelemetryConfig);
654
686
  /**
655
687
  * Get the delegation this access was created from.
656
688
  */
@@ -731,6 +763,8 @@ interface TinyCloudNodeConfig {
731
763
  privateKey?: string;
732
764
  /** Custom signer implementation. If provided, takes precedence over privateKey. */
733
765
  signer?: ISigner;
766
+ /** Strategy for root signature requests. Defaults to auto-sign for local keys. */
767
+ signStrategy?: SignStrategy;
734
768
  /** Explicit TinyCloud server URL. When omitted, signIn resolves the user's host. */
735
769
  host?: string;
736
770
  /** TinyCloud location registry URL. Default: https://registry.tinycloud.xyz. */
@@ -786,6 +820,8 @@ interface TinyCloudNodeConfig {
786
820
  capabilityRequest?: ComposedManifestRequest;
787
821
  /** Include implicit account registry permissions when composing `manifest`. Default true. */
788
822
  includeAccountRegistryPermissions?: boolean;
823
+ /** Run canonical first-account bootstrap when fresh account state is detected. Default true. */
824
+ autoBootstrapAccount?: boolean;
789
825
  /** Default-off service telemetry. */
790
826
  telemetry?: TelemetryConfig;
791
827
  }
@@ -915,6 +951,7 @@ declare class TinyCloudNode {
915
951
  * @internal
916
952
  */
917
953
  private setupAuth;
954
+ private shouldUseBootstrapSignInRequest;
918
955
  private syncResolvedHostFromAuth;
919
956
  /**
920
957
  * Install or replace the manifest that drives the SIWE recap at
@@ -985,12 +1022,16 @@ declare class TinyCloudNode {
985
1022
  */
986
1023
  signIn(options?: SignInOptions): Promise<void>;
987
1024
  private ownedSpaceId;
1025
+ private bootstrapAccountIfNeeded;
1026
+ private isFreshBootstrapAccount;
1027
+ private runAccountBootstrap;
1028
+ private registerBootstrapRuntimeGrant;
988
1029
  private writeManifestRegistryRecords;
989
1030
  private scheduleAccountRegistrySync;
990
1031
  private withAccountRegistryRetry;
991
1032
  private requestedEncryptionNetworkIds;
992
1033
  private ensureRequestedEncryptionNetworks;
993
- private ensureOwnedSpaceHosted;
1034
+ private ensureOwnedSpaceHostedById;
994
1035
  /**
995
1036
  * Host one of this user's owned spaces by name (e.g. `"applications"`).
996
1037
  *
@@ -1001,7 +1042,7 @@ declare class TinyCloudNode {
1001
1042
  * caller is the root authority of their own owned spaces, so no additional
1002
1043
  * delegation is required.
1003
1044
  *
1004
- * Unlike {@link ensureOwnedSpaceHosted}, this always submits the host
1045
+ * Unlike {@link ensureOwnedSpaceHostedById}, this always submits the host
1005
1046
  * delegation rather than inferring hosting from session activation: a space
1006
1047
  * the current session has never referenced is reported neither as
1007
1048
  * `activated` nor `skipped`, so activation-based detection would wrongly
@@ -1012,6 +1053,56 @@ declare class TinyCloudNode {
1012
1053
  * @returns The hosted space URI.
1013
1054
  */
1014
1055
  hostOwnedSpace(name: string): Promise<string>;
1056
+ /**
1057
+ * Ensure one of this user's owned spaces (e.g. `"secrets"`) is hosted on the
1058
+ * server.
1059
+ *
1060
+ * At sign-in, a full-authority session auto-hosts the owner's `secrets`
1061
+ * space, but a session created with a manifest / capabilityRequest does not.
1062
+ * Such a session can therefore hold valid `tinycloud.kv/*` capabilities for
1063
+ * the owned `secrets` space yet still fail its first scoped
1064
+ * `secrets.put(...)` with `404 Space not found`, because the space was never
1065
+ * registered on the node.
1066
+ *
1067
+ * Calling this resolves `name` to the owner's owned-space URI
1068
+ * (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`). It first consults the
1069
+ * account-space spaces registry (`account/spaces/{space_id}`, the canonical
1070
+ * KV source of truth, fronted by a best-effort SQLite index): if the space is
1071
+ * already registered/hosted it returns the URI WITHOUT submitting a host
1072
+ * delegation, avoiding a redundant host-SIWE signature prompt for owners who
1073
+ * already use the space. Only when the space is absent — or the registry
1074
+ * check fails for any reason (e.g. a cold SQLite index reporting
1075
+ * `no such table: spaces`) — does it fall through to {@link hostOwnedSpace}.
1076
+ *
1077
+ * The registry check is purely an optimization: any failure falls back to
1078
+ * hosting, and the host SIWE is idempotent server-side, so re-hosting an
1079
+ * existing space remains a safe no-op. Must be called after {@link signIn}.
1080
+ *
1081
+ * @param name - The owned space name (e.g. `"secrets"`).
1082
+ * @returns The hosted owned-space URI.
1083
+ */
1084
+ ensureOwnedSpaceHosted(name: string): Promise<string>;
1085
+ /**
1086
+ * Check whether an owned space is already registered/hosted by consulting the
1087
+ * account spaces registry.
1088
+ *
1089
+ * Source of truth is the canonical KV registry record
1090
+ * `account/spaces/{space_id}`, read here via `account.spaces.get(spaceId)`.
1091
+ * The KV path is used (rather than `syncAccessible()`) because it works under
1092
+ * a manifest/recap session with NO extra prompt: the composed manifest recap
1093
+ * already grants `tinycloud.kv get/list` on the account space `spaces/`
1094
+ * prefix, whereas `syncAccessible()` depends on `tinycloud.space/list`, which
1095
+ * a recap session does not hold. Before reading, it consults the fast SQLite
1096
+ * index (`account.index.spaces.list()`) as a best-effort short-circuit; on a
1097
+ * cold index (`no such table: spaces`) or any other index failure it falls
1098
+ * back to the canonical KV read.
1099
+ *
1100
+ * This is a best-effort optimization. ANY failure of the check path (missing
1101
+ * table, KV error, missing record, thrown exception) resolves to `false` so
1102
+ * the caller falls through to hosting — per the directive, "if it fails in any
1103
+ * way then create the space".
1104
+ */
1105
+ private isOwnedSpaceRegistered;
1015
1106
  /**
1016
1107
  * Restore a previously established session from stored delegation data.
1017
1108
  *
@@ -1046,7 +1137,32 @@ declare class TinyCloudNode {
1046
1137
  * for callers that need to round-trip the full session shape.
1047
1138
  */
1048
1139
  signature?: string;
1140
+ /**
1141
+ * The TinyCloud hosts this session was created against (from
1142
+ * {@link PersistedSessionData.tinycloudHosts}). When present they are
1143
+ * adopted so the restored session targets the same node as the
1144
+ * original sign-in — without this, service calls fall back to the
1145
+ * default host and the auth layer throws "TinyCloud hosts have not
1146
+ * been resolved". When absent (old persisted session) hosts resolve
1147
+ * lazily via the registry/fallback on the first host-needing call.
1148
+ */
1149
+ tinycloudHosts?: string[];
1049
1150
  }): Promise<void>;
1151
+ /**
1152
+ * Resolve the host a restored session should target.
1153
+ *
1154
+ * Mirrors fresh sign-in host resolution but for the restore path:
1155
+ * an explicit/pinned host always wins, then the hosts the session was
1156
+ * persisted with, then a lazy registry/fallback resolution for sessions
1157
+ * that predate the persisted `tinycloudHosts` field. Returns `undefined`
1158
+ * only when there's nothing to resolve from (no explicit host, no
1159
+ * persisted hosts, and no address/chainId) — in which case the existing
1160
+ * `config.host` (default) is left in place.
1161
+ *
1162
+ * Resolution failures are surfaced, not swallowed: a genuinely broken
1163
+ * registry lookup throws rather than silently falling back to a wrong host.
1164
+ */
1165
+ private resolveRestoredHost;
1050
1166
  /**
1051
1167
  * Resolve the currently-active TinyCloudSession, preferring the auth
1052
1168
  * layer's value (wallet mode) and falling back to the node-level