@tinycloud/node-sdk 1.7.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17027,13 +17027,63 @@ var require_utils2 = __commonJS({
17027
17027
  }
17028
17028
  });
17029
17029
 
17030
- // src/index.ts
17031
- import { TinyCloud as TinyCloud2 } from "@tinycloud/sdk-core";
17030
+ // src/NodeWasmBindings.ts
17031
+ import {
17032
+ invoke,
17033
+ prepareSession,
17034
+ completeSessionSetup,
17035
+ ensureEip55,
17036
+ makeSpaceId,
17037
+ createDelegation,
17038
+ generateHostSIWEMessage,
17039
+ siweToDelegationHeaders,
17040
+ protocolVersion,
17041
+ TCWSessionManager,
17042
+ initPanicHook,
17043
+ vault_encrypt,
17044
+ vault_decrypt,
17045
+ vault_derive_key,
17046
+ vault_x25519_from_seed,
17047
+ vault_x25519_dh,
17048
+ vault_random_bytes,
17049
+ vault_sha256
17050
+ } from "@tinycloud/node-sdk-wasm";
17051
+ var _NodeWasmBindings = class _NodeWasmBindings {
17052
+ constructor() {
17053
+ this.invoke = invoke;
17054
+ this.prepareSession = prepareSession;
17055
+ this.completeSessionSetup = completeSessionSetup;
17056
+ this.ensureEip55 = ensureEip55;
17057
+ this.makeSpaceId = makeSpaceId;
17058
+ this.createDelegation = createDelegation;
17059
+ this.generateHostSIWEMessage = generateHostSIWEMessage;
17060
+ this.siweToDelegationHeaders = siweToDelegationHeaders;
17061
+ this.protocolVersion = protocolVersion;
17062
+ // Vault crypto
17063
+ this.vault_encrypt = vault_encrypt;
17064
+ this.vault_decrypt = vault_decrypt;
17065
+ this.vault_derive_key = vault_derive_key;
17066
+ this.vault_x25519_from_seed = vault_x25519_from_seed;
17067
+ this.vault_x25519_dh = vault_x25519_dh;
17068
+ this.vault_random_bytes = vault_random_bytes;
17069
+ this.vault_sha256 = vault_sha256;
17070
+ if (!_NodeWasmBindings.panicHookInitialized) {
17071
+ initPanicHook();
17072
+ _NodeWasmBindings.panicHookInitialized = true;
17073
+ }
17074
+ }
17075
+ createSessionManager() {
17076
+ return new TCWSessionManager();
17077
+ }
17078
+ // No ensureInitialized needed — Node WASM is synchronous
17079
+ };
17080
+ _NodeWasmBindings.panicHookInitialized = false;
17081
+ var NodeWasmBindings = _NodeWasmBindings;
17032
17082
 
17033
17083
  // src/signers/PrivateKeySigner.ts
17034
17084
  import {
17035
17085
  signEthereumMessage,
17036
- ensureEip55
17086
+ ensureEip55 as ensureEip552
17037
17087
  } from "@tinycloud/node-sdk-wasm";
17038
17088
  var PrivateKeySigner = class {
17039
17089
  /**
@@ -17072,7 +17122,7 @@ var PrivateKeySigner = class {
17072
17122
  const pubKeyWithoutPrefix = publicKey.slice(4);
17073
17123
  const hash3 = keccak2563("0x" + pubKeyWithoutPrefix);
17074
17124
  const address = "0x" + hash3.slice(-40);
17075
- return ensureEip55(address);
17125
+ return ensureEip552(address);
17076
17126
  } catch {
17077
17127
  return "0x" + this.privateKeyHex.slice(0, 40);
17078
17128
  }
@@ -17096,6 +17146,37 @@ var PrivateKeySigner = class {
17096
17146
  }
17097
17147
  };
17098
17148
 
17149
+ // src/TinyCloudNode.ts
17150
+ import {
17151
+ TinyCloud,
17152
+ activateSessionWithHost as activateSessionWithHost2,
17153
+ KVService as KVService2,
17154
+ SQLService as SQLService2,
17155
+ DuckDbService as DuckDbService2,
17156
+ DataVaultService,
17157
+ createVaultCrypto,
17158
+ ServiceContext as ServiceContext2,
17159
+ SilentNotificationHandler,
17160
+ DelegationManager,
17161
+ SpaceService,
17162
+ CapabilityKeyRegistry,
17163
+ SharingService,
17164
+ UnsupportedFeatureError,
17165
+ makePublicSpaceId
17166
+ } from "@tinycloud/sdk-core";
17167
+
17168
+ // src/authorization/NodeUserAuthorization.ts
17169
+ import {
17170
+ fetchPeerId,
17171
+ submitHostDelegation,
17172
+ activateSessionWithHost,
17173
+ checkNodeInfo,
17174
+ AutoApproveSpaceCreationHandler
17175
+ } from "@tinycloud/sdk-core";
17176
+
17177
+ // src/authorization/strategies.ts
17178
+ var defaultSignStrategy = { type: "auto-sign" };
17179
+
17099
17180
  // src/storage/MemorySessionStorage.ts
17100
17181
  var MemorySessionStorage = class {
17101
17182
  constructor() {
@@ -17167,157 +17248,12 @@ var MemorySessionStorage = class {
17167
17248
  }
17168
17249
  };
17169
17250
 
17170
- // src/storage/FileSessionStorage.ts
17171
- import { validatePersistedSessionData } from "@tinycloud/sdk-core";
17172
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "fs";
17173
- import { join } from "path";
17174
- var FileSessionStorage = class {
17175
- /**
17176
- * Create a new FileSessionStorage.
17177
- *
17178
- * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)
17179
- */
17180
- constructor(baseDir) {
17181
- this.baseDir = baseDir || this.getDefaultDir();
17182
- this.ensureDirectoryExists();
17183
- }
17184
- /**
17185
- * Get the default session storage directory.
17186
- */
17187
- getDefaultDir() {
17188
- const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
17189
- return join(home, ".tinycloud", "sessions");
17190
- }
17191
- /**
17192
- * Ensure the storage directory exists.
17193
- */
17194
- ensureDirectoryExists() {
17195
- if (!existsSync(this.baseDir)) {
17196
- mkdirSync(this.baseDir, { recursive: true });
17197
- }
17198
- }
17199
- /**
17200
- * Get the file path for an address.
17201
- */
17202
- getFilePath(address) {
17203
- const normalizedAddress = address.toLowerCase();
17204
- const filename = `${normalizedAddress.replace("0x", "")}.json`;
17205
- return join(this.baseDir, filename);
17206
- }
17207
- /**
17208
- * Save a session for an address.
17209
- */
17210
- async save(address, session) {
17211
- const filePath = this.getFilePath(address);
17212
- const data = JSON.stringify(session, null, 2);
17213
- writeFileSync(filePath, data, "utf-8");
17214
- }
17215
- /**
17216
- * Load a session for an address.
17217
- */
17218
- async load(address) {
17219
- const filePath = this.getFilePath(address);
17220
- if (!existsSync(filePath)) {
17221
- return null;
17222
- }
17223
- try {
17224
- const data = readFileSync(filePath, "utf-8");
17225
- const parsed = JSON.parse(data);
17226
- const validation = validatePersistedSessionData(parsed);
17227
- if (!validation.ok) {
17228
- console.warn(`Invalid session data for ${address}:`, validation.error.message);
17229
- unlinkSync(filePath);
17230
- return null;
17231
- }
17232
- const session = validation.data;
17233
- const expiresAt = new Date(session.expiresAt);
17234
- if (expiresAt < /* @__PURE__ */ new Date()) {
17235
- unlinkSync(filePath);
17236
- return null;
17237
- }
17238
- return session;
17239
- } catch (error) {
17240
- try {
17241
- unlinkSync(filePath);
17242
- } catch {
17243
- }
17244
- return null;
17245
- }
17246
- }
17247
- /**
17248
- * Clear a session for an address.
17249
- */
17250
- async clear(address) {
17251
- const filePath = this.getFilePath(address);
17252
- if (existsSync(filePath)) {
17253
- unlinkSync(filePath);
17254
- }
17255
- }
17256
- /**
17257
- * Check if a session exists for an address.
17258
- */
17259
- exists(address) {
17260
- const filePath = this.getFilePath(address);
17261
- if (!existsSync(filePath)) {
17262
- return false;
17263
- }
17264
- try {
17265
- const data = readFileSync(filePath, "utf-8");
17266
- const session = JSON.parse(data);
17267
- const expiresAt = new Date(session.expiresAt);
17268
- if (expiresAt < /* @__PURE__ */ new Date()) {
17269
- unlinkSync(filePath);
17270
- return false;
17271
- }
17272
- return true;
17273
- } catch {
17274
- return false;
17275
- }
17276
- }
17277
- /**
17278
- * Check if file system storage is available.
17279
- */
17280
- isAvailable() {
17281
- try {
17282
- this.ensureDirectoryExists();
17283
- return existsSync(this.baseDir);
17284
- } catch {
17285
- return false;
17286
- }
17287
- }
17288
- };
17289
-
17290
17251
  // src/authorization/NodeUserAuthorization.ts
