@tinycloud/sdk-core 2.2.0-beta.3 → 2.2.0-beta.6

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
@@ -2694,12 +2694,6 @@ var DEFAULT_STANDARD_ENTRIES = [
2694
2694
  space: DEFAULT_MANIFEST_SPACE,
2695
2695
  path: "/",
2696
2696
  actions: ["read", "write"]
2697
- },
2698
- {
2699
- service: "tinycloud.capabilities",
2700
- space: DEFAULT_MANIFEST_SPACE,
2701
- path: "/",
2702
- actions: ["read"]
2703
2697
  }
2704
2698
  ];
2705
2699
  var DEFAULT_ADMIN_ENTRIES = [
@@ -2714,12 +2708,6 @@ var DEFAULT_ADMIN_ENTRIES = [
2714
2708
  space: DEFAULT_MANIFEST_SPACE,
2715
2709
  path: "/",
2716
2710
  actions: ["read", "write", "ddl"]
2717
- },
2718
- {
2719
- service: "tinycloud.capabilities",
2720
- space: DEFAULT_MANIFEST_SPACE,
2721
- path: "/",
2722
- actions: ["read", "admin"]
2723
2711
  }
2724
2712
  ];
2725
2713
  var DEFAULT_ALL_ENTRIES = [
@@ -2740,12 +2728,6 @@ var DEFAULT_ALL_ENTRIES = [
2740
2728
  space: DEFAULT_MANIFEST_SPACE,
2741
2729
  path: "/",
2742
2730
  actions: ["read", "write"]
2743
- },
2744
- {
2745
- service: "tinycloud.capabilities",
2746
- space: DEFAULT_MANIFEST_SPACE,
2747
- path: "/",
2748
- actions: ["read", "admin"]
2749
2731
  }
2750
2732
  ];
2751
2733
  function parseExpiry(duration) {
@@ -2895,7 +2877,8 @@ function defaultEntriesForTier(tier) {
2895
2877
  service: e.service,
2896
2878
  space: e.space,
2897
2879
  path: e.path,
2898
- actions: [...e.actions]
2880
+ actions: [...e.actions],
2881
+ ...e.skipPrefix !== void 0 ? { skipPrefix: e.skipPrefix } : {}
2899
2882
  }));
2900
2883
  }
