@tinycloud/node-sdk 1.2.0 → 1.3.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
@@ -17349,6 +17349,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17349
17349
  this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
17350
17350
  this.autoCreateSpace = config.autoCreateSpace ?? false;
17351
17351
  this.tinycloudHosts = config.tinycloudHosts ?? ["https://node.tinycloud.xyz"];
17352
+ this.enablePublicSpace = config.enablePublicSpace ?? true;
17352
17353
  this.sessionManager = new SessionManager();
17353
17354
  }
17354
17355
  /**
@@ -17380,12 +17381,12 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17380
17381
  * Create the space on the TinyCloud server (host delegation).
17381
17382
  * This registers the user as the owner of the space.
17382
17383
  */
17383
- async hostSpace() {
17384
+ async hostSpace(targetSpaceId) {
17384
17385
  if (!this._tinyCloudSession || !this._address || !this._chainId) {
17385
17386
  throw new Error("Must be signed in to host space");
17386
17387
  }
17387
17388
  const host = this.tinycloudHosts[0];
17388
- const spaceId = this._tinyCloudSession.spaceId;
17389
+ const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
17389
17390
  const peerId = await fetchPeerId(host, spaceId);
17390
17391
  const siwe = generateHostSIWEMessage({
17391
17392
  address: this._address,
@@ -17400,6 +17401,13 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17400
17401
  const result = await submitHostDelegation(host, headers);
17401
17402
  return result.success;
17402
17403
  }
17404
+ /**
17405
+ * Create a specific space on the server via host delegation.
17406
+ * Used for lazy creation of additional spaces (e.g., public).
17407
+ */
17408
+ async hostPublicSpace(spaceId) {
17409
+ return this.hostSpace(spaceId);
17410
+ }
17403
17411
  /**
17404
17412
  * Ensure the user's space exists on the TinyCloud server.
17405
17413
  * Creates the space if it doesn't exist and autoCreateSpace is enabled.
@@ -17413,11 +17421,33 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17413
17421
  throw new Error("Must be signed in to ensure space exists");
17414
17422
  }
17415
17423
  const host = this.tinycloudHosts[0];
17424
+ const primarySpaceId = this._tinyCloudSession.spaceId;
17416
17425
  const result = await activateSessionWithHost(
17417
17426
  host,
17418
17427
  this._tinyCloudSession.delegationHeader
17419
17428
  );
17420
17429
  if (result.success) {
17430
+ const primarySkipped = result.skipped?.includes(primarySpaceId);
17431
+ if (!primarySkipped) {
17432
+ return;
17433
+ }
17434
+ if (!this.autoCreateSpace) {
17435
+ return;
17436
+ }
17437
+ const created = await this.hostSpace();
17438
+ if (!created) {
17439
+ throw new Error(`Failed to create space: ${primarySpaceId}`);
17440
+ }
17441
+ await new Promise((resolve) => setTimeout(resolve, 100));
17442
+ const retryResult = await activateSessionWithHost(
17443
+ host,
17444
+ this._tinyCloudSession.delegationHeader
17445
+ );
17446
+ if (!retryResult.success) {
17447
+ throw new Error(
17448
+ `Failed to activate session after creating space: ${retryResult.error}`
17449
+ );
17450
+ }
17421
17451
  return;
17422
17452
  }
17423
17453
  if (result.status === 404) {
@@ -17426,9 +17456,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17426
17456
  }
17427
17457
  const created = await this.hostSpace();
17428
17458
  if (!created) {
17429
- throw new Error(
17430
- `Failed to create space: ${this._tinyCloudSession.spaceId}`
17431
- );
17459
+ throw new Error(`Failed to create space: ${primarySpaceId}`);
17432
17460
  }
17433
17461
  await new Promise((resolve) => setTimeout(resolve, 100));
17434
17462
  const retryResult = await activateSessionWithHost(
@@ -17496,11 +17524,13 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17496
17524
  siwe: prepared.siwe,
17497
17525
  signature: signature2
17498
17526
  };
17527
+ const spacesMetadata = this.enablePublicSpace ? { public: makeSpaceId(address, chainId, "public") } : void 0;
17499
17528
  const tinyCloudSession = {
17500
17529
  address,
17501
17530
  chainId,
17502
17531
  sessionKey: keyId,
17503
17532
  spaceId,
17533
+ spaces: spacesMetadata,
17504
17534
  delegationCid: session.delegationCid,
17505
17535
  delegationHeader: session.delegationHeader,
17506
17536
  verificationMethod: this.sessionManager.getDID(keyId),
@@ -17518,6 +17548,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17518
17548
  delegationHeader: session.delegationHeader,
17519
17549
  delegationCid: session.delegationCid,
17520
17550
  spaceId,
17551
+ spaces: spacesMetadata,
17521
17552
  verificationMethod: this.sessionManager.getDID(keyId)
17522
17553
  },
17523
17554
  expiresAt: expirationTime.toISOString(),
@@ -17647,11 +17678,13 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17647
17678
  siwe: prepared.siwe,
17648
17679
  signature: signature2
17649
17680
  };
17681
+ const spacesMetadata = this.enablePublicSpace ? { public: makeSpaceId(address, chainId, "public") } : void 0;
17650
17682
  const tinyCloudSession = {
17651
17683
  address,
17652
17684
  chainId,
17653
17685
  sessionKey: keyId,
17654
17686
  spaceId: prepared.spaceId,
17687
+ spaces: spacesMetadata,
17655
17688
  delegationCid: session.delegationCid,
17656
17689
  delegationHeader: session.delegationHeader,
17657
17690
  verificationMethod: this.sessionManager.getDID(keyId),
@@ -17673,6 +17706,7 @@ var _NodeUserAuthorization = class _NodeUserAuthorization {
17673
17706
  delegationHeader: session.delegationHeader,
17674
17707
  delegationCid: session.delegationCid,
17675
17708
  spaceId: prepared.spaceId,
17709
+ spaces: spacesMetadata,
17676
17710
  verificationMethod: this.sessionManager.getDID(keyId)
17677
17711
  },
17678
17712
  expiresAt,
@@ -17770,6 +17804,8 @@ import {
17770
17804
  activateSessionWithHost as activateSessionWithHost2,
17771
17805
  KVService as KVService2,
17772
17806
  SQLService as SQLService2,
17807
+ DataVaultService,
17808
+ createVaultCrypto,
17773
17809
  ServiceContext as ServiceContext2,
17774
17810
  DelegationManager,
17775
17811
  SpaceService,
@@ -17783,7 +17819,14 @@ import {
17783
17819
  ensureEip55 as ensureEip553,
17784
17820
  invoke as invoke2,
17785
17821
  initPanicHook as initPanicHook2,
17786
- createDelegation
17822
+ createDelegation,
17823
+ vault_encrypt,
17824
+ vault_decrypt,
17825
+ vault_derive_key,
17826
+ vault_x25519_from_seed,
17827
+ vault_x25519_dh,
17828
+ vault_random_bytes,
17829
+ vault_sha256
17787
17830
  } from "@tinycloud/node-sdk-wasm";
17788
17831
 
17789
17832
  // src/DelegatedAccess.ts
@@ -18015,7 +18058,8 @@ var _TinyCloudNode = class _TinyCloudNode {
18015
18058
  spacePrefix: config.prefix,
18016
18059
  sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
18017
18060
  tinycloudHosts: [host],
18018
- autoCreateSpace: config.autoCreateSpace
18061
+ autoCreateSpace: config.autoCreateSpace,
18062
+ enablePublicSpace: config.enablePublicSpace ?? true
18019
18063
  });
18020
18064
  this.tc = new TinyCloud(this.auth);
18021
18065
  }
@@ -18130,7 +18174,8 @@ var _TinyCloudNode = class _TinyCloudNode {
18130
18174
  spacePrefix: prefix,
18131
18175
  sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
18132
18176
  tinycloudHosts: [host],
18133
- autoCreateSpace: this.config.autoCreateSpace
18177
+ autoCreateSpace: this.config.autoCreateSpace,
18178
+ enablePublicSpace: this.config.enablePublicSpace ?? true
18134
18179
  });
18135
18180
  this.tc = new TinyCloud(this.auth);
18136
18181
  this.config.prefix = prefix;
@@ -18144,6 +18189,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18144
18189
  if (!session) {
18145
18190
  return;
18146
18191
  }
18192
+ this.tc.initializeServices(invoke2, [this.config.host]);
18147
18193
  this._serviceContext = new ServiceContext2({
18148
18194
  invoke: invoke2,
18149
18195
  fetch: globalThis.fetch.bind(globalThis),
@@ -18163,6 +18209,43 @@ var _TinyCloudNode = class _TinyCloudNode {
18163
18209
  jwk: session.jwk
18164
18210
  };
18165
18211
  this._serviceContext.setSession(serviceSession);
18212
+ this.tc.serviceContext.setSession(serviceSession);
18213
+ const vaultCrypto = createVaultCrypto({
18214
+ vault_encrypt,
18215
+ vault_decrypt,
18216
+ vault_derive_key,
18217
+ vault_x25519_from_seed,
18218
+ vault_x25519_dh,
18219
+ vault_random_bytes,
18220
+ vault_sha256
18221
+ });
18222
+ const self2 = this;
18223
+ this._vault = new DataVaultService({
18224
+ spaceId: session.spaceId,
18225
+ crypto: vaultCrypto,
18226
+ tc: {
18227
+ kv: this._kv,
18228
+ ensurePublicSpace: async () => {
18229
+ try {
18230
+ await self2.ensurePublicSpace();
18231
+ return { ok: true, data: void 0 };
18232
+ } catch (error) {
18233
+ return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
18234
+ }
18235
+ },
18236
+ get publicKV() {
18237
+ return self2._publicKV ?? self2.tc.publicKV;
18238
+ },
18239
+ readPublicSpace: (host, spaceId, key2) => TinyCloud.readPublicSpace(host, spaceId, key2),
18240
+ makePublicSpaceId: TinyCloud.makePublicSpaceId,
18241
+ did: this.did,
18242
+ address: this._address,
18243
+ chainId: this._chainId,
18244
+ hosts: [this.config.host]
18245
+ }
18246
+ });
18247
+ this._vault.initialize(this._serviceContext);
18248
+ this._serviceContext.registerService("vault", this._vault);
18166
18249
  this.initializeV2Services(serviceSession);
18167
18250
  }
18168
18251
  /**
@@ -18203,7 +18286,32 @@ var _TinyCloudNode = class _TinyCloudNode {
18203
18286
  isRevoked: false,
18204
18287
  allowSubDelegation: true
18205
18288
  };
18206
- this._capabilityRegistry.registerKey(sessionKey, [rootDelegation]);
18289
+ const delegations = [rootDelegation];
18290
+ if (tcSession.spaces) {
18291
+ for (const [spaceName, spaceId] of Object.entries(tcSession.spaces)) {
18292
+ delegations.push({
18293
+ cid: tcSession.delegationCid,
18294
+ delegateDID: tcSession.verificationMethod,
18295
+ spaceId,
18296
+ path: "",
18297
+ actions: [
18298
+ "tinycloud.kv/put",
18299
+ "tinycloud.kv/get",
18300
+ "tinycloud.kv/del",
18301
+ "tinycloud.kv/list",
18302
+ "tinycloud.kv/metadata",
18303
+ "tinycloud.sql/read",
18304
+ "tinycloud.sql/write",
18305
+ "tinycloud.sql/admin",
18306
+ "tinycloud.sql/*"
18307
+ ],
18308
+ expiry: this.getSessionExpiry(),
18309
+ isRevoked: false,
18310
+ allowSubDelegation: true
18311
+ });
18312
+ }
18313
+ }
18314
+ this._capabilityRegistry.registerKey(sessionKey, delegations);
18207
18315
  }
18208
18316
  this._delegationManager = new DelegationManager({
18209
18317
  hosts: [this.config.host],
@@ -18221,7 +18329,16 @@ var _TinyCloudNode = class _TinyCloudNode {
18221
18329
  createKVService: (spaceId) => {
18222
18330
  const kvService = new KVService2({});
18223
18331
  if (this._serviceContext) {
18224
- kvService.initialize(this._serviceContext);
18332
+ const spaceScopedContext = new ServiceContext2({
18333
+ invoke: this._serviceContext.invoke,
18334
+ fetch: this._serviceContext.fetch,
18335
+ hosts: this._serviceContext.hosts
18336
+ });
18337
+ const session = this._serviceContext.session;
18338
+ if (session) {
18339
+ spaceScopedContext.setSession({ ...session, spaceId });
18340
+ }
18341
+ kvService.initialize(spaceScopedContext);
18225
18342
  }
18226
18343
  return kvService;
18227
18344
  },
@@ -18356,6 +18473,16 @@ var _TinyCloudNode = class _TinyCloudNode {
18356
18473
  }
18357
18474
  return this._sql;
18358
18475
  }
18476
+ /**
18477
+ * Data Vault operations - client-side encrypted KV storage.
18478
+ * Call `vault.unlock(signer)` after signIn() to derive encryption keys.
18479
+ */
18480
+ get vault() {
18481
+ if (!this._vault) {
18482
+ throw new Error("Not signed in. Call signIn() first.");
18483
+ }
18484
+ return this._vault;
18485
+ }
18359
18486
  // ===========================================================================
18360
18487
  // v2 Service Accessors
18361
18488
  // ===========================================================================
@@ -18529,21 +18656,99 @@ var _TinyCloudNode = class _TinyCloudNode {
18529
18656
  // Public Space Methods
18530
18657
  // ===========================================================================
18531
18658
  /**
18532
- * Ensure the user's public space exists.
18533
- * Creates it via spaces.create('public') if it doesn't.
18534
- * Requires the user to be signed in.
18659
+ * Ensure the user's public space exists and is accessible.
18660
+ * Creates the space and activates a session delegation for it.
18661
+ * This is the trigger for lazy public space creation — call it
18662
+ * before writing to spaces.get('public').kv.
18535
18663
  */
18536
18664
  async ensurePublicSpace() {
18537
- if (!this.tc) {
18665
+ if (!this.auth || !this.session || !this.signer) {
18538
18666
  throw new Error("Not signed in. Call signIn() first.");
18539
18667
  }
18540
- return this.tc.ensurePublicSpace();
18668
+ const publicSpaceId = this.session.spaces?.public;
18669
+ if (!publicSpaceId) {
18670
+ throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
18671
+ }
18672
+ await this.auth.hostPublicSpace(publicSpaceId);
18673
+ const kvActions = [
18674
+ "tinycloud.kv/put",
18675
+ "tinycloud.kv/get",
18676
+ "tinycloud.kv/del",
18677
+ "tinycloud.kv/list",
18678
+ "tinycloud.kv/metadata"
18679
+ ];
18680
+ const abilities = { kv: { "": kvActions } };
18681
+ const now = /* @__PURE__ */ new Date();
18682
+ const expiryMs = 60 * 60 * 1e3;
18683
+ const expirationTime = new Date(now.getTime() + expiryMs);
18684
+ const prepared = prepareSession2({
18685
+ abilities,
18686
+ address: ensureEip553(this.session.address),
18687
+ chainId: this.session.chainId,
18688
+ domain: new URL(this.config.host).hostname,
18689
+ issuedAt: now.toISOString(),
18690
+ expirationTime: expirationTime.toISOString(),
18691
+ spaceId: publicSpaceId,
18692
+ jwk: this.session.jwk,
18693
+ parents: [this.session.delegationCid]
18694
+ });
18695
+ const signature2 = await this.signer.signMessage(prepared.siwe);
18696
+ const delegationSession = completeSessionSetup2({
18697
+ ...prepared,
18698
+ signature: signature2
18699
+ });
18700
+ const activateResult = await activateSessionWithHost2(
18701
+ this.config.host,
18702
+ delegationSession.delegationHeader
18703
+ );
18704
+ if (!activateResult.success) {
18705
+ throw new Error(`Failed to activate public space delegation: ${activateResult.error}`);
18706
+ }
18707
+ if (this._capabilityRegistry && this.session) {
18708
+ const sessionKey = {
18709
+ id: this.session.sessionKey,
18710
+ did: this.session.verificationMethod,
18711
+ type: "session",
18712
+ jwk: this.session.jwk,
18713
+ priority: 0
18714
+ };
18715
+ this._capabilityRegistry.registerKey(sessionKey, [{
18716
+ cid: delegationSession.delegationCid,
18717
+ delegateDID: this.session.verificationMethod,
18718
+ spaceId: publicSpaceId,
18719
+ path: "",
18720
+ actions: kvActions,
18721
+ expiry: expirationTime,
18722
+ isRevoked: false,
18723
+ allowSubDelegation: true
18724
+ }]);
18725
+ }
18726
+ if (this._serviceContext) {
18727
+ const publicKV = new KVService2({ prefix: "" });
18728
+ const publicContext = new ServiceContext2({
18729
+ invoke: invoke2,
18730
+ fetch: this._serviceContext.fetch,
18731
+ hosts: this._serviceContext.hosts
18732
+ });
18733
+ publicContext.setSession({
18734
+ delegationHeader: delegationSession.delegationHeader,
18735
+ delegationCid: delegationSession.delegationCid,
18736
+ spaceId: publicSpaceId,
18737
+ verificationMethod: this.session.verificationMethod,
18738
+ jwk: this.session.jwk
18739
+ });
18740
+ publicKV.initialize(publicContext);
18741
+ this._publicKV = publicKV;
18742
+ }
18541
18743
  }
18542
18744
  /**
18543
18745
  * Get a KVService scoped to the user's own public space.
18544
18746
  * Writes require authentication (owner/delegate).
18545
18747
  */
18546
18748
  get publicKV() {
18749
+ if (this._publicKV) {
18750
+ return this._publicKV;
18751
+ }
18547
18752
  if (!this.tc) {
18548
18753
  throw new Error("Not signed in. Call signIn() first.");
18549
18754
  }
@@ -18641,7 +18846,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18641
18846
  domain: new URL(this.config.host).hostname,
18642
18847
  issuedAt: now.toISOString(),
18643
18848
  expirationTime: expirationTime.toISOString(),
18644
- spaceId: session.spaceId,
18849
+ spaceId: params.spaceIdOverride ?? session.spaceId,
18645
18850
  delegateUri: params.delegateDID,
18646
18851
  parents: [session.delegationCid]
18647
18852
  });
@@ -18660,7 +18865,7 @@ var _TinyCloudNode = class _TinyCloudNode {
18660
18865
  return {
18661
18866
  cid: delegationSession.delegationCid,
18662
18867
  delegationHeader: delegationSession.delegationHeader,
18663
- spaceId: session.spaceId,
18868
+ spaceId: params.spaceIdOverride ?? session.spaceId,
18664
18869
  path: params.path,
18665
18870
  actions: params.actions,
18666
18871
  disableSubDelegation: params.disableSubDelegation ?? false,
@@ -18874,6 +19079,7 @@ function deserializeDelegation(data) {
18874
19079
  // src/index.ts
18875
19080
  import { KVService as KVService3, PrefixedKVService } from "@tinycloud/sdk-core";
18876
19081
  import { SQLService as SQLService3, SQLAction, DatabaseHandle } from "@tinycloud/sdk-core";
19082
+ import { DataVaultService as DataVaultService2, VaultAction, VaultHeaders, createVaultCrypto as createVaultCrypto2 } from "@tinycloud/sdk-core";
18877
19083
  import {
18878
19084
  DelegationManager as DelegationManager2,
18879
19085
  SharingService as SharingService2,
@@ -18903,6 +19109,7 @@ import { ServiceContext as ServiceContext3 } from "@tinycloud/sdk-core";
18903
19109
  export {
18904
19110
  CapabilityKeyRegistry2 as CapabilityKeyRegistry,
18905
19111
  CapabilityKeyRegistryErrorCodes,
19112
+ DataVaultService2 as DataVaultService,
18906
19113
  DatabaseHandle,
18907
19114
  DelegatedAccess,
18908
19115
  DelegationErrorCodes,
@@ -18923,6 +19130,8 @@ export {
18923
19130
  SpaceService2 as SpaceService,
18924
19131
  TinyCloud2 as TinyCloud,
18925
19132
  TinyCloudNode,
19133
+ VaultAction,
19134
+ VaultHeaders,
18926
19135
  VersionCheckError,
18927
19136
  WasmKeyProvider,
18928
19137
  buildSpaceUri,
@@ -18930,6 +19139,7 @@ export {
18930
19139
  createCapabilityKeyRegistry,
18931
19140
  createSharingService,
18932
19141
  createSpaceService,
19142
+ createVaultCrypto2 as createVaultCrypto,
18933
19143
  createWasmKeyProvider,
18934
19144
  defaultSignStrategy,
18935
19145
  deserializeDelegation,