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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js CHANGED
@@ -204,8 +204,10 @@ import {
204
204
  activateSessionWithHost,
205
205
  checkNodeInfo,
206
206
  AutoApproveSpaceCreationHandler,
207
- manifestAbilitiesUnion,
208
- resolveManifest
207
+ DEFAULT_MANIFEST_SPACE,
208
+ composeManifestRequest,
209
+ resourceCapabilitiesToAbilitiesMap,
210
+ resourceCapabilitiesToSpaceAbilitiesMap
209
211
  } from "@tinycloud/sdk-core";
210
212
 
211
213
  // src/authorization/strategies.ts
@@ -274,7 +276,9 @@ var NodeUserAuthorization = class {
274
276
  this.enablePublicSpace = config.enablePublicSpace ?? true;
275
277
  this.nonce = config.nonce;
276
278
  this.siweConfig = config.siweConfig;
279
+ this.includeAccountRegistryPermissions = config.includeAccountRegistryPermissions ?? true;
277
280
  this._manifest = config.manifest;
281
+ this._capabilityRequest = config.capabilityRequest;
278
282
  this.sessionManager = this.wasm.createSessionManager();
279
283
  }
280
284
  /**
@@ -286,12 +290,19 @@ var NodeUserAuthorization = class {
286
290
  get manifest() {
287
291
  return this._manifest;
288
292
  }
293
+ get capabilityRequest() {
294
+ return this.getCapabilityRequest();
295
+ }
289
296
  /**
290
297
  * Install or replace the stored manifest. Takes effect on the next
291
298
  * `signIn()` call — the current session (if any) is not touched.
292
299
  */
293
300
  setManifest(manifest) {
294
301
  this._manifest = manifest;
302
+ this._capabilityRequest = void 0;
303
+ }
304
+ setCapabilityRequest(request) {
305
+ this._capabilityRequest = request;
295
306
  }
296
307
  /**
297
308
  * The current active session (web-core compatible).
@@ -335,12 +346,51 @@ var NodeUserAuthorization = class {
335
346
  *
336
347
  * @internal
337
348
  */