17291
- import {
17292
- fetchPeerId,
17293
- submitHostDelegation,
17294
- activateSessionWithHost,
17295
- checkNodeInfo
17296
- } from "@tinycloud/sdk-core";
17297
- import {
17298
- TCWSessionManager as SessionManager,
17299
- prepareSession,
17300
- completeSessionSetup,
17301
- ensureEip55 as ensureEip552,
17302
- makeSpaceId,
17303
- initPanicHook,
17304
- generateHostSIWEMessage,
17305
- siweToDelegationHeaders,
17306
- protocolVersion
17307
- } from "@tinycloud/node-sdk-wasm";
17308
-
17309
- // src/authorization/strategies.ts
17310
- var defaultSignStrategy = { type: "auto-sign" };
17311
-
17312
- // src/authorization/NodeUserAuthorization.ts
17313
- var _NodeUserAuthorization = class _NodeUserAuthorization {
17252
+ var NodeUserAuthorization = class {
17314
17253
  constructor(config) {
17315
17254
  this.extensions = [];
17316
17255
  this._nodeFeatures = [];
17317
- if (!_NodeUserAuthorization.wasmInitialized) {
17318
- initPanicHook();
17319
- _NodeUserAuthorization.wasmInitialized = true;
17320
- }
17256
+ this.wasm = config.wasmBindings;
17321
17257
  this.signer = config.signer;
17322
17258
  this.signStrategy = config.signStrategy ?? defaultSignStrategy;
17323
17259
  this.sessionStorage = config.sessionStorage ?? new MemorySessionStorage();
@@ -17360,9 +17296,10 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17360
17296
  };
17361
17297
  this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
17362
17298
  this.autoCreateSpace = config.autoCreateSpace ?? false;
17299
+ this.spaceCreationHandler = config.spaceCreationHandler;
17363
17300
  this.tinycloudHosts = config.tinycloudHosts ?? ["https://node.tinycloud.xyz"];
17364
17301
  this.enablePublicSpace = config.enablePublicSpace ?? true;
17365
- this.sessionManager = new SessionManager();
17302
+ this.sessionManager = this.wasm.createSessionManager();
17366
17303
  }
17367
17304
  /**
17368
17305
  * The current active session (web-core compatible).
@@ -17403,7 +17340,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17403
17340
  const host = this.tinycloudHosts[0];
17404
17341
  const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
17405
17342
  const peerId = await fetchPeerId(host, spaceId);
17406
- const siwe = generateHostSIWEMessage({
17343
+ const siwe = this.wasm.generateHostSIWEMessage({
17407
17344
  address: this._address,
17408
17345
  chainId: this._chainId,
17409
17346
  domain: this.domain,
@@ -17412,7 +17349,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17412
17349
  peerId
17413
17350
  });
17414
17351
  const signature2 = await this.signMessage(siwe);
17415
- const headers = siweToDelegationHeaders({ siwe, signature: signature2 });
17352
+ const headers = this.wasm.siweToDelegationHeaders({ siwe, signature: signature2 });
17416
17353
  const result = await submitHostDelegation(host, headers);
17417
17354
  return result.success;
17418
17355
  }
@@ -17441,17 +17378,35 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17441
17378
  host,
17442
17379
  this._tinyCloudSession.delegationHeader
17443
17380
  );
17381
+ const handler = this.spaceCreationHandler ?? (this.autoCreateSpace ? new AutoApproveSpaceCreationHandler() : void 0);
17382
+ const creationContext = {
17383
+ spaceId: primarySpaceId,
17384
+ address: this._address,
17385
+ chainId: this._chainId,
17386
+ host
17387
+ };
17444
17388
  if (result.success) {
17445
17389
  const primarySkipped = result.skipped?.includes(primarySpaceId);
17446
17390
  if (!primarySkipped) {
17447
17391
  return;
17448
17392
  }
17449
- if (!this.autoCreateSpace) {
17393
+ if (!handler) {
17394
+ return;
17395
+ }
17396
+ const confirmed = await handler.confirmSpaceCreation(creationContext);
17397
+ if (!confirmed) {
17450
17398
  return;
17451
17399
  }
17452
- const created = await this.hostSpace();
17453
- if (!created) {
17454
- throw new Error(`Failed to create space: ${primarySpaceId}`);
17400
+ try {
17401
+ const created = await this.hostSpace();
17402
+ if (!created) {
17403
+ const err = new Error(`Failed to create space: ${primarySpaceId}`);
17404
+ handler.onSpaceCreationFailed?.(creationContext, err);
17405
+ throw err;
17406
+ }
17407
+ } catch (error) {
17408
+ handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));
17409
+ throw error;
17455
17410
  }
17456
17411
  await new Promise((resolve) => setTimeout(resolve, 100));
17457
17412
  const retryResult = await activateSessionWithHost(
@@ -17459,19 +17414,33 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17459
17414
  this._tinyCloudSession.delegationHeader
17460
17415
  );
17461
17416
  if (!retryResult.success) {
17462
- throw new Error(
17417
+ const err = new Error(
17463
17418
  `Failed to activate session after creating space: ${retryResult.error}`
17464
17419
  );
17420
+ handler.onSpaceCreationFailed?.(creationContext, err);
17421
+ throw err;
17465
17422
  }
17423
+ handler.onSpaceCreated?.(creationContext);
17466
17424
  return;
17467
17425
  }
17468
17426
  if (result.status === 404) {
17469
- if (!this.autoCreateSpace) {
17427
+ if (!handler) {
17470
17428
  return;
17471
17429
  }
17472
- const created = await this.hostSpace();
17473
- if (!created) {
17474
- throw new Error(`Failed to create space: ${primarySpaceId}`);
17430
+ const confirmed = await handler.confirmSpaceCreation(creationContext);
17431
+ if (!confirmed) {
17432
+ return;
17433
+ }
17434
+ try {
17435
+ const created = await this.hostSpace();
17436
+ if (!created) {
17437
+ const err = new Error(`Failed to create space: ${primarySpaceId}`);
17438
+ handler.onSpaceCreationFailed?.(creationContext, err);
17439
+ throw err;
17440
+ }
17441
+ } catch (error) {
17442
+ handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));
17443
+ throw error;
17475
17444
  }
17476
17445
  await new Promise((resolve) => setTimeout(resolve, 100));
17477
17446
  const retryResult = await activateSessionWithHost(
@@ -17479,10 +17448,13 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17479
17448
  this._tinyCloudSession.delegationHeader
17480
17449
  );
17481
17450
  if (!retryResult.success) {
17482
- throw new Error(
17451
+ const err = new Error(
17483
17452
  `Failed to activate session after creating space: ${retryResult.error}`
17484
17453
  );
17454
+ handler.onSpaceCreationFailed?.(creationContext, err);
17455
+ throw err;
17485
17456
  }
17457
+ handler.onSpaceCreated?.(creationContext);
17486
17458
  return;
17487
17459
  }
17488
17460
  throw new Error(`Failed to activate session: ${result.error}`);
@@ -17499,7 +17471,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17499
17471
  async signIn() {
17500
17472
  this._address = await this.signer.getAddress();
17501
17473
  this._chainId = await this.signer.getChainId();
17502
- const address = ensureEip552(this._address);
17474
+ const address = this.wasm.ensureEip55(this._address);
17503
17475
  const chainId = this._chainId;
17504
17476
  const keyId = `session-${Date.now()}`;
17505
17477
  this.sessionManager.renameSessionKeyId("default", keyId);
@@ -17508,10 +17480,10 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17508
17480
  throw new Error("Failed to create session key");
17509
17481
  }
17510
17482
  const jwk = JSON.parse(jwkString);
17511
- const spaceId = makeSpaceId(address, chainId, this.spacePrefix);
17483
+ const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);
17512
17484
  const now = /* @__PURE__ */ new Date();
17513
17485
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
17514
- const prepared = prepareSession({
17486
+ const prepared = this.wasm.prepareSession({
17515
17487
  abilities: this.defaultActions,
17516
17488
  address,
17517
17489
  chainId,
@@ -17527,7 +17499,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17527
17499
  message: prepared.siwe,
17528
17500
  type: "siwe"
17529
17501
  });
17530
- const session = completeSessionSetup({
17502
+ const session = this.wasm.completeSessionSetup({
17531
17503
  ...prepared,
17532
17504
  signature: signature2
17533
17505
  });
@@ -17539,7 +17511,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17539
17511
  siwe: prepared.siwe,
17540
17512
  signature: signature2
17541
17513
  };
17542
- const spacesMetadata = this.enablePublicSpace ? { public: makeSpaceId(address, chainId, "public") } : void 0;
17514
+ const spacesMetadata = this.enablePublicSpace ? { public: this.wasm.makeSpaceId(address, chainId, "public") } : void 0;
17543
17515
  const tinyCloudSession = {
17544
17516
  address,
17545
17517
  chainId,
@@ -17575,7 +17547,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17575
17547
  this._tinyCloudSession = tinyCloudSession;
17576
17548
  this._address = address;
17577
17549
  this._chainId = chainId;
17578
- const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], protocolVersion());
17550
+ const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());
17579
17551
  this._nodeFeatures = nodeInfo.features;
17580
17552
  for (const ext of this.extensions) {
17581
17553
  if (ext.afterSignIn) {
@@ -17638,7 +17610,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17638
17610
  * ```
17639
17611
  */
17640
17612
  async prepareSessionForSigning() {
17641
- const address = ensureEip552(await this.signer.getAddress());
17613
+ const address = this.wasm.ensureEip55(await this.signer.getAddress());
17642
17614
  const chainId = await this.signer.getChainId();
17643
17615
  const keyId = `session-${Date.now()}`;
17644
17616
  this.sessionManager.renameSessionKeyId("default", keyId);
@@ -17647,10 +17619,10 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17647
17619
  throw new Error("Failed to create session key");
17648
17620
  }
17649
17621
  const jwk = JSON.parse(jwkString);
17650
- const spaceId = makeSpaceId(address, chainId, this.spacePrefix);
17622
+ const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);
17651
17623
  const now = /* @__PURE__ */ new Date();
17652
17624
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
17653
- const prepared = prepareSession({
17625
+ const prepared = this.wasm.prepareSession({
17654
17626
  abilities: this.defaultActions,
17655
17627
  address,
17656
17628
  chainId,
@@ -17680,11 +17652,11 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17680
17652
  * @param jwk - The JWK from `prepareSessionForSigning()`
17681
17653
  */
17682
17654
  async signInWithPreparedSession(prepared, signature2, keyId, jwk) {
17683
- const session = completeSessionSetup({
17655
+ const session = this.wasm.completeSessionSetup({
17684
17656
  ...prepared,
17685
17657
  signature: signature2
17686
17658
  });
17687
- const address = ensureEip552(await this.signer.getAddress());
17659
+ const address = this.wasm.ensureEip55(await this.signer.getAddress());
17688
17660
  const chainId = await this.signer.getChainId();
17689
17661
  const clientSession = {
17690
17662
  address,
@@ -17694,7 +17666,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17694
17666
  siwe: prepared.siwe,
17695
17667
  signature: signature2
17696
17668
  };
17697
- const spacesMetadata = this.enablePublicSpace ? { public: makeSpaceId(address, chainId, "public") } : void 0;
17669
+ const spacesMetadata = this.enablePublicSpace ? { public: this.wasm.makeSpaceId(address, chainId, "public") } : void 0;
17698
17670
  const tinyCloudSession = {
17699
17671
  address,
17700
17672
  chainId,
@@ -17734,7 +17706,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17734
17706
  this._tinyCloudSession = tinyCloudSession;
17735
17707
  this._address = address;
17736
17708
  this._chainId = chainId;
17737
- const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], protocolVersion());
17709
+ const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());
17738
17710
  this._nodeFeatures = nodeInfo.features;
17739
17711
  for (const ext of this.extensions) {
17740
17712
  if (ext.afterSignIn) {
@@ -17811,43 +17783,6 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17811
17783
  });
17812
17784
  }
17813
17785
  };
17814
- /** Flag to ensure WASM panic hook is only initialized once */
17815
- _NodeUserAuthorization.wasmInitialized = false;
17816
- var NodeUserAuthorization = _NodeUserAuthorization;
17817
-
17818
- // src/TinyCloudNode.ts
17819
- import {
17820
- TinyCloud,
17821
- activateSessionWithHost as activateSessionWithHost2,
17822
- KVService as KVService2,
17823
- SQLService as SQLService2,
17824
- DuckDbService as DuckDbService2,
17825
- DataVaultService,
17826
- createVaultCrypto,
17827
- ServiceContext as ServiceContext2,
17828
- DelegationManager,
17829
- SpaceService,
17830
- CapabilityKeyRegistry,
17831
- SharingService,
17832
- UnsupportedFeatureError,
17833
- makePublicSpaceId
17834
- } from "@tinycloud/sdk-core";
17835
- import {
17836
- TCWSessionManager as SessionManager2,
17837
- prepareSession as prepareSession2,
17838
- completeSessionSetup as completeSessionSetup2,
17839
- ensureEip55 as ensureEip553,
17840
- invoke as invoke2,
17841
- initPanicHook as initPanicHook2,
17842
- createDelegation,
17843
- vault_encrypt,
17844
- vault_decrypt,
17845
- vault_derive_key,
17846
- vault_x25519_from_seed,
17847
- vault_x25519_dh,
17848
- vault_random_bytes,
17849
- vault_sha256
17850
- } from "@tinycloud/node-sdk-wasm";
17851
17786
 
17852
17787
  // src/DelegatedAccess.ts
17853
17788
  import {
@@ -17856,14 +17791,13 @@ import {
17856
17791
  DuckDbService,
17857
17792
  ServiceContext
17858
17793
  } from "@tinycloud/sdk-core";
17859
- import { invoke } from "@tinycloud/node-sdk-wasm";
17860
17794
  var DelegatedAccess = class {
17861
- constructor(session, delegation, host) {
17795
+ constructor(session, delegation, host, invoke2) {
17862
17796
  this.session = session;
17863
17797
  this._delegation = delegation;
17864
17798
  this.host = host;
17865
17799
  this._serviceContext = new ServiceContext({
17866
- invoke,
17800
+ invoke: invoke2,
17867
17801
  fetch: globalThis.fetch.bind(globalThis),
17868
17802
  hosts: [host]
17869
17803
  });
@@ -17981,7 +17915,7 @@ var WasmKeyProvider = class {
17981
17915
  * @returns Array of key IDs
17982
17916
  */
17983
17917
  listKeys() {
17984
- const keys = this.sessionManager.listSessionKeys();
17918
+ const keys = this.sessionManager.listSessionKeys?.();
17985
17919
  return Array.isArray(keys) ? keys : [];
17986
17920
  }
17987
17921
  /**
@@ -18001,7 +17935,7 @@ function createWasmKeyProvider(sessionManager) {
18001
17935
 
18002
17936
  // src/TinyCloudNode.ts
18003
17937
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
18004
- var _TinyCloudNode = class _TinyCloudNode {
17938
+ var TinyCloudNode = class _TinyCloudNode {
18005
17939
  /**
18006
17940
  * Create a new TinyCloudNode instance.
18007
17941
  *
@@ -18030,15 +17964,20 @@ var _TinyCloudNode = class _TinyCloudNode {
18030
17964
  this.auth = null;
18031
17965
  this.tc = null;
18032
17966
  this._chainId = 1;
18033
- if (!_TinyCloudNode.wasmInitialized) {
18034
- initPanicHook2();
18035
- _TinyCloudNode.wasmInitialized = true;
18036
- }
18037
17967
  this.config = {
18038
17968
  ...config,
18039
17969
  host: config.host ?? DEFAULT_HOST
18040
17970
  };
18041
- this.sessionManager = new SessionManager2();
17971
+ if (config.wasmBindings) {
17972
+ this.wasmBindings = config.wasmBindings;
17973
+ } else if (_TinyCloudNode.nodeDefaults) {
17974
+ this.wasmBindings = _TinyCloudNode.nodeDefaults.createWasmBindings();
17975
+ } else {
17976
+ throw new Error(
17977
+ "wasmBindings must be provided in config. Import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
17978
+ );
17979
+ }
17980
+ this.sessionManager = this.wasmBindings.createSessionManager();
18042
17981
  const defaultKeyId = "default";
18043
17982
  let jwkStr = this.sessionManager.jwk(defaultKeyId);
18044
17983
  if (jwkStr) {
@@ -18055,10 +17994,11 @@ var _TinyCloudNode = class _TinyCloudNode {
18055
17994
  this._keyProvider = new WasmKeyProvider({
18056
17995
  sessionManager: this.sessionManager
18057
17996
  });
17997
+ this.notificationHandler = config.notificationHandler ?? new SilentNotificationHandler();
18058
17998
  this._sharingService = new SharingService({
18059
17999
  hosts: [this.config.host],
18060
18000
  // session: undefined - not needed for receive()
18061
- invoke: invoke2,
18001
+ invoke: this.wasmBindings.invoke,
18062
18002
  fetch: globalThis.fetch.bind(globalThis),
18063
18003
  keyProvider: this._keyProvider,
18064
18004
  registry: this._capabilityRegistry,
@@ -18076,27 +18016,48 @@ var _TinyCloudNode = class _TinyCloudNode {
18076
18016
  return kvService;
18077
18017
  }
18078
18018
  });
18079
- if (config.privateKey) {
18080
- this.signer = new PrivateKeySigner(config.privateKey, this._chainId);
18081
- const host = this.config.host;
18082
- const domain = config.domain ?? new URL(host).hostname;
18083
- this.auth = new NodeUserAuthorization({
18084
- signer: this.signer,
18085
- signStrategy: { type: "auto-sign" },
18086
- sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
18087
- domain,
18088
- spacePrefix: config.prefix,
18089
- sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
18090
- tinycloudHosts: [host],
18091
- autoCreateSpace: config.autoCreateSpace,
18092
- enablePublicSpace: config.enablePublicSpace ?? true
18093
- });
18094
- this.tc = new TinyCloud(this.auth);
18019
+ if (config.signer) {
18020
+ this.signer = config.signer;
18021
+ this.setupAuth(config);
18022
+ } else if (config.privateKey) {
18023
+ if (!_TinyCloudNode.nodeDefaults) {
18024
+ throw new Error(
18025
+ "privateKey requires PrivateKeySigner. Either provide a signer in config, or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
18026
+ );
18027
+ }
18028
+ this.signer = _TinyCloudNode.nodeDefaults.createSigner(config.privateKey, this._chainId);
18029
+ this.setupAuth(config);
18095
18030
  }
18096
18031
  }
18032
+ /** @internal Register Node.js-specific defaults (NodeWasmBindings, PrivateKeySigner) */
18033
+ static registerNodeDefaults(defaults) {
18034
+ _TinyCloudNode.nodeDefaults = defaults;
18035
+ }
18097
18036
  get nodeFeatures() {
18098
18037
  return this.auth?.nodeFeatures ?? [];
18099
18038
  }
18039
+ /**
18040
+ * Set up authorization handler and TinyCloud instance.
18041
+ * @internal
18042
+ */
18043
+ setupAuth(config) {
18044
+ const host = this.config.host;
18045
+ const domain = config.domain ?? new URL(host).hostname;
18046
+ this.auth = new NodeUserAuthorization({
18047
+ signer: this.signer,
18048
+ signStrategy: { type: "auto-sign" },
18049
+ wasmBindings: this.wasmBindings,
18050
+ sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
18051
+ domain,
18052
+ spacePrefix: config.prefix,
18053
+ sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
18054
+ tinycloudHosts: [host],
18055
+ autoCreateSpace: config.autoCreateSpace,
18056
+ enablePublicSpace: config.enablePublicSpace ?? true,
18057
+ spaceCreationHandler: config.spaceCreationHandler
18058
+ });
18059
+ this.tc = new TinyCloud(this.auth);
18060
+ }
18100
18061
  /**
18101
18062
  * Get the primary identity DID for this user.
18102
18063
  * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
@@ -18158,6 +18119,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18158
18119
  "Cannot signIn() in session-only mode. Provide a privateKey in config to create your own space."
18159
18120
  );
18160
18121
  }
18122
+ await this.wasmBindings.ensureInitialized?.();
18161
18123
  this._address = await this.signer.getAddress();
18162
18124
  this._chainId = await this.signer.getChainId();
18163
18125
  this._kv = void 0;
@@ -18166,6 +18128,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18166
18128
  this._serviceContext = void 0;
18167
18129
  await this.tc.signIn();
18168
18130
  this.initializeServices();
18131
+ this.notificationHandler.success("Successfully signed in");
18169
18132
  }
18170
18133
  /**
18171
18134
  * Restore a previously established session from stored delegation data.
@@ -18177,6 +18140,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18177
18140
  * @param sessionData - The stored delegation data from the browser flow
18178
18141
  */
18179
18142
  async restoreSession(sessionData) {
18143
+ await this.wasmBindings.ensureInitialized?.();
18180
18144
  this._kv = void 0;
18181
18145
  this._sql = void 0;
18182
18146
  this._duckdb = void 0;
@@ -18188,7 +18152,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18188
18152
  this._chainId = sessionData.chainId;
18189
18153
  }
18190
18154
  this._serviceContext = new ServiceContext2({
18191
- invoke: invoke2,
18155
+ invoke: this.wasmBindings.invoke,
18192
18156
  fetch: globalThis.fetch.bind(globalThis),
18193
18157
  hosts: [this.config.host]
18194
18158
  });
@@ -18209,6 +18173,43 @@ var _TinyCloudNode = class _TinyCloudNode {
18209
18173
  jwk: sessionData.jwk
18210
18174
  };
18211
18175
  this._serviceContext.setSession(serviceSession);
18176
+ const wasm = this.wasmBindings;
18177
+ const vaultCrypto = createVaultCrypto({
18178
+ vault_encrypt: wasm.vault_encrypt,
18179
+ vault_decrypt: wasm.vault_decrypt,
18180
+ vault_derive_key: wasm.vault_derive_key,
18181
+ vault_x25519_from_seed: wasm.vault_x25519_from_seed,
18182
+ vault_x25519_dh: wasm.vault_x25519_dh,
18183
+ vault_random_bytes: wasm.vault_random_bytes,
18184
+ vault_sha256: wasm.vault_sha256
18185
+ });
18186
+ const self2 = this;
18187
+ this._vault = new DataVaultService({
18188
+ spaceId: sessionData.spaceId,
18189
+ crypto: vaultCrypto,
18190
+ tc: {
18191
+ kv: this._kv,
18192
+ ensurePublicSpace: async () => {
18193
+ try {
18194
+ await self2.ensurePublicSpace();
18195
+ return { ok: true, data: void 0 };
18196
+ } catch (error) {
18197
+ return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
18198
+ }
18199
+ },
18200
+ get publicKV() {
18201
+ return self2._publicKV ?? self2.tc.publicKV;
18202
+ },
18203
+ readPublicSpace: (host, spaceId, key2) => TinyCloud.readPublicSpace(host, spaceId, key2),
18204
+ makePublicSpaceId: TinyCloud.makePublicSpaceId,
18205
+ did: this.did,
18206
+ address: sessionData.address ?? this._address ?? "",
18207
+ chainId: sessionData.chainId ?? this._chainId,
18208
+ hosts: [this.config.host]
18209
+ }
18210
+ });
18211
+ this._vault.initialize(this._serviceContext);
18212
+ this._serviceContext.registerService("vault", this._vault);
18212
18213
  this.initializeV2Services(serviceSession);
18213
18214
  }
18214
18215
  /**
@@ -18243,17 +18244,61 @@ var _TinyCloudNode = class _TinyCloudNode {
18243
18244
  const prefix = options?.prefix ?? "default";
18244
18245
  const host = this.config.host;
18245
18246
  const domain = new URL(host).hostname;
18246
- this.signer = new PrivateKeySigner(privateKey);
18247
+ if (!_TinyCloudNode.nodeDefaults) {
18248
+ throw new Error(
18249
+ "connectWallet() requires PrivateKeySigner. Use connectSigner() instead, or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
18250
+ );
18251
+ }
18252
+ this.signer = _TinyCloudNode.nodeDefaults.createSigner(privateKey);
18247
18253
  this.auth = new NodeUserAuthorization({
18248
18254
  signer: this.signer,
18249
18255
  signStrategy: { type: "auto-sign" },
18256
+ wasmBindings: this.wasmBindings,
18250
18257
  sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
18251
18258
  domain,
18252
18259
  spacePrefix: prefix,
18253
18260
  sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
18254
18261
  tinycloudHosts: [host],
18255
18262
  autoCreateSpace: this.config.autoCreateSpace,
18256
- enablePublicSpace: this.config.enablePublicSpace ?? true
18263
+ enablePublicSpace: this.config.enablePublicSpace ?? true,
18264
+ spaceCreationHandler: this.config.spaceCreationHandler
18265
+ });
18266
+ this.tc = new TinyCloud(this.auth);
18267
+ this.config.prefix = prefix;
18268
+ }
18269
+ /**
18270
+ * Connect any ISigner to upgrade from session-only mode to wallet mode.
18271
+ *
18272
+ * Same as connectWallet() but accepts any ISigner implementation instead
18273
+ * of a raw private key string. Use this for browser wallets, hardware wallets,
18274
+ * or custom signing backends.
18275
+ *
18276
+ * Note: This does NOT automatically sign in. Call signIn() after connecting.
18277
+ *
18278
+ * @param signer - Any ISigner implementation
18279
+ * @param options - Optional configuration
18280
+ * @param options.prefix - Space name prefix (defaults to "default")
18281
+ */
18282
+ connectSigner(signer, options) {
18283
+ if (this.signer) {
18284
+ throw new Error("Signer already connected. Cannot connect another signer.");
18285
+ }
18286
+ const prefix = options?.prefix ?? "default";
18287
+ const host = this.config.host;
18288
+ const domain = new URL(host).hostname;
18289
+ this.signer = signer;
18290
+ this.auth = new NodeUserAuthorization({
18291
+ signer: this.signer,
18292
+ signStrategy: { type: "auto-sign" },
18293
+ wasmBindings: this.wasmBindings,
18294
+ sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
18295
+ domain,
18296
+ spacePrefix: prefix,
18297
+ sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
18298
+ tinycloudHosts: [host],
18299
+ autoCreateSpace: this.config.autoCreateSpace,
18300
+ enablePublicSpace: this.config.enablePublicSpace ?? true,
18301
+ spaceCreationHandler: this.config.spaceCreationHandler
18257
18302
  });
18258
18303
  this.tc = new TinyCloud(this.auth);
18259
18304
  this.config.prefix = prefix;
@@ -18267,9 +18312,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18267
18312
  if (!session) {
18268
18313
  return;
18269
18314
  }
18270
- this.tc.initializeServices(invoke2, [this.config.host]);
18315
+ this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
18271
18316
  this._serviceContext = new ServiceContext2({
18272
- invoke: invoke2,
18317
+ invoke: this.wasmBindings.invoke,
18273
18318
  fetch: globalThis.fetch.bind(globalThis),
18274
18319
  hosts: [this.config.host]
18275
18320
  });
@@ -18296,14 +18341,15 @@ var _TinyCloudNode = class _TinyCloudNode {
18296
18341
  };
18297
18342
  this._serviceContext.setSession(serviceSession);
18298
18343
  this.tc.serviceContext.setSession(serviceSession);
18344
+ const wasm = this.wasmBindings;
18299
18345
  const vaultCrypto = createVaultCrypto({
18300
- vault_encrypt,
18301
- vault_decrypt,
18302
- vault_derive_key,
18303
- vault_x25519_from_seed,
18304
- vault_x25519_dh,
18305
- vault_random_bytes,
18306
- vault_sha256
18346
+ vault_encrypt: wasm.vault_encrypt,
18347
+ vault_decrypt: wasm.vault_decrypt,
18348
+ vault_derive_key: wasm.vault_derive_key,
18349
+ vault_x25519_from_seed: wasm.vault_x25519_from_seed,
18350
+ vault_x25519_dh: wasm.vault_x25519_dh,
18351
+ vault_random_bytes: wasm.vault_random_bytes,
18352
+ vault_sha256: wasm.vault_sha256
18307
18353
  });
18308
18354
  const self2 = this;
18309
18355
  this._vault = new DataVaultService({
@@ -18416,13 +18462,13 @@ var _TinyCloudNode = class _TinyCloudNode {
18416
18462
  this._delegationManager = new DelegationManager({
18417
18463
  hosts: [this.config.host],
18418
18464
  session: serviceSession,
18419
- invoke: invoke2,
18465
+ invoke: this.wasmBindings.invoke,
18420
18466
  fetch: globalThis.fetch.bind(globalThis)
18421
18467
  });
18422
18468
  this._spaceService = new SpaceService({
18423
18469
  hosts: [this.config.host],
18424
18470
  session: serviceSession,
18425
- invoke: invoke2,
18471
+ invoke: this.wasmBindings.invoke,
18426
18472
  fetch: globalThis.fetch.bind(globalThis),
18427
18473
  capabilityRegistry: this._capabilityRegistry,
18428
18474
  userDid: this.did,
@@ -18483,7 +18529,10 @@ var _TinyCloudNode = class _TinyCloudNode {
18483
18529
  delegationManager: this._delegationManager,
18484
18530
  sessionExpiry: this.getSessionExpiry(),
18485
18531
  // WASM-based delegation creation (preferred - no server roundtrip)
18486
- createDelegationWasm: (params) => this.createDelegationWrapper(params)
18532
+ createDelegationWasm: (params) => this.createDelegationWrapper(params),
18533
+ // Root delegation for long-lived share links (bypasses session expiry)
18534
+ // In node-sdk we have direct signer access, so no popup needed
18535
+ onRootDelegationNeeded: this.signer ? async (params) => this.createRootDelegationForSharing(params) : void 0
18487
18536
  });
18488
18537
  this._spaceService.updateConfig({
18489
18538
  sharingService: this._sharingService
@@ -18510,7 +18559,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18510
18559
  spaceId: params.session.spaceId,
18511
18560
  verificationMethod: params.session.verificationMethod
18512
18561
  };
18513
- const result = createDelegation(
18562
+ const result = this.wasmBindings.createDelegation(
18514
18563
  wasmSession,
18515
18564
  params.delegateDID,
18516
18565
  params.spaceId,
@@ -18528,6 +18577,67 @@ var _TinyCloudNode = class _TinyCloudNode {
18528
18577
  expiry: new Date(result.expiry * 1e3)
18529
18578
  };
18530
18579
  }
18580
+ /**
18581
+ * Create a direct root delegation from the wallet to a share key.
18582
+ * This bypasses the session delegation chain, allowing share links
18583
+ * with expiry longer than the current session.
18584
+ * @internal
18585
+ */
18586
+ async createRootDelegationForSharing(params) {
18587
+ if (!this.signer) {
18588
+ return void 0;
18589
+ }
18590
+ const session = this.auth?.tinyCloudSession;
18591
+ if (!session) {
18592
+ return void 0;
18593
+ }
18594
+ try {
18595
+ const host = this.config.host;
18596
+ const now = /* @__PURE__ */ new Date();
18597
+ const abilities = {
18598
+ kv: {
18599
+ [params.path]: params.actions
18600
+ }
18601
+ };
18602
+ const prepared = this.wasmBindings.prepareSession({
18603
+ abilities,
18604
+ address: this.wasmBindings.ensureEip55(session.address),
18605
+ chainId: session.chainId,
18606
+ domain: new URL(host).hostname,
18607
+ issuedAt: now.toISOString(),
18608
+ expirationTime: params.requestedExpiry.toISOString(),
18609
+ spaceId: params.spaceId,
18610
+ delegateUri: params.shareKeyDID
18611
+ });
18612
+ const signature2 = await this.signer.signMessage(prepared.siwe);
18613
+ const delegationSession = this.wasmBindings.completeSessionSetup({
18614
+ ...prepared,
18615
+ signature: signature2
18616
+ });
18617
+ const activateResult = await activateSessionWithHost2(
18618
+ host,
18619
+ delegationSession.delegationHeader
18620
+ );
18621
+ if (!activateResult.success) {
18622
+ return void 0;
18623
+ }
18624
+ return {
18625
+ cid: delegationSession.delegationCid,
18626
+ delegateDID: params.shareKeyDID,
18627
+ delegatorDID: `did:pkh:eip155:${session.chainId}:${session.address}`,
18628
+ spaceId: params.spaceId,
18629
+ path: params.path,
18630
+ actions: params.actions,
18631
+ expiry: params.requestedExpiry,
18632
+ isRevoked: false,
18633
+ allowSubDelegation: true,
18634
+ createdAt: now,
18635
+ authHeader: delegationSession.delegationHeader.Authorization
18636
+ };
18637
+ } catch {
18638
+ return void 0;
18639
+ }
18640
+ }
18531
18641
  /**
18532
18642
  * Track a received delegation in the capability registry.
18533
18643
  * @internal
@@ -18798,9 +18908,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18798
18908
  const now = /* @__PURE__ */ new Date();
18799
18909
  const expiryMs = 60 * 60 * 1e3;
18800
18910
  const expirationTime = new Date(now.getTime() + expiryMs);
18801
- const prepared = prepareSession2({
18911
+ const prepared = this.wasmBindings.prepareSession({
18802
18912
  abilities,
18803
- address: ensureEip553(this.session.address),
18913
+ address: this.wasmBindings.ensureEip55(this.session.address),
18804
18914
  chainId: this.session.chainId,
18805
18915
  domain: new URL(this.config.host).hostname,
18806
18916
  issuedAt: now.toISOString(),
@@ -18810,7 +18920,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18810
18920
  parents: [this.session.delegationCid]
18811
18921
  });
18812
18922
  const signature2 = await this.signer.signMessage(prepared.siwe);
18813
- const delegationSession = completeSessionSetup2({
18923
+ const delegationSession = this.wasmBindings.completeSessionSetup({
18814
18924
  ...prepared,
18815
18925
  signature: signature2
18816
18926
  });
@@ -18843,7 +18953,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18843
18953
  if (this._serviceContext) {
18844
18954
  const publicKV = new KVService2({ prefix: "" });
18845
18955
  const publicContext = new ServiceContext2({
18846
- invoke: invoke2,
18956
+ invoke: this.wasmBindings.invoke,
18847
18957
  fetch: this._serviceContext.fetch,
18848
18958
  hosts: this._serviceContext.hosts
18849
18959
  });
@@ -18944,6 +19054,11 @@ var _TinyCloudNode = class _TinyCloudNode {
18944
19054
  if (!session) {
18945
19055
  throw new Error("Not signed in. Call signIn() first.");
18946
19056
  }
19057
+ if (params.delegateDID.endsWith(".eth") && this.config.ensResolver) {
19058
+ const address = await this.config.ensResolver.resolveAddress(params.delegateDID);
19059
+ if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);
19060
+ params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };
19061
+ }
18947
19062
  const abilities = {};
18948
19063
  const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
18949
19064
  const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
@@ -18960,9 +19075,9 @@ var _TinyCloudNode = class _TinyCloudNode {
18960
19075
  const now = /* @__PURE__ */ new Date();
18961
19076
  const expiryMs = params.expiryMs ?? 60 * 60 * 1e3;
18962
19077
  const expirationTime = new Date(now.getTime() + expiryMs);
18963
- const prepared = prepareSession2({
19078
+ const prepared = this.wasmBindings.prepareSession({
18964
19079
  abilities,
18965
- address: ensureEip553(session.address),
19080
+ address: this.wasmBindings.ensureEip55(session.address),
18966
19081
  chainId: session.chainId,
18967
19082
  domain: new URL(this.config.host).hostname,
18968
19083
  issuedAt: now.toISOString(),
@@ -18972,7 +19087,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18972
19087
  parents: [session.delegationCid]
18973
19088
  });
18974
19089
  const signature2 = await this.signer.signMessage(prepared.siwe);
18975
- const delegationSession = completeSessionSetup2({
19090
+ const delegationSession = this.wasmBindings.completeSessionSetup({
18976
19091
  ...prepared,
18977
19092
  signature: signature2
18978
19093
  });
@@ -18999,15 +19114,15 @@ var _TinyCloudNode = class _TinyCloudNode {
18999
19114
  const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
19000
19115
  if (hasKvActions && params.includePublicSpace !== false) {
19001
19116
  const publicSpaceId = makePublicSpaceId(
19002
- ensureEip553(session.address),
19117
+ this.wasmBindings.ensureEip55(session.address),
19003
19118
  session.chainId
19004
19119
  );
19005
19120
  const publicAbilities = {
19006
19121
  kv: { "": ["tinycloud.kv/get", "tinycloud.kv/put", "tinycloud.kv/metadata"] }
19007
19122
  };
19008
- const publicPrepared = prepareSession2({
19123
+ const publicPrepared = this.wasmBindings.prepareSession({
19009
19124
  abilities: publicAbilities,
19010
- address: ensureEip553(session.address),
19125
+ address: this.wasmBindings.ensureEip55(session.address),
19011
19126
  chainId: session.chainId,
19012
19127
  domain: new URL(this.config.host).hostname,
19013
19128
  issuedAt: now.toISOString(),
@@ -19017,7 +19132,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19017
19132
  parents: [session.delegationCid]
19018
19133
  });
19019
19134
  const publicSignature = await this.signer.signMessage(publicPrepared.siwe);
19020
- const publicSession = completeSessionSetup2({
19135
+ const publicSession = this.wasmBindings.completeSessionSetup({
19021
19136
  ...publicPrepared,
19022
19137
  signature: publicSignature
19023
19138
  });
@@ -19081,7 +19196,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19081
19196
  // Not used in session-only mode
19082
19197
  };
19083
19198
  this.trackReceivedDelegation(delegation, this.sessionKeyJwk);
19084
- return new DelegatedAccess(session2, delegation, targetHost);
19199
+ return new DelegatedAccess(session2, delegation, targetHost, this.wasmBindings.invoke);
19085
19200
  }
19086
19201
  const mySession = this.auth?.tinyCloudSession;
19087
19202
  if (!mySession) {
@@ -19104,9 +19219,9 @@ var _TinyCloudNode = class _TinyCloudNode {
19104
19219
  const now = /* @__PURE__ */ new Date();
19105
19220
  const maxExpiry = new Date(now.getTime() + 60 * 60 * 1e3);
19106
19221
  const expirationTime = delegation.expiry < maxExpiry ? delegation.expiry : maxExpiry;
19107
- const prepared = prepareSession2({
19222
+ const prepared = this.wasmBindings.prepareSession({
19108
19223
  abilities,
19109
- address: ensureEip553(mySession.address),
19224
+ address: this.wasmBindings.ensureEip55(mySession.address),
19110
19225
  chainId: mySession.chainId,
19111
19226
  domain: new URL(targetHost).hostname,
19112
19227
  issuedAt: now.toISOString(),
@@ -19116,7 +19231,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19116
19231
  parents: [delegation.cid]
19117
19232
  });
19118
19233
  const signature2 = await this.signer.signMessage(prepared.siwe);
19119
- const invokerSession = completeSessionSetup2({
19234
+ const invokerSession = this.wasmBindings.completeSessionSetup({
19120
19235
  ...prepared,
19121
19236
  signature: signature2
19122
19237
  });
@@ -19140,7 +19255,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19140
19255
  signature: signature2
19141
19256
  };
19142
19257
  this.trackReceivedDelegation(delegation, jwk);
19143
- return new DelegatedAccess(session, delegation, targetHost);
19258
+ return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);
19144
19259
  }
19145
19260
  /**
19146
19261
  * Create a sub-delegation from a received delegation.
@@ -19193,9 +19308,9 @@ var _TinyCloudNode = class _TinyCloudNode {
19193
19308
  abilities.duckdb = { [params.path]: duckdbActions };
19194
19309
  }
19195
19310
  const targetHost = parentDelegation.host ?? this.config.host;
19196
- const prepared = prepareSession2({
19311
+ const prepared = this.wasmBindings.prepareSession({
19197
19312
  abilities,
19198
- address: ensureEip553(this._address),
19313
+ address: this.wasmBindings.ensureEip55(this._address),
19199
19314
  chainId: this._chainId,
19200
19315
  domain: new URL(targetHost).hostname,
19201
19316
  issuedAt: now.toISOString(),
@@ -19205,7 +19320,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19205
19320
  parents: [parentDelegation.cid]
19206
19321
  });
19207
19322
  const signature2 = await this.signer.signMessage(prepared.siwe);
19208
- const subDelegationSession = completeSessionSetup2({
19323
+ const subDelegationSession = this.wasmBindings.completeSessionSetup({
19209
19324
  ...prepared,
19210
19325
  signature: signature2
19211
19326
  });
@@ -19231,9 +19346,140 @@ var _TinyCloudNode = class _TinyCloudNode {
19231
19346
  };
19232
19347
  }
19233
19348
  };
19234
- /** Flag to ensure WASM panic hook is only initialized once */
19235
- _TinyCloudNode.wasmInitialized = false;
19236
- var TinyCloudNode = _TinyCloudNode;
19349
+
19350
+ // src/nodeDefaults.ts
19351
+ TinyCloudNode.registerNodeDefaults({
19352
+ createWasmBindings: () => new NodeWasmBindings(),
19353
+ createSigner: (privateKey, chainId) => new PrivateKeySigner(privateKey, chainId)
19354
+ });
19355
+
19356
+ // src/index.ts
19357
+ import { TinyCloud as TinyCloud2 } from "@tinycloud/sdk-core";
19358
+ import {
19359
+ SilentNotificationHandler as SilentNotificationHandler2,
19360
+ AutoApproveSpaceCreationHandler as AutoApproveSpaceCreationHandler2,
19361
+ defaultSpaceCreationHandler
19362
+ } from "@tinycloud/sdk-core";
19363
+
19364
+ // src/storage/FileSessionStorage.ts
19365
+ import { validatePersistedSessionData } from "@tinycloud/sdk-core";
19366
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "fs";
19367
+ import { join } from "path";
19368
+ var FileSessionStorage = class {
19369
+ /**
19370
+ * Create a new FileSessionStorage.
19371
+ *
19372
+ * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)
19373
+ */
19374
+ constructor(baseDir) {
19375
+ this.baseDir = baseDir || this.getDefaultDir();
19376
+ this.ensureDirectoryExists();
19377
+ }
19378
+ /**
19379
+ * Get the default session storage directory.
19380
+ */
19381
+ getDefaultDir() {
19382
+ const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
19383
+ return join(home, ".tinycloud", "sessions");
19384
+ }
19385
+ /**
19386
+ * Ensure the storage directory exists.
19387
+ */
19388
+ ensureDirectoryExists() {
19389
+ if (!existsSync(this.baseDir)) {
19390
+ mkdirSync(this.baseDir, { recursive: true });
19391
+ }
19392
+ }
19393
+ /**
19394
+ * Get the file path for an address.
19395
+ */
19396
+ getFilePath(address) {
19397
+ const normalizedAddress = address.toLowerCase();
19398
+ const filename = `${normalizedAddress.replace("0x", "")}.json`;
19399
+ return join(this.baseDir, filename);
19400
+ }
19401
+ /**
19402
+ * Save a session for an address.
19403
+ */
19404
+ async save(address, session) {
19405
+ const filePath = this.getFilePath(address);
19406
+ const data = JSON.stringify(session, null, 2);
19407
+ writeFileSync(filePath, data, "utf-8");
19408
+ }
19409
+ /**
19410
+ * Load a session for an address.
19411
+ */
19412
+ async load(address) {
19413
+ const filePath = this.getFilePath(address);
19414
+ if (!existsSync(filePath)) {
19415
+ return null;
19416
+ }
19417
+ try {
19418
+ const data = readFileSync(filePath, "utf-8");
19419
+ const parsed = JSON.parse(data);
19420
+ const validation = validatePersistedSessionData(parsed);
19421
+ if (!validation.ok) {
19422
+ console.warn(`Invalid session data for ${address}:`, validation.error.message);
19423
+ unlinkSync(filePath);
19424
+ return null;
19425
+ }
19426
+ const session = validation.data;
19427
+ const expiresAt = new Date(session.expiresAt);
19428
+ if (expiresAt < /* @__PURE__ */ new Date()) {
19429
+ unlinkSync(filePath);
19430
+ return null;
19431
+ }
19432
+ return session;
19433
+ } catch (error) {
19434
+ try {
19435
+ unlinkSync(filePath);
19436
+ } catch {
19437
+ }
19438
+ return null;
19439
+ }
19440
+ }
19441
+ /**
19442
+ * Clear a session for an address.
19443
+ */
19444
+ async clear(address) {
19445
+ const filePath = this.getFilePath(address);
19446
+ if (existsSync(filePath)) {
19447
+ unlinkSync(filePath);
19448
+ }
19449
+ }
19450
+ /**
19451
+ * Check if a session exists for an address.
19452
+ */
19453
+ exists(address) {
19454
+ const filePath = this.getFilePath(address);
19455
+ if (!existsSync(filePath)) {
19456
+ return false;
19457
+ }
19458
+ try {
19459
+ const data = readFileSync(filePath, "utf-8");
19460
+ const session = JSON.parse(data);
19461
+ const expiresAt = new Date(session.expiresAt);
19462
+ if (expiresAt < /* @__PURE__ */ new Date()) {
19463
+ unlinkSync(filePath);
19464
+ return false;
19465
+ }
19466
+ return true;
19467
+ } catch {
19468
+ return false;
19469
+ }
19470
+ }
19471
+ /**
19472
+ * Check if file system storage is available.
19473
+ */
19474
+ isAvailable() {
19475
+ try {
19476
+ this.ensureDirectoryExists();
19477
+ return existsSync(this.baseDir);
19478
+ } catch {
19479
+ return false;
19480
+ }
19481
+ }
19482
+ };
19237
19483
 
19238
19484
  // src/delegation.ts
19239
19485
  function serializeDelegation(delegation) {
@@ -19284,6 +19530,7 @@ import {
19284
19530
  } from "@tinycloud/sdk-core";
19285
19531
  import { ServiceContext as ServiceContext3 } from "@tinycloud/sdk-core";
19286
19532
  export {
19533
+ AutoApproveSpaceCreationHandler2 as AutoApproveSpaceCreationHandler,
19287
19534
  CapabilityKeyRegistry2 as CapabilityKeyRegistry,
19288
19535
  CapabilityKeyRegistryErrorCodes,
19289
19536
  DataVaultService2 as DataVaultService,
@@ -19298,6 +19545,7 @@ export {
19298
19545
  KVService3 as KVService,
19299
19546
  MemorySessionStorage,
19300
19547
  NodeUserAuthorization,
19548
+ NodeWasmBindings,
19301
19549
  PrefixedKVService,
19302
19550
  PrivateKeySigner,
19303
19551
  ProtocolMismatchError,
@@ -19305,6 +19553,7 @@ export {
19305
19553
  SQLService3 as SQLService,
19306
19554
  ServiceContext3 as ServiceContext,
19307
19555
  SharingService2 as SharingService,
19556
+ SilentNotificationHandler2 as SilentNotificationHandler,
19308
19557
  Space,
19309
19558
  SpaceErrorCodes,
19310
19559
  SpaceService2 as SpaceService,
@@ -19323,6 +19572,7 @@ export {
19323
19572
  createVaultCrypto2 as createVaultCrypto,
19324
19573
  createWasmKeyProvider,
19325
19574
  defaultSignStrategy,
19575
+ defaultSpaceCreationHandler,
19326
19576
  deserializeDelegation,
19327
19577
  makePublicSpaceId2 as makePublicSpaceId,
19328
19578
  parseSpaceUri,