@tinycloud/node-sdk 3.8.0-beta.2 → 3.8.0-beta.20
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/README.md +6 -0
- package/dist/{TinyCloudNode-B6VOBrCb.d.ts → TinyCloudNode-BRyeZas2.d.ts} +47 -6
- package/dist/{TinyCloudNode-CVO41O12.d.cts → TinyCloudNode-NrmztjDd.d.cts} +47 -6
- package/dist/{WasmKeyProvider-5Ee7fcAw.d.cts → WasmKeyProvider-BKCPRC-c.d.cts} +21 -1
- package/dist/{WasmKeyProvider-5Ee7fcAw.d.ts → WasmKeyProvider-BKCPRC-c.d.ts} +21 -1
- package/dist/{authority-DGi1hIMK.d.ts → authority-D6JMJwor.d.ts} +1 -1
- package/dist/{authority-DgVV80bI.d.cts → authority-Z-reu6zL.d.cts} +1 -1
- package/dist/core.cjs +336 -29
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +5 -4
- package/dist/core.d.ts +5 -4
- package/dist/core.js +330 -24
- package/dist/core.js.map +1 -1
- package/dist/credentials-core.d.cts +1 -1
- package/dist/credentials-core.d.ts +1 -1
- package/dist/credentials.d.cts +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/{delegation-0LKZkmP2.d.cts → delegation-Ckc3UETl.d.cts} +1 -1
- package/dist/{delegation-0LKZkmP2.d.ts → delegation-Ckc3UETl.d.ts} +1 -1
- package/dist/encryption-keys.d.cts +2 -2
- package/dist/encryption-keys.d.ts +2 -2
- package/dist/index.cjs +304 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +293 -27
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.cjs +3 -0
- package/dist/replication/authority.cjs.map +1 -1
- package/dist/replication/authority.d.cts +4 -3
- package/dist/replication/authority.d.ts +4 -3
- package/dist/replication/authority.js +3 -0
- package/dist/replication/authority.js.map +1 -1
- package/dist/replication/runtime.cjs +1 -0
- package/dist/replication/runtime.cjs.map +1 -1
- package/dist/replication/runtime.js +1 -0
- package/dist/replication/runtime.js.map +1 -1
- package/dist/share-receive.cjs +775 -0
- package/dist/share-receive.cjs.map +1 -0
- package/dist/share-receive.d.cts +32 -0
- package/dist/share-receive.d.ts +32 -0
- package/dist/share-receive.js +777 -0
- package/dist/share-receive.js.map +1 -0
- package/package.json +11 -4
package/dist/core.js
CHANGED
|
@@ -242,10 +242,10 @@ import {
|
|
|
242
242
|
activateSessionWithHost,
|
|
243
243
|
checkNodeInfo,
|
|
244
244
|
AutoApproveSpaceCreationHandler,
|
|
245
|
+
ManifestValidationError,
|
|
245
246
|
DEFAULT_MANIFEST_SPACE,
|
|
246
247
|
ENCRYPTION_PERMISSION_SERVICE,
|
|
247
248
|
composeManifestRequest,
|
|
248
|
-
parseNetworkId,
|
|
249
249
|
principalDidEquals,
|
|
250
250
|
resourceCapabilitiesToAbilitiesMap,
|
|
251
251
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
@@ -273,6 +273,44 @@ import {
|
|
|
273
273
|
HOOKS,
|
|
274
274
|
ENCRYPTION
|
|
275
275
|
} from "@tinycloud/sdk-core";
|
|
276
|
+
import { parseEncryptionResource } from "@tinycloud/sdk-services/encryption/resource";
|
|
277
|
+
import { parseNetworkId } from "@tinycloud/sdk-services";
|
|
278
|
+
|
|
279
|
+
// src/authorization/appKeyHostBinding.ts
|
|
280
|
+
var DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
281
|
+
var IPV4 = /^\d+\.\d+\.\d+\.\d+$/;
|
|
282
|
+
var APP_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
283
|
+
function appKeyHostBinding(domain, appId) {
|
|
284
|
+
if (!APP_ID.test(appId)) return false;
|
|
285
|
+
if (domain.endsWith(":")) return false;
|
|
286
|
+
let url;
|
|
287
|
+
try {
|
|
288
|
+
url = new URL(`https://${domain}`);
|
|
289
|
+
} catch {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
if (url.protocol !== "https:" || url.port !== "" || url.username !== "" || url.password !== "") return false;
|
|
293
|
+
if (url.pathname !== "/" || url.search !== "" || url.hash !== "") return false;
|
|
294
|
+
const host = url.hostname;
|
|
295
|
+
if (host.startsWith("[") || host.endsWith(".") || IPV4.test(host)) return false;
|
|
296
|
+
const labels = host.split(".");
|
|
297
|
+
if (labels.length < 2 || labels[labels.length - 1] === "localhost") return false;
|
|
298
|
+
if (!labels.every((label) => DOMAIN_LABEL.test(label))) return false;
|
|
299
|
+
const reversed = labels.reverse().join(".");
|
|
300
|
+
return appId === reversed || appId.startsWith(`${reversed}.`);
|
|
301
|
+
}
|
|
302
|
+
function isAppKeyHostBound(keysAppId, origin) {
|
|
303
|
+
if (typeof origin === "string" && !origin.includes("://")) {
|
|
304
|
+
return appKeyHostBinding(origin, keysAppId);
|
|
305
|
+
}
|
|
306
|
+
let url;
|
|
307
|
+
try {
|
|
308
|
+
url = typeof origin === "string" ? new URL(origin) : origin;
|
|
309
|
+
} catch {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
return appKeyHostBinding(url.host, keysAppId);
|
|
313
|
+
}
|
|
276
314
|
|
|
277
315
|
// src/replication/authority-sign-in.ts
|
|
278
316
|
import {
|
|
@@ -410,6 +448,7 @@ function cloneAbilitiesMap(actions) {
|
|
|
410
448
|
var NodeUserAuthorization = class {
|
|
411
449
|
constructor(config) {
|
|
412
450
|
this.activeSessionKeyId = "default";
|
|
451
|
+
this.preparedSessionCounter = 0;
|
|
413
452
|
/** Incremented by resetSession; a sign-in started earlier publishes nothing. */
|
|
414
453
|
this.sessionGeneration = 0;
|
|
415
454
|
/**
|
|
@@ -766,6 +805,23 @@ var NodeUserAuthorization = class {
|
|
|
766
805
|
);
|
|
767
806
|
return this._capabilityRequest;
|
|
768
807
|
}
|
|
808
|
+
async refreshNamedKeyFeatureForSignIn(address, chainId) {
|
|
809
|
+
const request = this.getCapabilityRequest();
|
|
810
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
811
|
+
const hasNamedKeys = request?.manifests.some((manifest) => manifest.keys?.length && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id));
|
|
812
|
+
if (hasNamedKeys) {
|
|
813
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
814
|
+
await this.refreshNodeInfo();
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
/** Manifest key paths that this sign-in cannot grant. */
|
|
818
|
+
get unavailableKeyPaths() {
|
|
819
|
+
const request = this.getCapabilityRequest();
|
|
820
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
821
|
+
return (request?.manifests ?? []).flatMap(
|
|
822
|
+
(manifest) => this._nodeFeatures.includes("encryption-named-keys-v1") && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id) ? [] : (manifest.keys ?? []).map((entry) => "path" in entry ? entry.path : entry.prefix)
|
|
823
|
+
);
|
|
824
|
+
}
|
|
769
825
|
resolveSpaceName(space, address, chainId) {
|
|
770
826
|
if (space.startsWith("tinycloud:")) {
|
|
771
827
|
return space;
|
|
@@ -957,15 +1013,32 @@ var NodeUserAuthorization = class {
|
|
|
957
1013
|
}
|
|
958
1014
|
const rawAbilities = {};
|
|
959
1015
|
const currentDid = pkhDid(address, chainId);
|
|
1016
|
+
if (this._nodeFeatures.includes("encryption-named-keys-v1")) {
|
|
1017
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
1018
|
+
for (const manifest of request.manifests) {
|
|
1019
|
+
if (!appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id)) continue;
|
|
1020
|
+
for (const declaration of manifest.keys ?? []) {
|
|
1021
|
+
const path = "path" in declaration ? declaration.path : declaration.prefix;
|
|
1022
|
+
const resource = `urn:tinycloud:encryption:${currentDid}:default/${path}`;
|
|
1023
|
+
for (const ability of declaration.abilities) {
|
|
1024
|
+
addRawAbility(rawAbilities, resource, `tinycloud.encryption/${ability}`);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
960
1029
|
const spaceResources = request.resources.filter((entry) => {
|
|
961
1030
|
if (entry.service !== ENCRYPTION_PERMISSION_SERVICE) {
|
|
962
1031
|
return true;
|
|
963
1032
|
}
|
|
1033
|
+
const parsed = entry.path.includes("/") ? parseEncryptionResource(entry.path) : { ...parseNetworkId(entry.path), kind: "network" };
|
|
1034
|
+
const sharePrefix = parsed.kind === "prefix" && parsed.network === "default" && parsed.prefix === "share" && entry.actions.length === 1 && entry.actions[0] === DECRYPT_ACTION && didPrincipalMatches(parsed.ownerDid, currentDid);
|
|
1035
|
+
if (parsed.kind !== "network" && !sharePrefix) {
|
|
1036
|
+
throw new ManifestValidationError("named keys go in manifest.keys");
|
|
1037
|
+
}
|
|
964
1038
|
for (const action of entry.actions) {
|
|
965
1039
|
addRawAbility(rawAbilities, entry.path, action);
|
|
966
1040
|
}
|
|
967
|
-
if (entry.actions.includes(DECRYPT_ACTION)) {
|
|
968
|
-
const parsed = parseNetworkId(entry.path);
|
|
1041
|
+
if (entry.actions.includes(DECRYPT_ACTION) && parsed.kind === "network") {
|
|
969
1042
|
if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
|
|
970
1043
|
addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
|
|
971
1044
|
}
|
|
@@ -1002,8 +1075,7 @@ var NodeUserAuthorization = class {
|
|
|
1002
1075
|
/**
|
|
1003
1076
|
* Build SIWE overrides from the top-level nonce and siweConfig.
|
|
1004
1077
|
* - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
|
|
1005
|
-
* -
|
|
1006
|
-
* - resources are appended to the default resources
|
|
1078
|
+
* - resources are inserted after WASM preparation, before the final ReCap
|
|
1007
1079
|
* - uri triggers a warning (overwriting delegation target)
|
|
1008
1080
|
* - all other fields override directly
|
|
1009
1081
|
* - per-call nonce overrides siweConfig.nonce when provided
|
|
@@ -1021,9 +1093,6 @@ var NodeUserAuthorization = class {
|
|
|
1021
1093
|
if (statement) {
|
|
1022
1094
|
overrides.statement = this.statement ? `${statement} ${this.statement}` : statement;
|
|
1023
1095
|
}
|
|
1024
|
-
if (resources && resources.length > 0) {
|
|
1025
|
-
overrides.resources = resources;
|
|
1026
|
-
}
|
|
1027
1096
|
if (uri) {
|
|
1028
1097
|
console.warn(
|
|
1029
1098
|
"[tinycloud] siweConfig.uri is overwriting the delegation target URI. This may break delegation chain validation if the URI does not match the session key DID."
|
|
@@ -1035,6 +1104,29 @@ var NodeUserAuthorization = class {
|
|
|
1035
1104
|
}
|
|
1036
1105
|
return overrides;
|
|
1037
1106
|
}
|
|
1107
|
+
prepareSessionWithResources(params) {
|
|
1108
|
+
const resources = this.siweConfig?.resources;
|
|
1109
|
+
if (resources?.some((resource) => typeof resource !== "string" || !/^urn:tinycloud:recipients:[A-Za-z0-9_-]+$/.test(resource))) {
|
|
1110
|
+
throw new Error("SIWE metadata resources must be base64url recipients URIs");
|
|
1111
|
+
}
|
|
1112
|
+
const prepared = this.wasm.prepareSession(params);
|
|
1113
|
+
if (!resources?.length) return prepared;
|
|
1114
|
+
const recapLines = /^- urn:recap:[^\r\n]+$/gim;
|
|
1115
|
+
const recaps = prepared.siwe.match(recapLines);
|
|
1116
|
+
const recap = recaps?.[0];
|
|
1117
|
+
if (recaps?.length !== 1 || !prepared.siwe.endsWith(recap)) {
|
|
1118
|
+
throw new Error("Prepared SIWE must end with exactly one ReCap");
|
|
1119
|
+
}
|
|
1120
|
+
const insertedLines = resources.map((resource) => `- ${resource}`);
|
|
1121
|
+
const siwe = prepared.siwe.slice(0, -recap.length) + insertedLines.join("\n") + "\n" + recap;
|
|
1122
|
+
const expectedFields = extractImmutableSiweFields(prepared.siwe);
|
|
1123
|
+
expectedFields.nonRecapResources = [expectedFields.nonRecapResources, ...insertedLines].filter(Boolean).join("\n");
|
|
1124
|
+
const actualRecaps = siwe.match(recapLines);
|
|
1125
|
+
if (actualRecaps?.length !== 1 || actualRecaps[0] !== recap || diffImmutableSiweFields(expectedFields, extractImmutableSiweFields(siwe)).length) {
|
|
1126
|
+
throw new Error("SIWE metadata insertion changed the prepared message");
|
|
1127
|
+
}
|
|
1128
|
+
return { ...prepared, siwe };
|
|
1129
|
+
}
|
|
1038
1130
|
/**
|
|
1039
1131
|
* Add an extension to the authorization flow.
|
|
1040
1132
|
*/
|
|
@@ -1282,7 +1374,7 @@ var NodeUserAuthorization = class {
|
|
|
1282
1374
|
spaceAbilities[spaceId] = resourceCapabilitiesToAbilitiesMap(resources);
|
|
1283
1375
|
}
|
|
1284
1376
|
const abilities = spaceAbilities[options.spaceId] ?? resourceCapabilitiesToAbilitiesMap([]);
|
|
1285
|
-
const prepared = this.
|
|
1377
|
+
const prepared = this.prepareSessionWithResources({
|
|
1286
1378
|
abilities,
|
|
1287
1379
|
spaceAbilities,
|
|
1288
1380
|
...options.rawAbilities !== void 0 ? { rawAbilities: options.rawAbilities } : {},
|
|
@@ -1361,6 +1453,8 @@ var NodeUserAuthorization = class {
|
|
|
1361
1453
|
this._chainId = chainId;
|
|
1362
1454
|
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
1363
1455
|
this.assertSignInCurrent(generation);
|
|
1456
|
+
await this.refreshNamedKeyFeatureForSignIn(address, chainId);
|
|
1457
|
+
this.assertSignInCurrent(generation);
|
|
1364
1458
|
const keyId = `session-${Date.now()}`;
|
|
1365
1459
|
this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
|
|
1366
1460
|
this.activeSessionKeyId = keyId;
|
|
@@ -1373,7 +1467,7 @@ var NodeUserAuthorization = class {
|
|
|
1373
1467
|
const spaceId = capabilityPlan.spaceId;
|
|
1374
1468
|
const now = /* @__PURE__ */ new Date();
|
|
1375
1469
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
1376
|
-
const prepared = this.
|
|
1470
|
+
const prepared = this.prepareSessionWithResources({
|
|
1377
1471
|
abilities: capabilityPlan.abilities,
|
|
1378
1472
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
1379
1473
|
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
@@ -1507,9 +1601,9 @@ var NodeUserAuthorization = class {
|
|
|
1507
1601
|
refuseCaveated(this.getCapabilityRequest()?.manifests);
|
|
1508
1602
|
const address = canonicalizeAddress(await this.signer.getAddress());
|
|
1509
1603
|
const chainId = await this.signer.getChainId();
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
this.
|
|
1604
|
+
await this.refreshNamedKeyFeatureForSignIn(address, chainId);
|
|
1605
|
+
const keyId = `openkey-session-${Date.now()}-${++this.preparedSessionCounter}`;
|
|
1606
|
+
this.sessionManager.createSessionKey(keyId);
|
|
1513
1607
|
const jwkString = this.sessionManager.jwk(keyId);
|
|
1514
1608
|
if (!jwkString) {
|
|
1515
1609
|
throw new Error("Failed to create session key");
|
|
@@ -1519,7 +1613,7 @@ var NodeUserAuthorization = class {
|
|
|
1519
1613
|
const spaceId = capabilityPlan.spaceId;
|
|
1520
1614
|
const now = /* @__PURE__ */ new Date();
|
|
1521
1615
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
1522
|
-
const prepared = this.
|
|
1616
|
+
const prepared = this.prepareSessionWithResources({
|
|
1523
1617
|
abilities: capabilityPlan.abilities,
|
|
1524
1618
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
1525
1619
|
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
@@ -1590,6 +1684,7 @@ var NodeUserAuthorization = class {
|
|
|
1590
1684
|
await this.sessionStorage.save(address, persistedData);
|
|
1591
1685
|
this._session = clientSession;
|
|
1592
1686
|
this._tinyCloudSession = tinyCloudSession;
|
|
1687
|
+
this.activeSessionKeyId = keyId;
|
|
1593
1688
|
this._address = address;
|
|
1594
1689
|
this._chainId = chainId;
|
|
1595
1690
|
await this.refreshNodeInfo();
|
|
@@ -1636,6 +1731,11 @@ var NodeUserAuthorization = class {
|
|
|
1636
1731
|
* @param options Optional overrides for the OpenKey request.
|
|
1637
1732
|
*/
|
|
1638
1733
|
async signInWithOpenKey(authorizeFn, options) {
|
|
1734
|
+
const pending = await this.prepareOpenKeySignIn(options);
|
|
1735
|
+
return this.completeOpenKeySignIn(pending, authorizeFn(pending.request), options);
|
|
1736
|
+
}
|
|
1737
|
+
/** Finish address, host and SIWE preparation before an approval click. */
|
|
1738
|
+
async prepareOpenKeySignIn(options) {
|
|
1639
1739
|
refuseCaveated(this.getCapabilityRequest()?.manifests);
|
|
1640
1740
|
if (options?.host !== void 0) {
|
|
1641
1741
|
const overrideHost = options.host.trim();
|
|
@@ -1647,7 +1747,7 @@ var NodeUserAuthorization = class {
|
|
|
1647
1747
|
const signingAddress = canonicalizeAddress(await this.signer.getAddress());
|
|
1648
1748
|
const signingChainId = await this.signer.getChainId();
|
|
1649
1749
|
await this.resolveTinyCloudHostsForSignIn(signingAddress, signingChainId);
|
|
1650
|
-
const { prepared, keyId, jwk } = await this.prepareSessionForSigning();
|
|
1750
|
+
const { prepared, keyId, jwk, address, chainId } = await this.prepareSessionForSigning();
|
|
1651
1751
|
const presentation = this.buildPresentationEnvelope(options?.reason);
|
|
1652
1752
|
const hostHint = this.primaryTinyCloudHost;
|
|
1653
1753
|
const originalRequest = {
|
|
@@ -1659,12 +1759,32 @@ var NodeUserAuthorization = class {
|
|
|
1659
1759
|
keyId: options?.openkeyKeyId,
|
|
1660
1760
|
presentation
|
|
1661
1761
|
};
|
|
1762
|
+
return {
|
|
1763
|
+
request: originalRequest,
|
|
1764
|
+
prepared,
|
|
1765
|
+
keyId,
|
|
1766
|
+
jwk,
|
|
1767
|
+
address,
|
|
1768
|
+
chainId,
|
|
1769
|
+
generation: this.sessionGeneration,
|
|
1770
|
+
createdAt: Date.now()
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
/** Complete a prepared approval. The caller starts authorization before awaiting this method. */
|
|
1774
|
+
async completeOpenKeySignIn(pending, authorization, options) {
|
|
1775
|
+
if (Date.now() - pending.createdAt > 5 * 6e4) {
|
|
1776
|
+
throw new Error("Prepared OpenKey sign-in expired; prepare again");
|
|
1777
|
+
}
|
|
1778
|
+
if (pending.generation !== this.sessionGeneration) {
|
|
1779
|
+
throw new Error("Prepared OpenKey sign-in expired after sign-out");
|
|
1780
|
+
}
|
|
1781
|
+
const { request: originalRequest, prepared, keyId, jwk } = pending;
|
|
1662
1782
|
let result;
|
|
1663
1783
|
let signed;
|
|
1664
1784
|
let signature;
|
|
1665
1785
|
for (let attempt = 0; ; ) {
|
|
1666
1786
|
try {
|
|
1667
|
-
result ?? (result = await
|
|
1787
|
+
result ?? (result = await authorization);
|
|
1668
1788
|
signed = await this.verifyOpenKeyResult(result, prepared);
|
|
1669
1789
|
signature = result.signature;
|
|
1670
1790
|
break;
|
|
@@ -2085,6 +2205,50 @@ var NodeUserAuthorization = class {
|
|
|
2085
2205
|
}
|
|
2086
2206
|
};
|
|
2087
2207
|
|
|
2208
|
+
// src/authorization/openKeyBridge.ts
|
|
2209
|
+
function wireOpenKeyAuthorize(openkey, opts) {
|
|
2210
|
+
return async (input) => {
|
|
2211
|
+
const result = await openkey.authorizeTinyCloud({
|
|
2212
|
+
protocolVersion: 1,
|
|
2213
|
+
siwe: input.siwe,
|
|
2214
|
+
keyId: input.keyId,
|
|
2215
|
+
jwk: input.jwk,
|
|
2216
|
+
host: input.host,
|
|
2217
|
+
// Forward the presentation envelope verbatim — the OpenKey SDK
|
|
2218
|
+
// validates and size-bounds it before use.
|
|
2219
|
+
presentation: input.presentation
|
|
2220
|
+
}, opts);
|
|
2221
|
+
if (result.protocolVersion !== 1) {
|
|
2222
|
+
throw new Error(
|
|
2223
|
+
`wireOpenKeyAuthorize: OpenKey returned unsupported protocolVersion ${result.protocolVersion}`
|
|
2224
|
+
);
|
|
2225
|
+
}
|
|
2226
|
+
if (typeof result.signedMessage !== "string" || !result.signedMessage) {
|
|
2227
|
+
throw new Error(
|
|
2228
|
+
"wireOpenKeyAuthorize: OpenKey returned no signedMessage \u2014 cannot complete a TinyCloud session"
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
if (!Array.isArray(result.selectedActionKeys)) {
|
|
2232
|
+
throw new Error(
|
|
2233
|
+
"wireOpenKeyAuthorize: OpenKey returned no selectedActionKeys"
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
if (!Array.isArray(result.permissions)) {
|
|
2237
|
+
throw new Error(
|
|
2238
|
+
"wireOpenKeyAuthorize: OpenKey returned no permissions"
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
return {
|
|
2242
|
+
protocolVersion: 1,
|
|
2243
|
+
address: result.address,
|
|
2244
|
+
signature: result.signature,
|
|
2245
|
+
signedMessage: result.signedMessage,
|
|
2246
|
+
selectedActionKeys: result.selectedActionKeys,
|
|
2247
|
+
permissions: result.permissions
|
|
2248
|
+
};
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2088
2252
|
// src/recordingServiceContext.ts
|
|
2089
2253
|
import {
|
|
2090
2254
|
ServiceContext
|
|
@@ -2770,10 +2934,12 @@ import {
|
|
|
2770
2934
|
ENCRYPTION_PERMISSION_SERVICE as ENCRYPTION_PERMISSION_SERVICE2,
|
|
2771
2935
|
CaveatedDelegationUnsupportedError as CaveatedDelegationUnsupportedError2,
|
|
2772
2936
|
PermissionNotInManifestError,
|
|
2937
|
+
ManifestValidationError as ManifestValidationError2,
|
|
2773
2938
|
SessionExpiredError,
|
|
2774
2939
|
canonicalizeRecapCaveats as canonicalizeRecapCaveats2,
|
|
2775
2940
|
recapCaveatsEqual as recapCaveatsEqual2,
|
|
2776
2941
|
expandPermissionEntries as expandPermissionEntriesCore,
|
|
2942
|
+
expandDelegationPermissionEntries,
|
|
2777
2943
|
isCapabilitySubset as isCapabilitySubset2,
|
|
2778
2944
|
isExplicitOnlyAction,
|
|
2779
2945
|
parseRecapCapabilities,
|
|
@@ -2804,6 +2970,7 @@ import {
|
|
|
2804
2970
|
withoutShareLink,
|
|
2805
2971
|
verifyEip191MessageSignature,
|
|
2806
2972
|
signCompactUcanRootAuthorization,
|
|
2973
|
+
signCompactUcanAuthorization,
|
|
2807
2974
|
markDelegationTerminal,
|
|
2808
2975
|
isStorageFullError,
|
|
2809
2976
|
STORAGE_FULL_MESSAGE,
|
|
@@ -2819,6 +2986,7 @@ import {
|
|
|
2819
2986
|
tinyCloudDebugLogger
|
|
2820
2987
|
} from "@tinycloud/sdk-services";
|
|
2821
2988
|
import { RequestLog, observeReplicaReads, readOnlyRequestLog } from "@tinycloud/sdk-services/telemetry/requestLog";
|
|
2989
|
+
import { parseEncryptionResource as parseEncryptionResource2 } from "@tinycloud/sdk-services/encryption/resource";
|
|
2822
2990
|
|
|
2823
2991
|
// src/account/AccountService.ts
|
|
2824
2992
|
import { AccountService } from "@tinycloud/sdk-core";
|
|
@@ -3310,6 +3478,7 @@ var ROOT_DELEGATION_ACTIONS = [
|
|
|
3310
3478
|
DUCKDB2.ALL
|
|
3311
3479
|
];
|
|
3312
3480
|
var DEFAULT_SESSION_EXPIRATION_MS = EXPIRY3.SESSION_MS;
|
|
3481
|
+
var OWNER_REVOCATION_WINDOW_MS = 10 * 6e4;
|
|
3313
3482
|
function unifiedRootAttenuation(capabilities) {
|
|
3314
3483
|
const attenuation = {};
|
|
3315
3484
|
for (const capability of capabilities) {
|
|
@@ -3807,6 +3976,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3807
3976
|
constructor(config = {}) {
|
|
3808
3977
|
this.signer = null;
|
|
3809
3978
|
this.auth = null;
|
|
3979
|
+
this.consumedOpenKeyPendings = /* @__PURE__ */ new WeakSet();
|
|
3810
3980
|
this.tc = null;
|
|
3811
3981
|
this._chainId = 1;
|
|
3812
3982
|
this.replicaPurgeFailedHandlers = /* @__PURE__ */ new Set();
|
|
@@ -3841,6 +4011,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3841
4011
|
return void 0;
|
|
3842
4012
|
}
|
|
3843
4013
|
};
|
|
4014
|
+
this._keysUnavailable = [];
|
|
3844
4015
|
this._baseVaults = /* @__PURE__ */ new Map();
|
|
3845
4016
|
this._baseSecrets = /* @__PURE__ */ new Map();
|
|
3846
4017
|
this._secrets = /* @__PURE__ */ new Map();
|
|
@@ -4668,6 +4839,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4668
4839
|
this._hooks = void 0;
|
|
4669
4840
|
this._vault = void 0;
|
|
4670
4841
|
this._encryption = void 0;
|
|
4842
|
+
this._namedKeyClient = void 0;
|
|
4843
|
+
this._keysUnavailable = [];
|
|
4671
4844
|
this._baseVaults.clear();
|
|
4672
4845
|
this._baseSecrets.clear();
|
|
4673
4846
|
this._secrets.clear();
|
|
@@ -4744,6 +4917,37 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4744
4917
|
}
|
|
4745
4918
|
await this.signInWith(() => this.auth.signInWithOpenKey(authorizeFn, options));
|
|
4746
4919
|
}
|
|
4920
|
+
/** Prepare the OpenKey request before the approval click. */
|
|
4921
|
+
async prepareOpenKeySignIn() {
|
|
4922
|
+
if (!this.signer || !this.tc || !this.auth) {
|
|
4923
|
+
throw new Error("Cannot prepare OpenKey sign-in in session-only mode. Provide a signer in config.");
|
|
4924
|
+
}
|
|
4925
|
+
await this.signOutInFlight;
|
|
4926
|
+
await this.accountRegistryTail;
|
|
4927
|
+
await this.wasmBindings.ensureInitialized?.();
|
|
4928
|
+
return this.auth.prepareOpenKeySignIn();
|
|
4929
|
+
}
|
|
4930
|
+
/** Start OpenKey authorization synchronously, then complete normal session setup. */
|
|
4931
|
+
signInWithPreparedOpenKey(pending, authorizeFn) {
|
|
4932
|
+
if (!this.signer || !this.tc || !this.auth || this.signOutInFlight) {
|
|
4933
|
+
throw new Error("Prepared OpenKey sign-in is unavailable");
|
|
4934
|
+
}
|
|
4935
|
+
if (this.consumedOpenKeyPendings.has(pending)) {
|
|
4936
|
+
throw new Error("Prepared OpenKey sign-in was already used");
|
|
4937
|
+
}
|
|
4938
|
+
if (Date.now() - pending.createdAt > 5 * 6e4) {
|
|
4939
|
+
throw new Error("Prepared OpenKey sign-in expired; prepare again");
|
|
4940
|
+
}
|
|
4941
|
+
this.consumedOpenKeyPendings.add(pending);
|
|
4942
|
+
const authorization = authorizeFn(pending.request);
|
|
4943
|
+
void authorization.catch(() => void 0);
|
|
4944
|
+
return this.signInWith(() => {
|
|
4945
|
+
if (this._address !== pending.address || this._chainId !== pending.chainId) {
|
|
4946
|
+
throw new Error("OpenKey account changed after sign-in preparation");
|
|
4947
|
+
}
|
|
4948
|
+
return this.auth.completeOpenKeySignIn(pending, authorization);
|
|
4949
|
+
});
|
|
4950
|
+
}
|
|
4747
4951
|
async signInWith(performSignIn) {
|
|
4748
4952
|
refuseCaveated(this.auth?.capabilityRequest?.manifests);
|
|
4749
4953
|
const epoch = this.sessionEpoch;
|
|
@@ -4790,6 +4994,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4790
4994
|
this._hooks = void 0;
|
|
4791
4995
|
this._vault = void 0;
|
|
4792
4996
|
this._encryption = void 0;
|
|
4997
|
+
this._namedKeyClient = void 0;
|
|
4998
|
+
this._keysUnavailable = [];
|
|
4793
4999
|
this._baseVaults.clear();
|
|
4794
5000
|
this._baseSecrets.clear();
|
|
4795
5001
|
this._secrets.clear();
|
|
@@ -4842,6 +5048,26 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4842
5048
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
4843
5049
|
await this.ensureRequestedEncryptionNetworks();
|
|
4844
5050
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
5051
|
+
this._keysUnavailable = this.auth?.unavailableKeyPaths ?? [];
|
|
5052
|
+
if (this._keysUnavailable.length > 0) {
|
|
5053
|
+
this.notificationHandler.warning(`Named keys unavailable: ${this._keysUnavailable.join(", ")}`);
|
|
5054
|
+
}
|
|
5055
|
+
if (this.nodeFeatures.includes("encryption-named-keys-v1")) {
|
|
5056
|
+
for (const manifest of this.auth?.capabilityRequest?.manifests ?? []) {
|
|
5057
|
+
for (const declaration of manifest.keys ?? []) {
|
|
5058
|
+
if ("path" in declaration && declaration.abilities.includes("key.create") && !this._keysUnavailable.includes(declaration.path)) {
|
|
5059
|
+
try {
|
|
5060
|
+
await this.keys.ensureKey(declaration.path);
|
|
5061
|
+
} catch (error) {
|
|
5062
|
+
this._keysUnavailable.push(declaration.path);
|
|
5063
|
+
const code = error && typeof error === "object" && "code" in error && typeof error.code === "string" && /^[A-Z_]+$/.test(error.code) ? error.code : "UNKNOWN";
|
|
5064
|
+
this.notificationHandler.warning(`Named key unavailable: ${declaration.path} (${code})`);
|
|
5065
|
+
}
|
|
5066
|
+
this.assertSessionEpoch(epoch, "Sign-in");
|
|
5067
|
+
}
|
|
5068
|
+
}
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
4845
5071
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
4846
5072
|
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(SECRETS_SPACE2));
|
|
4847
5073
|
}
|
|
@@ -5629,7 +5855,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5629
5855
|
const networkIds = /* @__PURE__ */ new Set();
|
|
5630
5856
|
for (const resource of request.resources) {
|
|
5631
5857
|
if (resource.service === ENCRYPTION_PERMISSION_SERVICE2 && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
|
|
5632
|
-
|
|
5858
|
+
const parsed = resource.path.includes("/") ? parseEncryptionResource2(resource.path) : { ...parseNetworkId2(resource.path), kind: "network" };
|
|
5859
|
+
if (parsed.kind === "network") networkIds.add(resource.path);
|
|
5633
5860
|
}
|
|
5634
5861
|
}
|
|
5635
5862
|
return [...networkIds];
|
|
@@ -6179,6 +6406,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6179
6406
|
this._hooks = stagedGraph.hooks;
|
|
6180
6407
|
this._vault = stagedGraph.vault;
|
|
6181
6408
|
this._encryption = stagedGraph.encryption;
|
|
6409
|
+
this._namedKeyClient = void 0;
|
|
6410
|
+
this._keysUnavailable = [];
|
|
6182
6411
|
this._capabilityRegistry = stagedGraph.capabilityRegistry;
|
|
6183
6412
|
this._keyProvider = stagedGraph.keyProvider;
|
|
6184
6413
|
this._sharingService = stagedGraph.sharingService;
|
|
@@ -6360,6 +6589,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6360
6589
|
invoke: graph.invoke,
|
|
6361
6590
|
invokeAny: graph.invokeAny,
|
|
6362
6591
|
signOwnerRevocation: this.signer ? (cid) => this.signOwnerRevocation(cid) : void 0,
|
|
6592
|
+
sessionInvocationSigner: this.sessionInvocationSignerFor(input.serviceSession),
|
|
6363
6593
|
fetch: graph.fetch
|
|
6364
6594
|
});
|
|
6365
6595
|
const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
|
|
@@ -6575,6 +6805,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6575
6805
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
6576
6806
|
return signBytesWithJwk(bytes, session.jwk);
|
|
6577
6807
|
}
|
|
6808
|
+
/**
|
|
6809
|
+
* Signs proofless invocations with `session`'s own did:key, for the node's
|
|
6810
|
+
* issued-delegation list and revocation by the delegator. The audience is
|
|
6811
|
+
* this Node's DID; each invocation lives 60 seconds.
|
|
6812
|
+
*/
|
|
6813
|
+
sessionInvocationSignerFor(session) {
|
|
6814
|
+
return {
|
|
6815
|
+
did: () => session.verificationMethod.split("#", 1)[0],
|
|
6816
|
+
sign: async (attenuation) => {
|
|
6817
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
6818
|
+
const invocation = await signCompactUcanAuthorization({
|
|
6819
|
+
issuerDid: session.verificationMethod.split("#", 1)[0],
|
|
6820
|
+
audienceDid: await this.fetchNodeId(),
|
|
6821
|
+
attenuation,
|
|
6822
|
+
facts: [{}],
|
|
6823
|
+
proofs: [],
|
|
6824
|
+
notBefore: now,
|
|
6825
|
+
expiresAt: now + 60,
|
|
6826
|
+
nonce: `urn:uuid:${crypto.randomUUID()}`,
|
|
6827
|
+
sign: (bytes) => signBytesWithJwk(bytes, session.jwk)
|
|
6828
|
+
});
|
|
6829
|
+
return invocation.authorization;
|
|
6830
|
+
}
|
|
6831
|
+
};
|
|
6832
|
+
}
|
|
6578
6833
|
/** Author a proofless Policy/v3 owner root with the authenticated holder key. */
|
|
6579
6834
|
async createUnifiedOwnerRoot(input) {
|
|
6580
6835
|
const ownerDid = this.credentialHolderDid;
|
|
@@ -7109,7 +7364,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7109
7364
|
graph.assertActive();
|
|
7110
7365
|
const signed = await this.signRawNetworkAuthorization({
|
|
7111
7366
|
targetNode: input.targetNode,
|
|
7112
|
-
networkId: input.networkId
|
|
7367
|
+
networkId: input.body.keyPath === void 0 ? input.networkId : `${input.networkId}/${input.body.keyPath}`,
|
|
7113
7368
|
action: DECRYPT_ACTION2,
|
|
7114
7369
|
facts: input.facts
|
|
7115
7370
|
}, { graph, session });
|
|
@@ -7282,6 +7537,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7282
7537
|
invoke: graph.invoke,
|
|
7283
7538
|
invokeAny: graph.invokeAny,
|
|
7284
7539
|
signOwnerRevocation: this.signer ? (cid) => this.signOwnerRevocation(cid) : void 0,
|
|
7540
|
+
sessionInvocationSigner: this.sessionInvocationSignerFor(serviceSession),
|
|
7285
7541
|
fetch: graph.fetch
|
|
7286
7542
|
});
|
|
7287
7543
|
this._spaceService = new SpaceService({
|
|
@@ -7532,7 +7788,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7532
7788
|
* Sign a wallet (CACAO) revocation of the delegation `cid` for the node's
|
|
7533
7789
|
* `POST /revoke`, and return its Authorization header value. The node
|
|
7534
7790
|
* accepts it when the owner delegated `cid` or owns a space its abilities
|
|
7535
|
-
* target, whichever key issued it. Valid for
|
|
7791
|
+
* target, whichever key issued it. Valid for 10 minutes. Requires the
|
|
7536
7792
|
* owner wallet signer.
|
|
7537
7793
|
*/
|
|
7538
7794
|
async signOwnerRevocation(cid) {
|
|
@@ -7548,7 +7804,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7548
7804
|
chainId: session.chainId,
|
|
7549
7805
|
nonce: generateNonce(),
|
|
7550
7806
|
issuedAt: issuedAt.toISOString(),
|
|
7551
|
-
expirationTime: new Date(issuedAt.getTime() +
|
|
7807
|
+
expirationTime: new Date(issuedAt.getTime() + OWNER_REVOCATION_WINDOW_MS).toISOString()
|
|
7552
7808
|
}).prepareMessage();
|
|
7553
7809
|
const signature = await this.signer.signMessage(siwe);
|
|
7554
7810
|
return this.wasmBindings.siweToDelegationHeaders({ siwe, signature }).Authorization;
|
|
@@ -7775,6 +8031,40 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7775
8031
|
get encryption() {
|
|
7776
8032
|
return this.getEncryptionService();
|
|
7777
8033
|
}
|
|
8034
|
+
/** Named keys bound to the current session. */
|
|
8035
|
+
get keys() {
|
|
8036
|
+
return new Proxy({}, {
|
|
8037
|
+
get: (_target, property) => {
|
|
8038
|
+
if (property === "refreshNodeInfo") {
|
|
8039
|
+
return () => {
|
|
8040
|
+
void this._namedKeyClient?.then((client) => client.refreshNodeInfo());
|
|
8041
|
+
};
|
|
8042
|
+
}
|
|
8043
|
+
if (typeof property !== "string" || ![
|
|
8044
|
+
"getPublicKey",
|
|
8045
|
+
"describeKey",
|
|
8046
|
+
"createKey",
|
|
8047
|
+
"blockKey",
|
|
8048
|
+
"unblockKey",
|
|
8049
|
+
"ensureKey",
|
|
8050
|
+
"encrypt",
|
|
8051
|
+
"decrypt",
|
|
8052
|
+
"decryptMany"
|
|
8053
|
+
].includes(property)) return void 0;
|
|
8054
|
+
return (...args) => {
|
|
8055
|
+
this._namedKeyClient ?? (this._namedKeyClient = import("./encryption-keys.js").then(({ createNamedKeyClient }) => createNamedKeyClient(this)));
|
|
8056
|
+
return this._namedKeyClient.then((client) => {
|
|
8057
|
+
const method = client[property];
|
|
8058
|
+
return method.apply(client, args);
|
|
8059
|
+
});
|
|
8060
|
+
};
|
|
8061
|
+
}
|
|
8062
|
+
});
|
|
8063
|
+
}
|
|
8064
|
+
/** Manifest key paths unavailable during the latest `signIn()` attempt. */
|
|
8065
|
+
get keysUnavailable() {
|
|
8066
|
+
return this._keysUnavailable;
|
|
8067
|
+
}
|
|
7778
8068
|
async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
|
|
7779
8069
|
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
7780
8070
|
return this.fetchEncryptionNetworkAt(
|
|
@@ -8664,7 +8954,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8664
8954
|
"delegateTo requires a non-empty permissions array"
|
|
8665
8955
|
);
|
|
8666
8956
|
}
|
|
8667
|
-
const expandedEntries =
|
|
8957
|
+
const expandedEntries = expandDelegationPermissionEntries(permissions);
|
|
8958
|
+
const namedKeyEntries = expandedEntries.filter((entry) => entry.service === ENCRYPTION_PERMISSION_SERVICE2 && entry.path.includes("/"));
|
|
8959
|
+
if (namedKeyEntries.length > 0) {
|
|
8960
|
+
if (expandedEntries.some((entry) => entry.service === ENCRYPTION_PERMISSION_SERVICE2 && !entry.path.includes("/"))) {
|
|
8961
|
+
throw new ManifestValidationError2("named-key delegation cannot include bare-network permissions");
|
|
8962
|
+
}
|
|
8963
|
+
if (options?.forceWalletSign) {
|
|
8964
|
+
throw new ManifestValidationError2("named-key delegation requires a signed session grant");
|
|
8965
|
+
}
|
|
8966
|
+
const granted = this.projectSignedRecapCapabilities(session.siwe);
|
|
8967
|
+
const { subset, missing } = this.signedCapabilitySubset(namedKeyEntries, granted);
|
|
8968
|
+
if (!subset) throw new PermissionNotInManifestError(missing, granted);
|
|
8969
|
+
}
|
|
8668
8970
|
const now = /* @__PURE__ */ new Date();
|
|
8669
8971
|
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
8670
8972
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
@@ -10049,7 +10351,7 @@ import {
|
|
|
10049
10351
|
CaveatedDelegationUnsupportedError as CaveatedDelegationUnsupportedError3,
|
|
10050
10352
|
PermissionNotInManifestError as PermissionNotInManifestError2,
|
|
10051
10353
|
SessionExpiredError as SessionExpiredError2,
|
|
10052
|
-
ManifestValidationError,
|
|
10354
|
+
ManifestValidationError as ManifestValidationError3,
|
|
10053
10355
|
composeManifestRequest as composeManifestRequest2,
|
|
10054
10356
|
resolveManifest as resolveManifest2,
|
|
10055
10357
|
validateManifest,
|
|
@@ -10134,12 +10436,13 @@ export {
|
|
|
10134
10436
|
IdentityParseError,
|
|
10135
10437
|
InvalidRestoredSessionError,
|
|
10136
10438
|
KVService3 as KVService,
|
|
10137
|
-
ManifestValidationError,
|
|
10439
|
+
ManifestValidationError3 as ManifestValidationError,
|
|
10138
10440
|
MemorySessionStorage,
|
|
10139
10441
|
NodeUserAuthorization,
|
|
10140
10442
|
PermissionNotInManifestError2 as PermissionNotInManifestError,
|
|
10141
10443
|
PrefixedKVService,
|
|
10142
10444
|
ProtocolMismatchError2 as ProtocolMismatchError,
|
|
10445
|
+
RuntimeDelegationRejectedError,
|
|
10143
10446
|
SECRET_NAME_RE,
|
|
10144
10447
|
SQLAction,
|
|
10145
10448
|
SQLService3 as SQLService,
|
|
@@ -10162,6 +10465,7 @@ export {
|
|
|
10162
10465
|
VersionCheckError,
|
|
10163
10466
|
WasmKeyProvider,
|
|
10164
10467
|
activateCompactRuntimeDelegation,
|
|
10468
|
+
activateValidatedRuntimeDelegation,
|
|
10165
10469
|
addressStorageKey,
|
|
10166
10470
|
buildSpaceUri,
|
|
10167
10471
|
canonicalizeAddress3 as canonicalizeAddress,
|
|
@@ -10191,6 +10495,7 @@ export {
|
|
|
10191
10495
|
getNodeReplicationLoaders,
|
|
10192
10496
|
getTinyCloudDebugLogs,
|
|
10193
10497
|
installTinyCloudDebugGlobals,
|
|
10498
|
+
isAppKeyHostBound,
|
|
10194
10499
|
isCapabilitySubset3 as isCapabilitySubset,
|
|
10195
10500
|
isEvmAddress,
|
|
10196
10501
|
loadManifest,
|
|
@@ -10212,6 +10517,7 @@ export {
|
|
|
10212
10517
|
resourceCapabilitiesToSpaceAbilitiesMap2 as resourceCapabilitiesToSpaceAbilitiesMap,
|
|
10213
10518
|
serializeDelegation,
|
|
10214
10519
|
tinyCloudDebugLogger2 as tinyCloudDebugLogger,
|
|
10215
|
-
validateManifest
|
|
10520
|
+
validateManifest,
|
|
10521
|
+
wireOpenKeyAuthorize
|
|
10216
10522
|
};
|
|
10217
10523
|
//# sourceMappingURL=core.js.map
|