338
- resolveSignInAbilities() {
349
+ getCapabilityRequest() {
350
+ if (this._capabilityRequest !== void 0) {
351
+ return this._capabilityRequest;
352
+ }
339
353
  if (this._manifest === void 0) {
340
- return this.defaultActions;
354
+ return void 0;
355
+ }
356
+ this._capabilityRequest = composeManifestRequest(
357
+ Array.isArray(this._manifest) ? this._manifest : [this._manifest],
358
+ {
359
+ includeAccountRegistryPermissions: this.includeAccountRegistryPermissions
360
+ }
361
+ );
362
+ return this._capabilityRequest;
363
+ }
364
+ resolveSpaceName(space, address, chainId) {
365
+ if (space.startsWith("tinycloud:")) {
366
+ return space;
341
367
  }
342
- const resolved = resolveManifest(this._manifest);
343
- return manifestAbilitiesUnion(resolved);
368
+ return this.wasm.makeSpaceId(address, chainId, space);
369
+ }
370
+ resolveSignInCapabilities(address, chainId) {
371
+ const request = this.getCapabilityRequest();
372
+ if (request === void 0) {
373
+ return {
374
+ abilities: this.defaultActions,
375
+ spaceId: this.wasm.makeSpaceId(address, chainId, this.spacePrefix)
376
+ };
377
+ }
378
+ const primarySpaceName = request.resources.find((entry) => entry.space !== "account")?.space ?? DEFAULT_MANIFEST_SPACE;
379
+ const primarySpaceId = this.resolveSpaceName(
380
+ primarySpaceName,
381
+ address,
382
+ chainId
383
+ );
384
+ const bySpace = resourceCapabilitiesToSpaceAbilitiesMap(request.resources);
385
+ const spaceAbilities = {};
386
+ for (const [space, abilities] of Object.entries(bySpace)) {
387
+ spaceAbilities[this.resolveSpaceName(space, address, chainId)] = abilities;
388
+ }
389
+ return {
390
+ abilities: spaceAbilities[primarySpaceId] ?? resourceCapabilitiesToAbilitiesMap([]),
391
+ spaceId: primarySpaceId,
392
+ spaceAbilities
393
+ };
344
394
  }
345
395
  /**
346
396
  * Build SIWE overrides from the top-level nonce and siweConfig.
@@ -421,6 +471,13 @@ var NodeUserAuthorization = class {
421
471
  async hostPublicSpace(spaceId) {
422
472
  return this.hostSpace(spaceId);
423
473
  }
474
+ /**
475
+ * Create a specific owned space on the server via host delegation.
476
+ * Used by manifest registry setup for the account space.
477
+ */
478
+ async hostOwnedSpace(spaceId) {
479
+ return this.hostSpace(spaceId);
480
+ }
424
481
  /**
425
482
  * Ensure the user's space exists on the TinyCloud server.
426
483
  * Creates the space if it doesn't exist and autoCreateSpace is enabled.
@@ -549,11 +606,13 @@ var NodeUserAuthorization = class {
549
606
  throw new Error("Failed to create session key");
550
607
  }
551
608
  const jwk = JSON.parse(jwkString);
552
- const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);
609
+ const capabilityPlan = this.resolveSignInCapabilities(address, chainId);
610
+ const spaceId = capabilityPlan.spaceId;
553
611
  const now = /* @__PURE__ */ new Date();
554
612
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
555
613
  const prepared = this.wasm.prepareSession({
556
- abilities: this.resolveSignInAbilities(),
614
+ abilities: capabilityPlan.abilities,
615
+ ...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
557
616
  address,
558
617
  chainId,
559
618
  domain: this.domain,
@@ -692,11 +751,13 @@ var NodeUserAuthorization = class {
692
751
  throw new Error("Failed to create session key");
693
752
  }
694
753
  const jwk = JSON.parse(jwkString);
695
- const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);
754
+ const capabilityPlan = this.resolveSignInCapabilities(address, chainId);
755
+ const spaceId = capabilityPlan.spaceId;
696
756
  const now = /* @__PURE__ */ new Date();
697
757
  const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
698
758
  const prepared = this.wasm.prepareSession({
699
- abilities: this.resolveSignInAbilities(),
759
+ abilities: capabilityPlan.abilities,
760
+ ...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
700
761
  address,
701
762
  chainId,
702
763
  domain: this.domain,
@@ -881,6 +942,7 @@ import {
881
942
  SharingService,
882
943
  UnsupportedFeatureError,
883
944
  makePublicSpaceId,
945
+ ACCOUNT_REGISTRY_SPACE,
884
946
  PermissionNotInManifestError,
885
947
  SessionExpiredError,
886
948
  expandActionShortNames,
@@ -1238,7 +1300,9 @@ var _TinyCloudNode = class _TinyCloudNode {
1238
1300
  spaceCreationHandler: config.spaceCreationHandler,
1239
1301
  nonce: config.nonce,
1240
1302
  siweConfig: config.siweConfig,
1241
- manifest: config.manifest
1303
+ manifest: config.manifest,
1304
+ capabilityRequest: config.capabilityRequest,
1305
+ includeAccountRegistryPermissions: config.includeAccountRegistryPermissions
1242
1306
  });
1243
1307
  this.tc = new TinyCloud(this.auth, {
1244
1308
  invokeAny: this.wasmBindings.invokeAny
@@ -1257,8 +1321,20 @@ var _TinyCloudNode = class _TinyCloudNode {
1257
1321
  "setManifest requires wallet mode. Provide a signer or privateKey in the TinyCloudNode config."
1258
1322
  );
1259
1323
  }
1324
+ this.config.manifest = manifest;
1325
+ this.config.capabilityRequest = void 0;
1260
1326
  this.auth.setManifest(manifest);
1261
1327
  }
1328
+ setCapabilityRequest(request) {
1329
+ if (!this.auth) {
1330
+ throw new Error(
1331
+ "setCapabilityRequest requires wallet mode. Provide a signer or privateKey in the TinyCloudNode config."
1332
+ );
1333
+ }
1334
+ this.config.capabilityRequest = request;
1335
+ this.config.manifest = request?.manifests;
1336
+ this.auth.setCapabilityRequest(request);
1337
+ }
1262
1338
  /**
1263
1339
  * Return the manifest currently installed on the auth handler,
1264
1340
  * or `undefined` if none is set.
@@ -1266,6 +1342,9 @@ var _TinyCloudNode = class _TinyCloudNode {
1266
1342
  get manifest() {
1267
1343
  return this.auth?.manifest;
1268
1344
  }
1345
+ get capabilityRequest() {
1346
+ return this.auth?.capabilityRequest;
1347
+ }
1269
1348
  /**
1270
1349
  * Get the primary identity DID for this user.
1271
1350
  * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
@@ -1339,8 +1418,39 @@ var _TinyCloudNode = class _TinyCloudNode {
1339
1418
  this._serviceContext = void 0;
1340
1419
  await this.tc.signIn(options);
1341
1420
  this.initializeServices();
1421
+ await this.writeManifestRegistryRecords();
1342
1422
  this.notificationHandler.success("Successfully signed in");
1343
1423
  }
1424
+ ownedSpaceId(name) {
1425
+ if (!this._address) {
1426
+ throw new Error("Cannot resolve owned space before sign-in");
1427
+ }
1428
+ return this.wasmBindings.makeSpaceId(this._address, this._chainId, name);
1429
+ }
1430
+ async writeManifestRegistryRecords() {
1431
+ const request = this.capabilityRequest;
1432
+ if (!request || request.registryRecords.length === 0) {
1433
+ return;
1434
+ }
1435
+ if (!this.auth || !this.signer) {
1436
+ throw new Error("Manifest registry write requires wallet mode");
1437
+ }
1438
+ const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE);
1439
+ await this.auth.hostOwnedSpace(accountSpaceId);
1440
+ const accountKV = this.spaces.get(accountSpaceId).kv;
1441
+ for (const record of request.registryRecords) {
1442
+ const result = await accountKV.put(record.key, {
1443
+ app_id: record.app_id,
1444
+ manifests: record.manifests,
1445
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
1446
+ });
1447
+ if (!result.ok) {
1448
+ throw new Error(
1449
+ `Failed to write manifest registry record ${record.key}: ${result.error.message}`
1450
+ );
1451
+ }
1452
+ }
1453
+ }
1344
1454
  /**
1345
1455
  * Restore a previously established session from stored delegation data.
1346
1456
  *
@@ -1478,7 +1588,10 @@ var _TinyCloudNode = class _TinyCloudNode {
1478
1588
  enablePublicSpace: this.config.enablePublicSpace ?? true,
1479
1589
  spaceCreationHandler: this.config.spaceCreationHandler,
1480
1590
  nonce: this.config.nonce,
1481
- siweConfig: this.config.siweConfig
1591
+ siweConfig: this.config.siweConfig,
1592
+ manifest: this.config.manifest,
1593
+ capabilityRequest: this.config.capabilityRequest,
1594
+ includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
1482
1595
  });
1483
1596
  this.tc = new TinyCloud(this.auth, {
1484
1597
  invokeAny: this.wasmBindings.invokeAny
@@ -1518,7 +1631,10 @@ var _TinyCloudNode = class _TinyCloudNode {
1518
1631
  enablePublicSpace: this.config.enablePublicSpace ?? true,
1519
1632
  spaceCreationHandler: this.config.spaceCreationHandler,
1520
1633
  nonce: this.config.nonce,
1521
- siweConfig: this.config.siweConfig
1634
+ siweConfig: this.config.siweConfig,
1635
+ manifest: this.config.manifest,
1636
+ capabilityRequest: this.config.capabilityRequest,
1637
+ includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
1522
1638
  });
1523
1639
  this.tc = new TinyCloud(this.auth, {
1524
1640
  invokeAny: this.wasmBindings.invokeAny
@@ -2380,6 +2496,42 @@ var _TinyCloudNode = class _TinyCloudNode {
2380
2496
  );
2381
2497
  return { delegation, prompted: false };
2382
2498
  }
2499
+ /**
2500
+ * Materialize one manifest-declared delegation using the current session key.
2501
+ * Delivery is intentionally out of band; callers decide how to transmit the
2502
+ * returned UCAN to the delegate.
2503
+ */
2504
+ async materializeDelegation(did, request = this.capabilityRequest) {
2505
+ if (!request) {
2506
+ throw new Error(
2507
+ "materializeDelegation requires a composed manifest request"
2508
+ );
2509
+ }
2510
+ const target = request.delegationTargets.find((entry) => entry.did === did);
2511
+ if (!target) {
2512
+ throw new Error(`No manifest delegation target found for DID ${did}`);
2513
+ }
2514
+ const result = await this.delegateTo(target.did, target.permissions, {
2515
+ expiry: target.expiryMs
2516
+ });
2517
+ return { ...result, target };
2518
+ }
2519
+ /**
2520
+ * Materialize every delegation target declared by the composed manifest
2521
+ * request. This does not deliver the delegations anywhere.
2522
+ */
2523
+ async materializeDelegations(request = this.capabilityRequest) {
2524
+ if (!request) {
2525
+ throw new Error(
2526
+ "materializeDelegations requires a composed manifest request"
2527
+ );
2528
+ }
2529
+ const out = [];
2530
+ for (const target of request.delegationTargets) {
2531
+ out.push(await this.materializeDelegation(target.did, request));
2532
+ }
2533
+ return out;
2534
+ }
2383
2535
  /**
2384
2536
  * Issue a delegation via the session-key UCAN WASM path.
2385
2537
  *
@@ -2403,7 +2555,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2403
2555
  }
2404
2556
  const resolvedSpaces = /* @__PURE__ */ new Set();
2405
2557
  for (const entry of entries) {
2406
- const spaceId2 = entry.space === "default" ? session.spaceId : entry.space;
2558
+ const spaceId2 = this.resolvePermissionSpace(entry.space, session);
2407
2559
  resolvedSpaces.add(spaceId2);
2408
2560
  }
2409
2561
  if (resolvedSpaces.size !== 1) {
@@ -2478,6 +2630,22 @@ var _TinyCloudNode = class _TinyCloudNode {
2478
2630
  host: this.config.host
2479
2631
  };
2480
2632
  }
2633
+ resolvePermissionSpace(space, session) {
2634
+ if (space === void 0) {
2635
+ return this.wasmBindings.makeSpaceId(
2636
+ session.address,
2637
+ session.chainId,
2638
+ "applications"
2639
+ );
2640
+ }
2641
+ if (space === "default") {
2642
+ return session.spaceId;
2643
+ }
2644
+ if (space.startsWith("tinycloud:")) {
2645
+ return space;
2646
+ }
2647
+ return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
2648
+ }
2481
2649
  /**
2482
2650
  * Issue a delegation via the legacy wallet-signed SIWE path for a single
2483
2651
  * {@link PermissionEntry}. Shares the implementation with the public
@@ -2488,7 +2656,8 @@ var _TinyCloudNode = class _TinyCloudNode {
2488
2656
  * @internal
2489
2657
  */
2490
2658
  async createDelegationLegacyWalletPath(delegateDID, entry, expirationTime) {
2491
- const spaceIdOverride = entry.space === "default" ? void 0 : entry.space;
2659
+ const session = this.auth?.tinyCloudSession;
2660
+ const spaceIdOverride = session === void 0 || entry.space === "default" ? void 0 : this.resolvePermissionSpace(entry.space, session);
2492
2661
  return this.createDelegationWalletPath({
2493
2662
  path: entry.path,
2494
2663
  actions: entry.actions,
@@ -2860,15 +3029,21 @@ var TinyCloudNode = _TinyCloudNode;
2860
3029
 
2861
3030
  // src/core.ts
2862
3031
  import {
3032
+ ACCOUNT_REGISTRY_PATH,
3033
+ ACCOUNT_REGISTRY_SPACE as ACCOUNT_REGISTRY_SPACE2,
3034
+ DEFAULT_MANIFEST_SPACE as DEFAULT_MANIFEST_SPACE2,
3035
+ DEFAULT_MANIFEST_VERSION,
2863
3036
  PermissionNotInManifestError as PermissionNotInManifestError2,
2864
3037
  SessionExpiredError as SessionExpiredError2,
2865
3038
  ManifestValidationError,
2866
- resolveManifest as resolveManifest2,
3039
+ composeManifestRequest as composeManifestRequest2,
3040
+ resolveManifest,
2867
3041
  validateManifest,
2868
3042
  loadManifest,
2869
3043
  isCapabilitySubset as isCapabilitySubset2,
2870
3044
  expandActionShortNames as expandActionShortNames2,
2871
- parseExpiry as parseExpiry2
3045
+ parseExpiry as parseExpiry2,
3046
+ resourceCapabilitiesToSpaceAbilitiesMap as resourceCapabilitiesToSpaceAbilitiesMap2
2872
3047
  } from "@tinycloud/sdk-core";
2873
3048
 
2874
3049
  // src/delegation.ts
@@ -2920,9 +3095,13 @@ import {
2920
3095
  } from "@tinycloud/sdk-core";
2921
3096
  import { ServiceContext as ServiceContext3 } from "@tinycloud/sdk-core";
2922
3097
  export {
3098
+ ACCOUNT_REGISTRY_PATH,
3099
+ ACCOUNT_REGISTRY_SPACE2 as ACCOUNT_REGISTRY_SPACE,
2923
3100
  AutoApproveSpaceCreationHandler2 as AutoApproveSpaceCreationHandler,
2924
3101
  CapabilityKeyRegistry2 as CapabilityKeyRegistry,
2925
3102
  CapabilityKeyRegistryErrorCodes,
3103
+ DEFAULT_MANIFEST_SPACE2 as DEFAULT_MANIFEST_SPACE,
3104
+ DEFAULT_MANIFEST_VERSION,
2926
3105
  DataVaultService2 as DataVaultService,
2927
3106
  DatabaseHandle,
2928
3107
  DelegatedAccess,
@@ -2957,6 +3136,7 @@ export {
2957
3136
  WasmKeyProvider,
2958
3137
  buildSpaceUri,
2959
3138
  checkNodeInfo2 as checkNodeInfo,
3139
+ composeManifestRequest2 as composeManifestRequest,
2960
3140
  createCapabilityKeyRegistry,
2961
3141
  createSharingService,
2962
3142
  createSpaceService,
@@ -2971,7 +3151,8 @@ export {
2971
3151
  makePublicSpaceId2 as makePublicSpaceId,
2972
3152
  parseExpiry2 as parseExpiry,
2973
3153
  parseSpaceUri,
2974
- resolveManifest2 as resolveManifest,
3154
+ resolveManifest,
3155
+ resourceCapabilitiesToSpaceAbilitiesMap2 as resourceCapabilitiesToSpaceAbilitiesMap,
2975
3156
  serializeDelegation,
2976
3157
  validateManifest
2977
3158
  };