2901
2884
  function resolveManifest(input) {
@@ -2908,8 +2891,8 @@ function resolveManifest(input) {
2908
2891
  const defaultEntries = defaultEntriesForTier(tier);
2909
2892
  const explicitEntries = manifest.permissions ?? [];
2910
2893
  const allEntries = [...defaultEntries, ...explicitEntries];
2911
- const resources = allEntries.map(
2912
- (entry) => resolveEntry(entry, prefix, expiryMs, space)
2894
+ const resources = withCapabilitiesReadForSpaces(
2895
+ allEntries.map((entry) => resolveEntry(entry, prefix, expiryMs, space))
2913
2896
  );
2914
2897
  const additionalDelegates = manifest.did === void 0 ? [] : [
2915
2898
  {
@@ -2992,6 +2975,24 @@ function dedupeResources(resources) {
2992
2975
  }
2993
2976
  return [...byKey.values()];
2994
2977
  }
2978
+ function capabilitiesReadPermission(space) {
2979
+ return {
2980
+ service: "tinycloud.capabilities",
2981
+ space,
2982
+ path: "",
2983
+ actions: ["tinycloud.capabilities/read"]
2984
+ };
2985
+ }
2986
+ function withCapabilitiesReadForSpaces(resources) {
2987
+ if (resources.length === 0) {
2988
+ return [];
2989
+ }
2990
+ const spaces = new Set(resources.map((resource) => resource.space));
2991
+ return dedupeResources([
2992
+ ...resources,
2993
+ ...[...spaces].map(capabilitiesReadPermission)
2994
+ ]);
2995
+ }
2995
2996
  function accountRegistryPermission() {
2996
2997
  return {
2997
2998
  service: "tinycloud.kv",
@@ -3019,6 +3020,7 @@ function composeManifestRequest(inputs, options = {}) {
3019
3020
  if (includeAccountRegistryPermissions) {
3020
3021
  resources.push(accountRegistryPermission());
3021
3022
  }
3023
+ const resourcesWithImplicitCapabilities = withCapabilitiesReadForSpaces(resources);
3022
3024
  const manifestsByAppId = /* @__PURE__ */ new Map();
3023
3025
  for (const manifest of manifests) {
3024
3026
  const current = manifestsByAppId.get(manifest.app_id);
@@ -3038,7 +3040,7 @@ function composeManifestRequest(inputs, options = {}) {
3038
3040
  })) : [];
3039
3041
  return {
3040
3042
  manifests,
3041
- resources: dedupeResources(resources),
3043
+ resources: resourcesWithImplicitCapabilities,
3042
3044
  delegationTargets,
3043
3045
  registryRecords,
3044
3046
  expiryMs: Math.max(...resolved.map((entry) => entry.expiryMs)),
@@ -4257,6 +4259,8 @@ import { uriToMultiaddr } from "@multiformats/uri-to-multiaddr";
4257
4259
  import { ed25519 } from "@noble/curves/ed25519";
4258
4260
  import { bases } from "multiformats/basics";
4259
4261
  import { verifyMessage } from "viem";
4262
+ var DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL = "https://registry.tinycloud.xyz";
4263
+ var DEFAULT_TINYCLOUD_FALLBACK_HOST = "https://node.tinycloud.xyz";
4260
4264
  var LocationRecordValidationError = class extends Error {
4261
4265
  constructor(message) {
4262
4266
  super(`Location record validation failed: ${message}`);
@@ -4291,7 +4295,9 @@ function canonicalLocationPayload(payload) {
4291
4295
  async function signLocationRecord(payload, signer) {
4292
4296
  validateLocationRecordPayload(payload);
4293
4297
  const message = canonicalLocationPayload(payload);
4294
- const signature = signer.type === "did:pkh" ? await signer.signMessage(message) : base64UrlEncode2(await signer.signBytes(new TextEncoder().encode(message)));
4298
+ const signature = signer.type === "did:pkh" ? await signer.signMessage(message) : base64UrlEncode2(
4299
+ await signer.signBytes(new TextEncoder().encode(message))
4300
+ );
4295
4301
  return { ...payload, signature };
4296
4302
  }
4297
4303
  function validateLocationRecordPayload(input) {
@@ -4305,7 +4311,9 @@ function validateLocationRecordPayload(input) {
4305
4311
  validateSubject(payload.subject);
4306
4312
  validateMultiaddrs(payload.multiaddrs);
4307
4313
  if (typeof payload.updated_at !== "string" || Number.isNaN(Date.parse(payload.updated_at))) {
4308
- throw new LocationRecordValidationError("updated_at must be an ISO timestamp");
4314
+ throw new LocationRecordValidationError(
4315
+ "updated_at must be an ISO timestamp"
4316
+ );
4309
4317
  }
4310
4318
  if (typeof payload.sequence !== "number" || !Number.isSafeInteger(payload.sequence) || payload.sequence < 0) {
4311
4319
  throw new LocationRecordValidationError(
@@ -4324,7 +4332,9 @@ function validateLocationRecord(input) {
4324
4332
  const payload = validateLocationRecordPayload(input);
4325
4333
  const signature = input.signature;
4326
4334
  if (typeof signature !== "string" || signature.length === 0) {
4327
- throw new LocationRecordValidationError("signature must be a non-empty string");
4335
+ throw new LocationRecordValidationError(
4336
+ "signature must be a non-empty string"
4337
+ );
4328
4338
  }
4329
4339
  return { ...payload, signature };
4330
4340
  }
@@ -4376,6 +4386,22 @@ async function resolveCloudLocation(subject, options = {}) {
4376
4386
  resolvedAt: (/* @__PURE__ */ new Date()).toISOString()
4377
4387
  };
4378
4388
  }
4389
+ async function resolveTinyCloudHosts(subject, options = {}) {
4390
+ const location = await resolveCloudLocation(subject, {
4391
+ explicitMultiaddrs: hostsToMultiaddrs(options.explicitHosts),
4392
+ blockchain: options.blockchain,
4393
+ centralizedRegistryUrl: options.registryUrl === null ? void 0 : options.registryUrl ?? DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
4394
+ fallbackMultiaddrs: hostsToMultiaddrs(
4395
+ options.fallbackHosts === null ? void 0 : options.fallbackHosts ?? [DEFAULT_TINYCLOUD_FALLBACK_HOST]
4396
+ ),
4397
+ fetch: options.fetch,
4398
+ verifyRecords: options.verifyRecords
4399
+ });
4400
+ return {
4401
+ hosts: location.multiaddrs.map((addr) => multiaddrToHttpUrl(addr)),
4402
+ location
4403
+ };
4404
+ }
4379
4405
  function multiaddrToHttpUrl(input) {
4380
4406
  const uri = multiaddrToUri(multiaddr(input));
4381
4407
  if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
@@ -4392,6 +4418,14 @@ function httpUrlToMultiaddr(input) {
4392
4418
  }
4393
4419
  return uriToMultiaddr(url.toString()).toString();
4394
4420
  }
4421
+ function hostsToMultiaddrs(hosts) {
4422
+ if (hosts === void 0 || hosts.length === 0) {
4423
+ return void 0;
4424
+ }
4425
+ return hosts.map(
4426
+ (host) => host.startsWith("/") ? host : httpUrlToMultiaddr(host)
4427
+ );
4428
+ }
4395
4429
  async function resolveExplicit(subject, multiaddrs) {
4396
4430
  return resolveAttempt("explicit", async () => {
4397
4431
  if (multiaddrs === void 0 || multiaddrs.length === 0) {
@@ -4405,7 +4439,12 @@ async function resolveBlockchain(subject, resolver, verifyRecords) {
4405
4439
  if (!resolver) {
4406
4440
  return null;
4407
4441
  }
4408
- return toCandidate(subject, "blockchain", await resolver(subject), verifyRecords);
4442
+ return toCandidate(
4443
+ subject,
4444
+ "blockchain",
4445
+ await resolver(subject),
4446
+ verifyRecords
4447
+ );
4409
4448
  });
4410
4449
  }
4411
4450
  async function resolveCentralized(subject, options, verifyRecords) {
@@ -4457,13 +4496,17 @@ async function toCandidate(subject, source, input, verifyRecord) {
4457
4496
  );
4458
4497
  }
4459
4498
  if (verifyRecord && !await verifyLocationRecord(record)) {
4460
- throw new LocationRecordValidationError("location record signature is invalid");
4499
+ throw new LocationRecordValidationError(
4500
+ "location record signature is invalid"
4501
+ );
4461
4502
  }
4462
4503
  return { source, multiaddrs: [...record.multiaddrs], record };
4463
4504
  }
4464
4505
  const candidateInput = input;
4465
4506
  if (!Array.isArray(candidateInput.multiaddrs)) {
4466
- throw new LocationRecordValidationError("candidate multiaddrs must be an array");
4507
+ throw new LocationRecordValidationError(
4508
+ "candidate multiaddrs must be an array"
4509
+ );
4467
4510
  }
4468
4511
  validateMultiaddrs(candidateInput.multiaddrs);
4469
4512
  if (candidateInput.record !== void 0) {
@@ -4474,7 +4517,9 @@ async function toCandidate(subject, source, input, verifyRecord) {
4474
4517
  );
4475
4518
  }
4476
4519
  if (verifyRecord && !await verifyLocationRecord(record)) {
4477
- throw new LocationRecordValidationError("location record signature is invalid");
4520
+ throw new LocationRecordValidationError(
4521
+ "location record signature is invalid"
4522
+ );
4478
4523
  }
4479
4524
  return { source, multiaddrs: [...candidateInput.multiaddrs], record };
4480
4525
  }
@@ -4482,10 +4527,14 @@ async function toCandidate(subject, source, input, verifyRecord) {
4482
4527
  }
4483
4528
  function validateSubject(subject) {
4484
4529
  if (typeof subject !== "string" || subject.length === 0) {
4485
- throw new LocationRecordValidationError("subject must be a non-empty string");
4530
+ throw new LocationRecordValidationError(
4531
+ "subject must be a non-empty string"
4532
+ );
4486
4533
  }
4487
4534
  if (!subject.startsWith("did:pkh:") && !subject.startsWith("did:key:")) {
4488
- throw new LocationRecordValidationError("subject must be did:pkh or did:key");
4535
+ throw new LocationRecordValidationError(
4536
+ "subject must be did:pkh or did:key"
4537
+ );
4489
4538
  }
4490
4539
  }
4491
4540
  function validateMultiaddrs(input) {
@@ -4529,16 +4578,24 @@ function verifyDidKeySignature(did, payload, signature) {
4529
4578
  "did:key signature must be a base64url Ed25519 signature"
4530
4579
  );
4531
4580
  }
4532
- return ed25519.verify(signatureBytes, new TextEncoder().encode(payload), publicKey);
4581
+ return ed25519.verify(
4582
+ signatureBytes,
4583
+ new TextEncoder().encode(payload),
4584
+ publicKey
4585
+ );
4533
4586
  }
4534
4587
  function ed25519PublicKeyFromDidKey(did) {
4535
4588
  const identifier = did.slice("did:key:".length);
4536
4589
  if (!identifier.startsWith("z")) {
4537
- throw new LocationRecordValidationError("did:key must use base58btc multibase");
4590
+ throw new LocationRecordValidationError(
4591
+ "did:key must use base58btc multibase"
4592
+ );
4538
4593
  }
4539
4594
  const bytes = bases.base58btc.decode(identifier);
4540
4595
  if (bytes.length !== 34 || bytes[0] !== 237 || bytes[1] !== 1) {
4541
- throw new LocationRecordValidationError("did:key must be an Ed25519 public key");
4596
+ throw new LocationRecordValidationError(
4597
+ "did:key must be an Ed25519 public key"
4598
+ );
4542
4599
  }
4543
4600
  return bytes.slice(2);
4544
4601
  }
@@ -4708,6 +4765,8 @@ export {
4708
4765
  DEFAULT_EXPIRY,
4709
4766
  DEFAULT_MANIFEST_SPACE,
4710
4767
  DEFAULT_MANIFEST_VERSION,
4768
+ DEFAULT_TINYCLOUD_FALLBACK_HOST,
4769
+ DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
4711
4770
  DataVaultService,
4712
4771
  DatabaseHandle,
4713
4772
  DelegationErrorCodes,
@@ -4773,6 +4832,7 @@ export {
4773
4832
  parseSpaceUri,
4774
4833
  resolveCloudLocation,
4775
4834
  resolveManifest,
4835
+ resolveTinyCloudHosts,
4776
4836
  resourceCapabilitiesToAbilitiesMap,
4777
4837
  resourceCapabilitiesToSpaceAbilitiesMap,
4778
4838
  serviceError4 as serviceError,