@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.cjs +97 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -40
- package/dist/index.d.ts +61 -40
- package/dist/index.js +94 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,8 @@ __export(index_exports, {
|
|
|
41
41
|
DEFAULT_EXPIRY: () => DEFAULT_EXPIRY,
|
|
42
42
|
DEFAULT_MANIFEST_SPACE: () => DEFAULT_MANIFEST_SPACE,
|
|
43
43
|
DEFAULT_MANIFEST_VERSION: () => DEFAULT_MANIFEST_VERSION,
|
|
44
|
+
DEFAULT_TINYCLOUD_FALLBACK_HOST: () => DEFAULT_TINYCLOUD_FALLBACK_HOST,
|
|
45
|
+
DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL: () => DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
|
|
44
46
|
DataVaultService: () => import_sdk_services4.DataVaultService,
|
|
45
47
|
DatabaseHandle: () => import_sdk_services4.DatabaseHandle,
|
|
46
48
|
DelegationErrorCodes: () => DelegationErrorCodes,
|
|
@@ -106,6 +108,7 @@ __export(index_exports, {
|
|
|
106
108
|
parseSpaceUri: () => parseSpaceUri,
|
|
107
109
|
resolveCloudLocation: () => resolveCloudLocation,
|
|
108
110
|
resolveManifest: () => resolveManifest,
|
|
111
|
+
resolveTinyCloudHosts: () => resolveTinyCloudHosts,
|
|
109
112
|
resourceCapabilitiesToAbilitiesMap: () => resourceCapabilitiesToAbilitiesMap,
|
|
110
113
|
resourceCapabilitiesToSpaceAbilitiesMap: () => resourceCapabilitiesToSpaceAbilitiesMap,
|
|
111
114
|
serviceError: () => import_sdk_services4.serviceError,
|
|
@@ -2786,12 +2789,6 @@ var DEFAULT_STANDARD_ENTRIES = [
|
|
|
2786
2789
|
space: DEFAULT_MANIFEST_SPACE,
|
|
2787
2790
|
path: "/",
|
|
2788
2791
|
actions: ["read", "write"]
|
|
2789
|
-
},
|
|
2790
|
-
{
|
|
2791
|
-
service: "tinycloud.capabilities",
|
|
2792
|
-
space: DEFAULT_MANIFEST_SPACE,
|
|
2793
|
-
path: "/",
|
|
2794
|
-
actions: ["read"]
|
|
2795
2792
|
}
|
|
2796
2793
|
];
|
|
2797
2794
|
var DEFAULT_ADMIN_ENTRIES = [
|
|
@@ -2806,12 +2803,6 @@ var DEFAULT_ADMIN_ENTRIES = [
|
|
|
2806
2803
|
space: DEFAULT_MANIFEST_SPACE,
|
|
2807
2804
|
path: "/",
|
|
2808
2805
|
actions: ["read", "write", "ddl"]
|
|
2809
|
-
},
|
|
2810
|
-
{
|
|
2811
|
-
service: "tinycloud.capabilities",
|
|
2812
|
-
space: DEFAULT_MANIFEST_SPACE,
|
|
2813
|
-
path: "/",
|
|
2814
|
-
actions: ["read", "admin"]
|
|
2815
2806
|
}
|
|
2816
2807
|
];
|
|
2817
2808
|
var DEFAULT_ALL_ENTRIES = [
|
|
@@ -2832,12 +2823,6 @@ var DEFAULT_ALL_ENTRIES = [
|
|
|
2832
2823
|
space: DEFAULT_MANIFEST_SPACE,
|
|
2833
2824
|
path: "/",
|
|
2834
2825
|
actions: ["read", "write"]
|
|
2835
|
-
},
|
|
2836
|
-
{
|
|
2837
|
-
service: "tinycloud.capabilities",
|
|
2838
|
-
space: DEFAULT_MANIFEST_SPACE,
|
|
2839
|
-
path: "/",
|
|
2840
|
-
actions: ["read", "admin"]
|
|
2841
2826
|
}
|
|
2842
2827
|
];
|
|
2843
2828
|
function parseExpiry(duration) {
|
|
@@ -2987,7 +2972,8 @@ function defaultEntriesForTier(tier) {
|
|
|
2987
2972
|
service: e.service,
|
|
2988
2973
|
space: e.space,
|
|
2989
2974
|
path: e.path,
|
|
2990
|
-
actions: [...e.actions]
|
|
2975
|
+
actions: [...e.actions],
|
|
2976
|
+
...e.skipPrefix !== void 0 ? { skipPrefix: e.skipPrefix } : {}
|
|
2991
2977
|
}));
|
|
2992
2978
|
}
|
|
2993
2979
|
function resolveManifest(input) {
|
|
@@ -3000,8 +2986,8 @@ function resolveManifest(input) {
|
|
|
3000
2986
|
const defaultEntries = defaultEntriesForTier(tier);
|
|
3001
2987
|
const explicitEntries = manifest.permissions ?? [];
|
|
3002
2988
|
const allEntries = [...defaultEntries, ...explicitEntries];
|
|
3003
|
-
const resources =
|
|
3004
|
-
(entry) => resolveEntry(entry, prefix, expiryMs, space)
|
|
2989
|
+
const resources = withCapabilitiesReadForSpaces(
|
|
2990
|
+
allEntries.map((entry) => resolveEntry(entry, prefix, expiryMs, space))
|
|
3005
2991
|
);
|
|
3006
2992
|
const additionalDelegates = manifest.did === void 0 ? [] : [
|
|
3007
2993
|
{
|
|
@@ -3084,6 +3070,24 @@ function dedupeResources(resources) {
|
|
|
3084
3070
|
}
|
|
3085
3071
|
return [...byKey.values()];
|
|
3086
3072
|
}
|
|
3073
|
+
function capabilitiesReadPermission(space) {
|
|
3074
|
+
return {
|
|
3075
|
+
service: "tinycloud.capabilities",
|
|
3076
|
+
space,
|
|
3077
|
+
path: "",
|
|
3078
|
+
actions: ["tinycloud.capabilities/read"]
|
|
3079
|
+
};
|
|
3080
|
+
}
|
|
3081
|
+
function withCapabilitiesReadForSpaces(resources) {
|
|
3082
|
+
if (resources.length === 0) {
|
|
3083
|
+
return [];
|
|
3084
|
+
}
|
|
3085
|
+
const spaces = new Set(resources.map((resource) => resource.space));
|
|
3086
|
+
return dedupeResources([
|
|
3087
|
+
...resources,
|
|
3088
|
+
...[...spaces].map(capabilitiesReadPermission)
|
|
3089
|
+
]);
|
|
3090
|
+
}
|
|
3087
3091
|
function accountRegistryPermission() {
|
|
3088
3092
|
return {
|
|
3089
3093
|
service: "tinycloud.kv",
|
|
@@ -3111,6 +3115,7 @@ function composeManifestRequest(inputs, options = {}) {
|
|
|
3111
3115
|
if (includeAccountRegistryPermissions) {
|
|
3112
3116
|
resources.push(accountRegistryPermission());
|
|
3113
3117
|
}
|
|
3118
|
+
const resourcesWithImplicitCapabilities = withCapabilitiesReadForSpaces(resources);
|
|
3114
3119
|
const manifestsByAppId = /* @__PURE__ */ new Map();
|
|
3115
3120
|
for (const manifest of manifests) {
|
|
3116
3121
|
const current = manifestsByAppId.get(manifest.app_id);
|
|
@@ -3130,7 +3135,7 @@ function composeManifestRequest(inputs, options = {}) {
|
|
|
3130
3135
|
})) : [];
|
|
3131
3136
|
return {
|
|
3132
3137
|
manifests,
|
|
3133
|
-
resources:
|
|
3138
|
+
resources: resourcesWithImplicitCapabilities,
|
|
3134
3139
|
delegationTargets,
|
|
3135
3140
|
registryRecords,
|
|
3136
3141
|
expiryMs: Math.max(...resolved.map((entry) => entry.expiryMs)),
|
|
@@ -4349,6 +4354,8 @@ var import_uri_to_multiaddr = require("@multiformats/uri-to-multiaddr");
|
|
|
4349
4354
|
var import_ed25519 = require("@noble/curves/ed25519");
|
|
4350
4355
|
var import_basics = require("multiformats/basics");
|
|
4351
4356
|
var import_viem = require("viem");
|
|
4357
|
+
var DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL = "https://registry.tinycloud.xyz";
|
|
4358
|
+
var DEFAULT_TINYCLOUD_FALLBACK_HOST = "https://node.tinycloud.xyz";
|
|
4352
4359
|
var LocationRecordValidationError = class extends Error {
|
|
4353
4360
|
constructor(message) {
|
|
4354
4361
|
super(`Location record validation failed: ${message}`);
|
|
@@ -4383,7 +4390,9 @@ function canonicalLocationPayload(payload) {
|
|
|
4383
4390
|
async function signLocationRecord(payload, signer) {
|
|
4384
4391
|
validateLocationRecordPayload(payload);
|
|
4385
4392
|
const message = canonicalLocationPayload(payload);
|
|
4386
|
-
const signature = signer.type === "did:pkh" ? await signer.signMessage(message) : base64UrlEncode2(
|
|
4393
|
+
const signature = signer.type === "did:pkh" ? await signer.signMessage(message) : base64UrlEncode2(
|
|
4394
|
+
await signer.signBytes(new TextEncoder().encode(message))
|
|
4395
|
+
);
|
|
4387
4396
|
return { ...payload, signature };
|
|
4388
4397
|
}
|
|
4389
4398
|
function validateLocationRecordPayload(input) {
|
|
@@ -4397,7 +4406,9 @@ function validateLocationRecordPayload(input) {
|
|
|
4397
4406
|
validateSubject(payload.subject);
|
|
4398
4407
|
validateMultiaddrs(payload.multiaddrs);
|
|
4399
4408
|
if (typeof payload.updated_at !== "string" || Number.isNaN(Date.parse(payload.updated_at))) {
|
|
4400
|
-
throw new LocationRecordValidationError(
|
|
4409
|
+
throw new LocationRecordValidationError(
|
|
4410
|
+
"updated_at must be an ISO timestamp"
|
|
4411
|
+
);
|
|
4401
4412
|
}
|
|
4402
4413
|
if (typeof payload.sequence !== "number" || !Number.isSafeInteger(payload.sequence) || payload.sequence < 0) {
|
|
4403
4414
|
throw new LocationRecordValidationError(
|
|
@@ -4416,7 +4427,9 @@ function validateLocationRecord(input) {
|
|
|
4416
4427
|
const payload = validateLocationRecordPayload(input);
|
|
4417
4428
|
const signature = input.signature;
|
|
4418
4429
|
if (typeof signature !== "string" || signature.length === 0) {
|
|
4419
|
-
throw new LocationRecordValidationError(
|
|
4430
|
+
throw new LocationRecordValidationError(
|
|
4431
|
+
"signature must be a non-empty string"
|
|
4432
|
+
);
|
|
4420
4433
|
}
|
|
4421
4434
|
return { ...payload, signature };
|
|
4422
4435
|
}
|
|
@@ -4468,6 +4481,22 @@ async function resolveCloudLocation(subject, options = {}) {
|
|
|
4468
4481
|
resolvedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4469
4482
|
};
|
|
4470
4483
|
}
|
|
4484
|
+
async function resolveTinyCloudHosts(subject, options = {}) {
|
|
4485
|
+
const location = await resolveCloudLocation(subject, {
|
|
4486
|
+
explicitMultiaddrs: hostsToMultiaddrs(options.explicitHosts),
|
|
4487
|
+
blockchain: options.blockchain,
|
|
4488
|
+
centralizedRegistryUrl: options.registryUrl === null ? void 0 : options.registryUrl ?? DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
|
|
4489
|
+
fallbackMultiaddrs: hostsToMultiaddrs(
|
|
4490
|
+
options.fallbackHosts === null ? void 0 : options.fallbackHosts ?? [DEFAULT_TINYCLOUD_FALLBACK_HOST]
|
|
4491
|
+
),
|
|
4492
|
+
fetch: options.fetch,
|
|
4493
|
+
verifyRecords: options.verifyRecords
|
|
4494
|
+
});
|
|
4495
|
+
return {
|
|
4496
|
+
hosts: location.multiaddrs.map((addr) => multiaddrToHttpUrl(addr)),
|
|
4497
|
+
location
|
|
4498
|
+
};
|
|
4499
|
+
}
|
|
4471
4500
|
function multiaddrToHttpUrl(input) {
|
|
4472
4501
|
const uri = (0, import_multiaddr_to_uri.multiaddrToUri)((0, import_multiaddr.multiaddr)(input));
|
|
4473
4502
|
if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
|
|
@@ -4484,6 +4513,14 @@ function httpUrlToMultiaddr(input) {
|
|
|
4484
4513
|
}
|
|
4485
4514
|
return (0, import_uri_to_multiaddr.uriToMultiaddr)(url.toString()).toString();
|
|
4486
4515
|
}
|
|
4516
|
+
function hostsToMultiaddrs(hosts) {
|
|
4517
|
+
if (hosts === void 0 || hosts.length === 0) {
|
|
4518
|
+
return void 0;
|
|
4519
|
+
}
|
|
4520
|
+
return hosts.map(
|
|
4521
|
+
(host) => host.startsWith("/") ? host : httpUrlToMultiaddr(host)
|
|
4522
|
+
);
|
|
4523
|
+
}
|
|
4487
4524
|
async function resolveExplicit(subject, multiaddrs) {
|
|
4488
4525
|
return resolveAttempt("explicit", async () => {
|
|
4489
4526
|
if (multiaddrs === void 0 || multiaddrs.length === 0) {
|
|
@@ -4497,7 +4534,12 @@ async function resolveBlockchain(subject, resolver, verifyRecords) {
|
|
|
4497
4534
|
if (!resolver) {
|
|
4498
4535
|
return null;
|
|
4499
4536
|
}
|
|
4500
|
-
return toCandidate(
|
|
4537
|
+
return toCandidate(
|
|
4538
|
+
subject,
|
|
4539
|
+
"blockchain",
|
|
4540
|
+
await resolver(subject),
|
|
4541
|
+
verifyRecords
|
|
4542
|
+
);
|
|
4501
4543
|
});
|
|
4502
4544
|
}
|
|
4503
4545
|
async function resolveCentralized(subject, options, verifyRecords) {
|
|
@@ -4549,13 +4591,17 @@ async function toCandidate(subject, source, input, verifyRecord) {
|
|
|
4549
4591
|
);
|
|
4550
4592
|
}
|
|
4551
4593
|
if (verifyRecord && !await verifyLocationRecord(record)) {
|
|
4552
|
-
throw new LocationRecordValidationError(
|
|
4594
|
+
throw new LocationRecordValidationError(
|
|
4595
|
+
"location record signature is invalid"
|
|
4596
|
+
);
|
|
4553
4597
|
}
|
|
4554
4598
|
return { source, multiaddrs: [...record.multiaddrs], record };
|
|
4555
4599
|
}
|
|
4556
4600
|
const candidateInput = input;
|
|
4557
4601
|
if (!Array.isArray(candidateInput.multiaddrs)) {
|
|
4558
|
-
throw new LocationRecordValidationError(
|
|
4602
|
+
throw new LocationRecordValidationError(
|
|
4603
|
+
"candidate multiaddrs must be an array"
|
|
4604
|
+
);
|
|
4559
4605
|
}
|
|
4560
4606
|
validateMultiaddrs(candidateInput.multiaddrs);
|
|
4561
4607
|
if (candidateInput.record !== void 0) {
|
|
@@ -4566,7 +4612,9 @@ async function toCandidate(subject, source, input, verifyRecord) {
|
|
|
4566
4612
|
);
|
|
4567
4613
|
}
|
|
4568
4614
|
if (verifyRecord && !await verifyLocationRecord(record)) {
|
|
4569
|
-
throw new LocationRecordValidationError(
|
|
4615
|
+
throw new LocationRecordValidationError(
|
|
4616
|
+
"location record signature is invalid"
|
|
4617
|
+
);
|
|
4570
4618
|
}
|
|
4571
4619
|
return { source, multiaddrs: [...candidateInput.multiaddrs], record };
|
|
4572
4620
|
}
|
|
@@ -4574,10 +4622,14 @@ async function toCandidate(subject, source, input, verifyRecord) {
|
|
|
4574
4622
|
}
|
|
4575
4623
|
function validateSubject(subject) {
|
|
4576
4624
|
if (typeof subject !== "string" || subject.length === 0) {
|
|
4577
|
-
throw new LocationRecordValidationError(
|
|
4625
|
+
throw new LocationRecordValidationError(
|
|
4626
|
+
"subject must be a non-empty string"
|
|
4627
|
+
);
|
|
4578
4628
|
}
|
|
4579
4629
|
if (!subject.startsWith("did:pkh:") && !subject.startsWith("did:key:")) {
|
|
4580
|
-
throw new LocationRecordValidationError(
|
|
4630
|
+
throw new LocationRecordValidationError(
|
|
4631
|
+
"subject must be did:pkh or did:key"
|
|
4632
|
+
);
|
|
4581
4633
|
}
|
|
4582
4634
|
}
|
|
4583
4635
|
function validateMultiaddrs(input) {
|
|
@@ -4621,16 +4673,24 @@ function verifyDidKeySignature(did, payload, signature) {
|
|
|
4621
4673
|
"did:key signature must be a base64url Ed25519 signature"
|
|
4622
4674
|
);
|
|
4623
4675
|
}
|
|
4624
|
-
return import_ed25519.ed25519.verify(
|
|
4676
|
+
return import_ed25519.ed25519.verify(
|
|
4677
|
+
signatureBytes,
|
|
4678
|
+
new TextEncoder().encode(payload),
|
|
4679
|
+
publicKey
|
|
4680
|
+
);
|
|
4625
4681
|
}
|
|
4626
4682
|
function ed25519PublicKeyFromDidKey(did) {
|
|
4627
4683
|
const identifier = did.slice("did:key:".length);
|
|
4628
4684
|
if (!identifier.startsWith("z")) {
|
|
4629
|
-
throw new LocationRecordValidationError(
|
|
4685
|
+
throw new LocationRecordValidationError(
|
|
4686
|
+
"did:key must use base58btc multibase"
|
|
4687
|
+
);
|
|
4630
4688
|
}
|
|
4631
4689
|
const bytes = import_basics.bases.base58btc.decode(identifier);
|
|
4632
4690
|
if (bytes.length !== 34 || bytes[0] !== 237 || bytes[1] !== 1) {
|
|
4633
|
-
throw new LocationRecordValidationError(
|
|
4691
|
+
throw new LocationRecordValidationError(
|
|
4692
|
+
"did:key must be an Ed25519 public key"
|
|
4693
|
+
);
|
|
4634
4694
|
}
|
|
4635
4695
|
return bytes.slice(2);
|
|
4636
4696
|
}
|
|
@@ -4801,6 +4861,8 @@ function parseRecapCapabilities(parseWasm, siwe) {
|
|
|
4801
4861
|
DEFAULT_EXPIRY,
|
|
4802
4862
|
DEFAULT_MANIFEST_SPACE,
|
|
4803
4863
|
DEFAULT_MANIFEST_VERSION,
|
|
4864
|
+
DEFAULT_TINYCLOUD_FALLBACK_HOST,
|
|
4865
|
+
DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
|
|
4804
4866
|
DataVaultService,
|
|
4805
4867
|
DatabaseHandle,
|
|
4806
4868
|
DelegationErrorCodes,
|
|
@@ -4866,6 +4928,7 @@ function parseRecapCapabilities(parseWasm, siwe) {
|
|
|
4866
4928
|
parseSpaceUri,
|
|
4867
4929
|
resolveCloudLocation,
|
|
4868
4930
|
resolveManifest,
|
|
4931
|
+
resolveTinyCloudHosts,
|
|
4869
4932
|
resourceCapabilitiesToAbilitiesMap,
|
|
4870
4933
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
4871
4934
|
serviceError,
|