@tinycloud/node-sdk 3.12.0-beta.1 → 3.12.0-beta.3
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 +39 -0
- package/dist/{NodeUserAuthorization-BtoDI9in.d.cts → NodeUserAuthorization-B_TFUlua.d.cts} +19 -53
- package/dist/{NodeUserAuthorization-BtoDI9in.d.ts → NodeUserAuthorization-B_TFUlua.d.ts} +19 -53
- package/dist/{TinyCloudNode-DLrINr98.d.ts → TinyCloudNode-Brcu8QoX.d.cts} +33 -59
- package/dist/{TinyCloudNode-C24728N_.d.cts → TinyCloudNode-DBJUnsMN.d.ts} +33 -59
- package/dist/{authority-BQN2Z3st.d.ts → authority-BFc5lesl.d.ts} +1 -1
- package/dist/{authority-DDdheOL6.d.cts → authority-DQ6R1HEG.d.cts} +1 -1
- package/dist/core.cjs +555 -320
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +5 -5
- package/dist/core.d.ts +5 -5
- package/dist/core.js +581 -324
- 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-BQbAuKad.d.cts → delegation-CeOWDnBB.d.cts} +7 -0
- package/dist/{delegation-BQbAuKad.d.ts → delegation-CeOWDnBB.d.ts} +7 -0
- package/dist/encryption-keys.d.cts +3 -3
- package/dist/encryption-keys.d.ts +3 -3
- package/dist/index.cjs +572 -337
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +582 -325
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +4 -4
- package/dist/replication/authority.d.ts +4 -4
- package/dist/space-hosting.cjs +48 -6
- package/dist/space-hosting.cjs.map +1 -1
- package/dist/space-hosting.d.cts +23 -8
- package/dist/space-hosting.d.ts +23 -8
- package/dist/space-hosting.js +48 -6
- package/dist/space-hosting.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -17443,7 +17443,7 @@ import {
|
|
|
17443
17443
|
canonicalizeRecapCaveats as canonicalizeRecapCaveats3,
|
|
17444
17444
|
isCapabilitySubset as isCapabilitySubset3,
|
|
17445
17445
|
principalDid,
|
|
17446
|
-
parseSpaceUri as
|
|
17446
|
+
parseSpaceUri as parseSpaceUri3
|
|
17447
17447
|
} from "@tinycloud/sdk-core";
|
|
17448
17448
|
import { parseUcanGrant as replicaParseUcanGrant } from "@tinycloud/replica";
|
|
17449
17449
|
function reportReplicaDenial(result, reason, onEvent, context) {
|
|
@@ -17625,7 +17625,7 @@ function replicationScopeFromSignedSession(input) {
|
|
|
17625
17625
|
for (const resource of Object.keys(grant.att)) {
|
|
17626
17626
|
const space = resource.match(/^(?:tinycloud:\/\/)?(.+?)\/kv(?:\/|$)/)?.[1];
|
|
17627
17627
|
if (space !== input.persistedSpace) continue;
|
|
17628
|
-
const owner =
|
|
17628
|
+
const owner = parseSpaceUri3(space);
|
|
17629
17629
|
if (owner?.owner && owner.address && owner.chainId) return { space, principal: owner.owner };
|
|
17630
17630
|
}
|
|
17631
17631
|
return void 0;
|
|
@@ -18151,6 +18151,7 @@ import {
|
|
|
18151
18151
|
decodeBase64Url,
|
|
18152
18152
|
principalDidEquals
|
|
18153
18153
|
} from "@tinycloud/sdk-core";
|
|
18154
|
+
import { routingFailure } from "@tinycloud/sdk-services";
|
|
18154
18155
|
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
18155
18156
|
"host_mismatch",
|
|
18156
18157
|
"expired",
|
|
@@ -18192,7 +18193,8 @@ var SERVICE_BY_SHORT_NAME = {
|
|
|
18192
18193
|
kv: "tinycloud.kv",
|
|
18193
18194
|
sql: "tinycloud.sql",
|
|
18194
18195
|
duckdb: "tinycloud.duckdb",
|
|
18195
|
-
hooks: "tinycloud.hooks"
|
|
18196
|
+
hooks: "tinycloud.hooks",
|
|
18197
|
+
capabilities: "tinycloud.capabilities"
|
|
18196
18198
|
};
|
|
18197
18199
|
function authorizationWithoutBearer(authorization) {
|
|
18198
18200
|
return authorization.replace(/^Bearer /i, "");
|
|
@@ -18323,8 +18325,8 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
18323
18325
|
));
|
|
18324
18326
|
continue;
|
|
18325
18327
|
}
|
|
18326
|
-
const match = /^(?:tinycloud:\/\/([^/]+)|(tinycloud:[^/]+))\/(
|
|
18327
|
-
if (!match) {
|
|
18328
|
+
const match = /^(?:tinycloud:\/\/([^/]+)|(tinycloud:[^/]+))\/([^/]+)(?:\/|$)(.*)$/.exec(resource);
|
|
18329
|
+
if (!match || !Object.prototype.hasOwnProperty.call(SERVICE_BY_SHORT_NAME, match[3])) {
|
|
18328
18330
|
throw new Error(
|
|
18329
18331
|
`Validated runtime delegation has an unsupported signed resource '${resource}'.`
|
|
18330
18332
|
);
|
|
@@ -18469,13 +18471,8 @@ function resourcesMatch(actual, expected) {
|
|
|
18469
18471
|
return JSON.stringify(actual.map(comparable)) === JSON.stringify(expected.map(comparable));
|
|
18470
18472
|
}
|
|
18471
18473
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
reject(
|
|
18475
|
-
"host_mismatch",
|
|
18476
|
-
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
18477
|
-
);
|
|
18478
|
-
}
|
|
18474
|
+
let host = normalizedHost(options.host);
|
|
18475
|
+
const differentHost = delegation.host !== void 0 && normalizedHost(delegation.host) !== host;
|
|
18479
18476
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
18480
18477
|
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
18481
18478
|
}
|
|
@@ -18519,6 +18516,13 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
18519
18516
|
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
18520
18517
|
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
18521
18518
|
}
|
|
18519
|
+
if (differentHost) {
|
|
18520
|
+
const registeredHost = await node.resolveRegisteredDelegationHost?.(signed2.permissions, host);
|
|
18521
|
+
if (registeredHost === void 0) {
|
|
18522
|
+
reject("host_mismatch", `Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`);
|
|
18523
|
+
}
|
|
18524
|
+
host = normalizedHost(registeredHost);
|
|
18525
|
+
}
|
|
18522
18526
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
18523
18527
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
18524
18528
|
reject(
|
|
@@ -18562,6 +18566,7 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
18562
18566
|
await node.useRuntimeDelegation(installedCandidate);
|
|
18563
18567
|
}
|
|
18564
18568
|
} catch (error) {
|
|
18569
|
+
if (routingFailure(error)) throw error;
|
|
18565
18570
|
reject(
|
|
18566
18571
|
activationRejectionReason(error),
|
|
18567
18572
|
error instanceof Error ? error.message : String(error)
|
|
@@ -18580,6 +18585,7 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
18580
18585
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
18581
18586
|
);
|
|
18582
18587
|
}
|
|
18588
|
+
node.refreshRegistryForCapabilities?.(signed2.permissions);
|
|
18583
18589
|
return {
|
|
18584
18590
|
cid,
|
|
18585
18591
|
delegation: installed,
|
|
@@ -18689,6 +18695,15 @@ function deserializeDelegation(data) {
|
|
|
18689
18695
|
}
|
|
18690
18696
|
|
|
18691
18697
|
// src/TinyCloudNode.ts
|
|
18698
|
+
import {
|
|
18699
|
+
createResourceRoutingFetch,
|
|
18700
|
+
verifyResourceDestination as verifyResourceDestination2,
|
|
18701
|
+
NodeNotRespondingError as NodeNotRespondingError2,
|
|
18702
|
+
NodeIdentityMismatchError,
|
|
18703
|
+
PartialNodeWriteError as PartialNodeWriteError2,
|
|
18704
|
+
ResourceNotRoutedError,
|
|
18705
|
+
routingFailure as routingFailure3
|
|
18706
|
+
} from "@tinycloud/sdk-services";
|
|
18692
18707
|
import { generateNonce, SiweMessage as SiweMessage3 } from "siwe";
|
|
18693
18708
|
import { didKeyFromEd25519PublicKey } from "@tinycloud/share-envelope";
|
|
18694
18709
|
|
|
@@ -18762,9 +18777,15 @@ import {
|
|
|
18762
18777
|
verifyDidKeyEd25519Signature,
|
|
18763
18778
|
canonicalizeAddress as canonicalizeAddress2,
|
|
18764
18779
|
pkhDid as pkhDid2,
|
|
18765
|
-
|
|
18766
|
-
|
|
18780
|
+
parseSpaceUri as parseSpaceUri2,
|
|
18781
|
+
resolveRegistryResource as resolveRegistryResource2,
|
|
18782
|
+
warnRegistryDefaultNode as warnRegistryDefaultNode2,
|
|
18783
|
+
NodeNotFoundError as NodeNotFoundError2,
|
|
18784
|
+
exactHttpOrigin as exactHttpOrigin2,
|
|
18767
18785
|
createInMemoryRegistrySequenceStore as createInMemoryRegistrySequenceStore2,
|
|
18786
|
+
createInMemoryRegistryCacheStore as createInMemoryRegistryCacheStore2,
|
|
18787
|
+
refreshOwnerRegistry,
|
|
18788
|
+
registryOwnerKeyV2,
|
|
18768
18789
|
publishLocationRecord,
|
|
18769
18790
|
principalDidEquals as principalDidEquals3,
|
|
18770
18791
|
parseNetworkId as parseNetworkId2,
|
|
@@ -18811,11 +18832,16 @@ import {
|
|
|
18811
18832
|
principalDidEquals as principalDidEquals2,
|
|
18812
18833
|
resourceCapabilitiesToAbilitiesMap,
|
|
18813
18834
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
|
|
18835
|
+
resolveRegistryResource,
|
|
18836
|
+
warnRegistryDefaultNode,
|
|
18837
|
+
parseSpaceUri,
|
|
18838
|
+
NodeNotFoundError,
|
|
18839
|
+
RegistryUnavailableError,
|
|
18840
|
+
discoverLocalTinyCloudNode,
|
|
18841
|
+
exactHttpOrigin,
|
|
18817
18842
|
assertSpaceCreationAllowed,
|
|
18818
18843
|
createInMemoryRegistrySequenceStore,
|
|
18844
|
+
createInMemoryRegistryCacheStore,
|
|
18819
18845
|
registryOwnerSubjectV1,
|
|
18820
18846
|
EXPIRY,
|
|
18821
18847
|
assertExpiryWithinTechnicalLimit,
|
|
@@ -18838,7 +18864,13 @@ import {
|
|
|
18838
18864
|
ENCRYPTION
|
|
18839
18865
|
} from "@tinycloud/sdk-core";
|
|
18840
18866
|
import { parseEncryptionResource } from "@tinycloud/sdk-services/encryption/resource";
|
|
18841
|
-
import {
|
|
18867
|
+
import {
|
|
18868
|
+
parseNetworkId,
|
|
18869
|
+
verifyResourceDestination,
|
|
18870
|
+
NodeNotRespondingError,
|
|
18871
|
+
PartialNodeWriteError,
|
|
18872
|
+
routingFailure as routingFailure2
|
|
18873
|
+
} from "@tinycloud/sdk-services";
|
|
18842
18874
|
|
|
18843
18875
|
// src/authorization/appKeyHostBinding.ts
|
|
18844
18876
|
var DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
@@ -19116,11 +19148,12 @@ var NodeUserAuthorization = class {
|
|
|
19116
19148
|
this.tinycloudHosts = config.tinycloudHosts;
|
|
19117
19149
|
this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
|
|
19118
19150
|
this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
|
|
19119
|
-
this.registryPolicy = config.registryPolicy;
|
|
19120
19151
|
this.newUserHost = config.newUserHost;
|
|
19121
19152
|
this.registryChainId = config.registryChainId;
|
|
19122
19153
|
this.registrySequenceStore = config.registrySequenceStore ?? createInMemoryRegistrySequenceStore();
|
|
19154
|
+
this.registryCacheStore = config.registryCacheStore ?? createInMemoryRegistryCacheStore();
|
|
19123
19155
|
this.onNodeNotFound = config.onNodeNotFound;
|
|
19156
|
+
this.onRegistryFallback = config.onRegistryFallback;
|
|
19124
19157
|
this.autoDiscoverLocalNode = config.autoDiscoverLocalNode;
|
|
19125
19158
|
this.localNodeUrl = config.localNodeUrl;
|
|
19126
19159
|
this.localLinkName = config.localLinkName;
|
|
@@ -19188,13 +19221,8 @@ var NodeUserAuthorization = class {
|
|
|
19188
19221
|
* undefined for missing SIWEs and the SDK then treats the session as
|
|
19189
19222
|
* expired-at-epoch-zero.
|
|
19190
19223
|
*
|
|
19191
|
-
* @param hosts -
|
|
19192
|
-
*
|
|
19193
|
-
* present (and non-empty) they are adopted directly so the restored
|
|
19194
|
-
* session resolves to the same node as the original sign-in without
|
|
19195
|
-
* re-running registry/fallback resolution. When absent (old session)
|
|
19196
|
-
* hosts are resolved lazily on the first host-needing call via
|
|
19197
|
-
* {@link ensureTinyCloudHosts}.
|
|
19224
|
+
* @param hosts - Persisted host hints for genuine no-entry onboarding.
|
|
19225
|
+
* Current signed registry membership always takes precedence.
|
|
19198
19226
|
*/
|
|
19199
19227
|
setRestoredTinyCloudSession(session, hosts) {
|
|
19200
19228
|
const address = canonicalizeAddress(session.address);
|
|
@@ -19256,89 +19284,84 @@ var NodeUserAuthorization = class {
|
|
|
19256
19284
|
signature: session.signature
|
|
19257
19285
|
};
|
|
19258
19286
|
}
|
|
19259
|
-
/**
|
|
19260
|
-
* Ensure `tinycloudHosts` are resolved before a host-needing call.
|
|
19261
|
-
*
|
|
19262
|
-
* Fresh sign-in resolves hosts up front; a restored session may not have
|
|
19263
|
-
* (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
|
|
19264
|
-
* This guard makes a restored session resolve the node exactly like a fresh
|
|
19265
|
-
* sign-in — persisted hosts are preferred (already set by
|
|
19266
|
-
* {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
|
|
19267
|
-
* resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
|
|
19268
|
-
* early-returns when hosts are already set.
|
|
19269
|
-
*
|
|
19270
|
-
* Throws if hosts are unset and the restored session has no address/chainId
|
|
19271
|
-
* to resolve from — a real failure that must surface, not be masked.
|
|
19272
|
-
*/
|
|
19287
|
+
/** Refresh the primary space's registry destinations, including after restore. */
|
|
19273
19288
|
async ensureTinyCloudHosts() {
|
|
19274
|
-
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
19275
|
-
return;
|
|
19276
|
-
}
|
|
19277
19289
|
if (this._address === void 0 || this._chainId === void 0) {
|
|
19278
|
-
throw new Error(
|
|
19279
|
-
"Cannot resolve TinyCloud hosts: no address/chainId available. Sign in or restore a session first."
|
|
19280
|
-
);
|
|
19290
|
+
throw new Error("Cannot resolve TinyCloud hosts: sign in or restore a session first.");
|
|
19281
19291
|
}
|
|
19282
|
-
await this.resolveTinyCloudHostsForSignIn(this._address, this._chainId);
|
|
19292
|
+
await this.resolveTinyCloudHostsForSignIn(this._address, this._chainId, this._tinyCloudSession?.spaceId);
|
|
19283
19293
|
}
|
|
19284
|
-
async resolveTinyCloudHostsForSignIn(address, chainId) {
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
const resolved2 = await resolveFailClosedTinyCloudHosts(address, {
|
|
19290
|
-
registryUrl: this.tinycloudRegistryUrl,
|
|
19291
|
-
registryChainId: this.registryChainId,
|
|
19292
|
-
newUserHost: this.newUserHost,
|
|
19293
|
-
sequenceStore: this.registrySequenceStore,
|
|
19294
|
-
onNodeNotFound: this.onNodeNotFound,
|
|
19295
|
-
autoDiscoverLocalNode: this.autoDiscoverLocalNode,
|
|
19296
|
-
localNodeUrl: this.localNodeUrl,
|
|
19297
|
-
localLinkName: this.localLinkName,
|
|
19298
|
-
expectedNodeDid: this.expectedNodeDid,
|
|
19299
|
-
localNodeIdentityStore: this.localNodeIdentityStore
|
|
19300
|
-
});
|
|
19301
|
-
this.tinycloudHosts = resolved2.hosts;
|
|
19302
|
-
this.registryVerdict = resolved2.verdict;
|
|
19303
|
-
return;
|
|
19304
|
-
}
|
|
19305
|
-
const subject = pkhDid(address, chainId);
|
|
19306
|
-
const resolved = await resolveTinyCloudHosts(subject, {
|
|
19307
|
-
registryUrl: this.tinycloudRegistryUrl,
|
|
19308
|
-
fallbackHosts: this.tinycloudFallbackHosts,
|
|
19309
|
-
autoDiscoverLocalNode: this.autoDiscoverLocalNode,
|
|
19310
|
-
localNodeUrl: this.localNodeUrl,
|
|
19311
|
-
localLinkName: this.localLinkName,
|
|
19312
|
-
expectedNodeDid: this.expectedNodeDid,
|
|
19313
|
-
localNodeIdentityStore: this.localNodeIdentityStore
|
|
19314
|
-
});
|
|
19315
|
-
this.tinycloudHosts = resolved.hosts;
|
|
19294
|
+
async resolveTinyCloudHostsForSignIn(address, chainId, restoredSpaceId) {
|
|
19295
|
+
const spaceId = restoredSpaceId ?? this.resolveSignInCapabilities(address, chainId).spaceId;
|
|
19296
|
+
const destinations = await this.resolveResourceDestinations(spaceId, "read");
|
|
19297
|
+
for (const destination of destinations) await verifyResourceDestination(destination, globalThis.fetch.bind(globalThis));
|
|
19298
|
+
this.tinycloudHosts = destinations.map(({ url }) => url);
|
|
19316
19299
|
}
|
|
19317
|
-
/**
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19300
|
+
/** Current full-resource registry routing; saved hosts are only no-entry hints. */
|
|
19301
|
+
async resolveResourceDestinations(resource, access, noEntryHosts = this.tinycloudHosts ?? []) {
|
|
19302
|
+
const owner = resource.startsWith("urn:tinycloud:encryption:") ? parseNetworkId(resource.split("/")[0]).ownerDid : parseSpaceUri(resource)?.owner ?? (() => {
|
|
19303
|
+
const key2 = /^tinycloud:key:(z[^:]+):[^/]+$/.exec(resource);
|
|
19304
|
+
return key2 ? `did:key:${key2[1]}` : void 0;
|
|
19305
|
+
})();
|
|
19306
|
+
if (!owner) throw new Error(`Cannot determine registry owner for ${resource}`);
|
|
19307
|
+
const subject = owner.startsWith("did:pkh:") ? registryOwnerSubjectV1(owner.slice(owner.lastIndexOf(":") + 1), this.registryChainId) : owner;
|
|
19308
|
+
for (let attempt = 1; ; attempt++) {
|
|
19309
|
+
try {
|
|
19310
|
+
const resolved = await resolveRegistryResource(subject, resource, access, {
|
|
19311
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
19312
|
+
registryChainId: this.registryChainId,
|
|
19313
|
+
sequenceStore: this.registrySequenceStore,
|
|
19314
|
+
cacheStore: this.registryCacheStore,
|
|
19315
|
+
onRegistryFallback: this.onRegistryFallback
|
|
19316
|
+
});
|
|
19317
|
+
this.registryVerdict = resolved.verdict;
|
|
19318
|
+
if (resolved.verdict.status === "unregistered") {
|
|
19319
|
+
if (noEntryHosts.length === 0 && (this.autoDiscoverLocalNode ?? true)) {
|
|
19320
|
+
const local = await discoverLocalTinyCloudNode({
|
|
19321
|
+
localNodeUrl: this.localNodeUrl,
|
|
19322
|
+
localLinkName: this.localLinkName,
|
|
19323
|
+
expectedNodeDid: this.expectedNodeDid,
|
|
19324
|
+
identityStore: this.localNodeIdentityStore
|
|
19325
|
+
});
|
|
19326
|
+
if (local) {
|
|
19327
|
+
warnRegistryDefaultNode(resolved.verdict, this.registryCacheStore, this.onRegistryFallback);
|
|
19328
|
+
return [{ url: local.url }];
|
|
19329
|
+
}
|
|
19330
|
+
}
|
|
19331
|
+
const host = noEntryHosts[0] ?? this.newUserHost ?? (this.tinycloudFallbackHosts === void 0 ? "https://node.tinycloud.xyz" : this.tinycloudFallbackHosts?.[0]);
|
|
19332
|
+
if (!host || this.newUserHost === null && noEntryHosts.length === 0) throw new NodeNotFoundError(subject, resolved.verdict);
|
|
19333
|
+
const url = exactHttpOrigin(host, "new-user host");
|
|
19334
|
+
warnRegistryDefaultNode(resolved.verdict, this.registryCacheStore, this.onRegistryFallback);
|
|
19335
|
+
return [{ url }];
|
|
19336
|
+
}
|
|
19337
|
+
const destinations = resolved.hosts.flatMap((host) => host.urls.map((url) => ({ url, nodeDid: host.nodeDid })));
|
|
19338
|
+
return destinations;
|
|
19339
|
+
} catch (error) {
|
|
19340
|
+
if (!(error instanceof NodeNotFoundError) && !(error instanceof RegistryUnavailableError)) throw error;
|
|
19341
|
+
if (!this.onNodeNotFound) throw error;
|
|
19342
|
+
const decision = await this.onNodeNotFound({ error, attempt });
|
|
19343
|
+
if (decision.action === "retry") continue;
|
|
19344
|
+
if (decision.action === "use-host" && error.verdict?.status === "unregistered") {
|
|
19345
|
+
const url = exactHttpOrigin(decision.host, "new-user host");
|
|
19346
|
+
warnRegistryDefaultNode(error.verdict, this.registryCacheStore, this.onRegistryFallback);
|
|
19347
|
+
return [{ url }];
|
|
19348
|
+
}
|
|
19349
|
+
throw error;
|
|
19350
|
+
}
|
|
19330
19351
|
}
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19352
|
+
}
|
|
19353
|
+
get registryRecordPresent() {
|
|
19354
|
+
return this.registryVerdict?.status === "registered";
|
|
19355
|
+
}
|
|
19356
|
+
/** Refresh membership before hosting; a saved no-entry verdict never authorizes a later creation. */
|
|
19357
|
+
async assertMayCreateSpace(spaceId = this._tinyCloudSession?.spaceId, host = this.primaryTinyCloudHost) {
|
|
19358
|
+
if (!spaceId) throw new Error("Must be signed in to create a space");
|
|
19359
|
+
const destinations = await this.resolveResourceDestinations(spaceId, "host");
|
|
19360
|
+
if (!destinations.some((destination) => destination.url === host)) {
|
|
19361
|
+
const subject = parseSpaceUri(spaceId)?.owner;
|
|
19362
|
+
if (!subject || !this.registryVerdict) throw new Error("Cannot resolve space owner");
|
|
19363
|
+
assertSpaceCreationAllowed(this.registryVerdict, host, spaceId);
|
|
19340
19364
|
}
|
|
19341
|
-
assertSpaceCreationAllowed(verdict, this.primaryTinyCloudHost);
|
|
19342
19365
|
}
|
|
19343
19366
|
requireTinyCloudHosts() {
|
|
19344
19367
|
if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
|
|
@@ -19768,23 +19791,60 @@ var NodeUserAuthorization = class {
|
|
|
19768
19791
|
* Create the space on the TinyCloud server (host delegation).
|
|
19769
19792
|
* This registers the user as the owner of the space.
|
|
19770
19793
|
*/
|
|
19771
|
-
async hostSpace(targetSpaceId, purpose, signal) {
|
|
19772
|
-
|
|
19794
|
+
async hostSpace(targetSpaceId, purpose, signal, assertCurrent, siweParameters) {
|
|
19795
|
+
const context = typeof targetSpaceId === "object" ? targetSpaceId : void 0;
|
|
19796
|
+
const address = context?.address ?? this._address;
|
|
19797
|
+
const chainId = context?.chainId ?? this._chainId;
|
|
19798
|
+
if (!address || chainId === void 0 || !this._tinyCloudSession) {
|
|
19773
19799
|
throw new Error("Must be signed in to host space");
|
|
19774
19800
|
}
|
|
19801
|
+
const checkCurrent = () => {
|
|
19802
|
+
signal?.throwIfAborted();
|
|
19803
|
+
assertCurrent?.();
|
|
19804
|
+
};
|
|
19805
|
+
checkCurrent();
|
|
19775
19806
|
await this.ensureTinyCloudHosts();
|
|
19776
|
-
|
|
19777
|
-
const
|
|
19807
|
+
checkCurrent();
|
|
19808
|
+
const host = context?.host ?? this.primaryTinyCloudHost;
|
|
19809
|
+
const spaceId = context?.spaceId ?? (typeof targetSpaceId === "string" ? targetSpaceId : this._tinyCloudSession.spaceId);
|
|
19810
|
+
const destinations = await this.resolveResourceDestinations(spaceId, "host");
|
|
19811
|
+
if (this.registryVerdict?.status === "registered") {
|
|
19812
|
+
const results = [];
|
|
19813
|
+
for (const destination of destinations) {
|
|
19814
|
+
checkCurrent();
|
|
19815
|
+
try {
|
|
19816
|
+
await verifyResourceDestination(destination, globalThis.fetch.bind(globalThis));
|
|
19817
|
+
const result = await activateSessionWithHost(destination.url, this._tinyCloudSession.delegationHeader, signal);
|
|
19818
|
+
results.push(result.skipped?.includes(spaceId) ? { ...result, success: false, status: 403, error: "The session does not activate the requested space" } : result);
|
|
19819
|
+
} catch (error) {
|
|
19820
|
+
if (routingFailure2(error) || signal?.aborted) throw error;
|
|
19821
|
+
throw new NodeNotRespondingError([destination.url], error);
|
|
19822
|
+
}
|
|
19823
|
+
}
|
|
19824
|
+
const failed = results.flatMap((result, index) => result.success ? [] : [{ url: destinations[index].url, status: result.status }]);
|
|
19825
|
+
if (failed.length) {
|
|
19826
|
+
if (destinations.length === 1) return results[0];
|
|
19827
|
+
throw new PartialNodeWriteError(destinations.filter((_, index) => results[index].success).map(({ url }) => url), failed);
|
|
19828
|
+
}
|
|
19829
|
+
return {
|
|
19830
|
+
...results[0],
|
|
19831
|
+
activated: [...new Set(results.flatMap((result) => result.activated ?? []))],
|
|
19832
|
+
skipped: [...new Set(results.flatMap((result) => result.skipped ?? []))]
|
|
19833
|
+
};
|
|
19834
|
+
}
|
|
19778
19835
|
const peerId = await fetchPeerId(host, spaceId, signal);
|
|
19779
|
-
|
|
19780
|
-
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
|
|
19784
|
-
|
|
19785
|
-
|
|
19786
|
-
|
|
19787
|
-
|
|
19836
|
+
checkCurrent();
|
|
19837
|
+
const siwe = this.wasm.generateHostSIWEMessage(
|
|
19838
|
+
context && siweParameters ? siweParameters(peerId) : {
|
|
19839
|
+
address,
|
|
19840
|
+
chainId,
|
|
19841
|
+
domain: this.domain,
|
|
19842
|
+
issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19843
|
+
spaceId,
|
|
19844
|
+
peerId
|
|
19845
|
+
}
|
|
19846
|
+
);
|
|
19847
|
+
checkCurrent();
|
|
19788
19848
|
const signing = this.signMessage(siwe, purpose);
|
|
19789
19849
|
let signature2;
|
|
19790
19850
|
if (!signal) {
|
|
@@ -19803,8 +19863,9 @@ var NodeUserAuthorization = class {
|
|
|
19803
19863
|
signal.removeEventListener("abort", onAbort);
|
|
19804
19864
|
}
|
|
19805
19865
|
}
|
|
19806
|
-
|
|
19866
|
+
checkCurrent();
|
|
19807
19867
|
const headers = this.wasm.siweToDelegationHeaders({ siwe, signature: signature2 });
|
|
19868
|
+
checkCurrent();
|
|
19808
19869
|
return submitHostDelegation(host, headers, signal);
|
|
19809
19870
|
}
|
|
19810
19871
|
/**
|
|
@@ -19841,13 +19902,45 @@ var NodeUserAuthorization = class {
|
|
|
19841
19902
|
if (!this._tinyCloudSession) {
|
|
19842
19903
|
throw new Error("Must be signed in to ensure space exists");
|
|
19843
19904
|
}
|
|
19844
|
-
await this.ensureTinyCloudHosts();
|
|
19845
|
-
const host = this.primaryTinyCloudHost;
|
|
19846
19905
|
const primarySpaceId = this._tinyCloudSession.spaceId;
|
|
19847
|
-
const
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
)
|
|
19906
|
+
const primary = await this.resolveResourceDestinations(primarySpaceId, "read");
|
|
19907
|
+
this.tinycloudHosts = primary.map(({ url }) => url);
|
|
19908
|
+
const targets = new Map(primary.map((destination) => [destination.url, destination]));
|
|
19909
|
+
if (this.registryVerdict?.status === "registered" && this.registryVerdict.record) {
|
|
19910
|
+
const record = this.registryVerdict.record;
|
|
19911
|
+
const resources = Object.keys(extractRecapAttenuations(this._tinyCloudSession.siwe ?? ""));
|
|
19912
|
+
for (const space of record.spaces) {
|
|
19913
|
+
const registeredSpace = parseSpaceUri(space.space);
|
|
19914
|
+
if (!resources.some((resource) => {
|
|
19915
|
+
const fullSpace = resource.split("/")[0];
|
|
19916
|
+
const requestedSpace = parseSpaceUri(fullSpace);
|
|
19917
|
+
return fullSpace === space.space || registeredSpace !== null && requestedSpace !== null && registeredSpace.owner === requestedSpace.owner && registeredSpace.name === requestedSpace.name;
|
|
19918
|
+
})) continue;
|
|
19919
|
+
for (const membership of space.nodes) {
|
|
19920
|
+
const node = record.nodes.find((candidate) => candidate.did === membership.did);
|
|
19921
|
+
targets.set(node.url, { url: node.url, nodeDid: node.did });
|
|
19922
|
+
}
|
|
19923
|
+
}
|
|
19924
|
+
if (record.encryptionNode && resources.some((resource) => resource.startsWith("urn:tinycloud:encryption:"))) {
|
|
19925
|
+
const node = record.nodes.find((candidate) => candidate.did === record.encryptionNode);
|
|
19926
|
+
targets.set(node.url, { url: node.url, nodeDid: node.did });
|
|
19927
|
+
}
|
|
19928
|
+
}
|
|
19929
|
+
let result;
|
|
19930
|
+
for (const destination of targets.values()) {
|
|
19931
|
+
await verifyResourceDestination(destination, globalThis.fetch.bind(globalThis));
|
|
19932
|
+
let activated;
|
|
19933
|
+
try {
|
|
19934
|
+
activated = await activateSessionWithHost(destination.url, this._tinyCloudSession.delegationHeader);
|
|
19935
|
+
} catch (error) {
|
|
19936
|
+
throw new NodeNotRespondingError([destination.url], error);
|
|
19937
|
+
}
|
|
19938
|
+
if (!activated.success && activated.status !== 404) {
|
|
19939
|
+
throw Object.assign(new Error(`Failed to activate session: ${describeHostFailure(activated)}`), { cause: activated });
|
|
19940
|
+
}
|
|
19941
|
+
if (destination.url === primary[0].url) result = activated;
|
|
19942
|
+
}
|
|
19943
|
+
if (!result) throw new Error("Primary space activation did not return a result");
|
|
19851
19944
|
this.recordActivationSkippedSpaces(result, primarySpaceId);
|
|
19852
19945
|
if (!result.success && result.status !== 404) {
|
|
19853
19946
|
throw Object.assign(
|
|
@@ -19866,43 +19959,36 @@ var NodeUserAuthorization = class {
|
|
|
19866
19959
|
*
|
|
19867
19960
|
* @throws Error if the creation handler fails or times out, or hosting fails
|
|
19868
19961
|
*/
|
|
19869
|
-
async ensurePrimarySpaceHosted(hosting) {
|
|
19870
|
-
if (hosting !== "not-hosted") {
|
|
19871
|
-
return;
|
|
19872
|
-
}
|
|
19962
|
+
async ensurePrimarySpaceHosted(hosting, signal) {
|
|
19873
19963
|
const session = this._tinyCloudSession;
|
|
19874
|
-
if (
|
|
19875
|
-
|
|
19876
|
-
}
|
|
19964
|
+
if (hosting !== "not-hosted") return;
|
|
19965
|
+
if (!session) throw new Error("Must be signed in to host the primary space");
|
|
19877
19966
|
const handler = this.spaceCreationHandler ?? (this.autoCreateSpace ? new AutoApproveSpaceCreationHandler() : void 0);
|
|
19878
|
-
if (!handler)
|
|
19879
|
-
return;
|
|
19880
|
-
}
|
|
19881
|
-
await this.ensureTinyCloudHosts();
|
|
19882
|
-
const host = this.primaryTinyCloudHost;
|
|
19883
|
-
const primarySpaceId = session.spaceId;
|
|
19884
|
-
const creationContext = {
|
|
19885
|
-
spaceId: primarySpaceId,
|
|
19886
|
-
address: this._address,
|
|
19887
|
-
chainId: this._chainId,
|
|
19888
|
-
host
|
|
19889
|
-
};
|
|
19967
|
+
if (!handler) return;
|
|
19890
19968
|
const { createPrimarySpace } = await import("./space-hosting.js");
|
|
19891
19969
|
await createPrimarySpace({
|
|
19892
19970
|
handler,
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19971
|
+
session,
|
|
19972
|
+
currentSession: () => this._tinyCloudSession,
|
|
19973
|
+
signerAddress: () => this.signer.getAddress(),
|
|
19974
|
+
resolveHost: async () => {
|
|
19975
|
+
await this.ensureTinyCloudHosts();
|
|
19976
|
+
return this.primaryTinyCloudHost;
|
|
19977
|
+
},
|
|
19978
|
+
domain: this.domain,
|
|
19979
|
+
guard: (context) => this.guardSpaceCreation(handler, context),
|
|
19980
|
+
host: (context, assertCurrent, siweParameters) => this.hostSpace(context, void 0, signal, assertCurrent, siweParameters),
|
|
19896
19981
|
onHosted: () => {
|
|
19897
19982
|
this._spaceHosting = "hosted";
|
|
19898
19983
|
},
|
|
19899
|
-
activate: () => activateSessionWithHost(host, session.delegationHeader)
|
|
19984
|
+
activate: (context) => activateSessionWithHost(context.host, session.delegationHeader),
|
|
19985
|
+
signal
|
|
19900
19986
|
});
|
|
19901
19987
|
}
|
|
19902
19988
|
/** {@link assertMayCreateSpace}, reporting a refusal to the creation handler before rethrowing it. */
|
|
19903
19989
|
async guardSpaceCreation(handler, context) {
|
|
19904
19990
|
try {
|
|
19905
|
-
await this.assertMayCreateSpace();
|
|
19991
|
+
await this.assertMayCreateSpace(context.spaceId, context.host);
|
|
19906
19992
|
} catch (error) {
|
|
19907
19993
|
const failure = error instanceof Error ? error : new Error(String(error));
|
|
19908
19994
|
handler.onSpaceCreationFailed?.(context, failure);
|
|
@@ -21824,6 +21910,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21824
21910
|
* ```
|
|
21825
21911
|
*/
|
|
21826
21912
|
constructor(config = {}) {
|
|
21913
|
+
this.registryRefreshOwners = /* @__PURE__ */ new Set();
|
|
21827
21914
|
this.signer = null;
|
|
21828
21915
|
this.auth = null;
|
|
21829
21916
|
this.consumedOpenKeyPendings = /* @__PURE__ */ new WeakSet();
|
|
@@ -21987,8 +22074,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21987
22074
|
this.config = {
|
|
21988
22075
|
...config,
|
|
21989
22076
|
host: config.host ?? DEFAULT_HOST,
|
|
22077
|
+
registryPolicy: "fail-closed",
|
|
21990
22078
|
// One store for every authorization this client creates.
|
|
21991
|
-
registrySequenceStore: config.registrySequenceStore ?? createInMemoryRegistrySequenceStore2()
|
|
22079
|
+
registrySequenceStore: config.registrySequenceStore ?? createInMemoryRegistrySequenceStore2(),
|
|
22080
|
+
registryCacheStore: config.registryCacheStore ?? createInMemoryRegistryCacheStore2()
|
|
21992
22081
|
};
|
|
21993
22082
|
if (this.config.replication?.enabled) {
|
|
21994
22083
|
const runtime = getNodeReplicationLoaders().runtime().then(({ ReplicationRuntime: ReplicationRuntime2 }) => {
|
|
@@ -22235,6 +22324,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22235
22324
|
return "unknown";
|
|
22236
22325
|
}
|
|
22237
22326
|
}
|
|
22327
|
+
/** Run the existing primary-space creation flow for the restored session. */
|
|
22328
|
+
async ensurePrimarySpaceHosted(hosting) {
|
|
22329
|
+
const graph = this._serviceGraph;
|
|
22330
|
+
const epoch = this.sessionEpoch;
|
|
22331
|
+
graph.assertActive();
|
|
22332
|
+
this.assertSessionEpoch(epoch, "Space hosting");
|
|
22333
|
+
const auth = this.auth;
|
|
22334
|
+
if (!auth || !this.session) return;
|
|
22335
|
+
await auth.ensurePrimarySpaceHosted(hosting, graph.signal);
|
|
22336
|
+
graph.assertActive();
|
|
22337
|
+
this.assertSessionEpoch(epoch, "Space hosting");
|
|
22338
|
+
}
|
|
22238
22339
|
/**
|
|
22239
22340
|
* The node's last answer for the primary space: recorded at sign-in from the
|
|
22240
22341
|
* activation, or by {@link checkSpaceHosting}. `unknown` after a restore until
|
|
@@ -22280,7 +22381,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22280
22381
|
// A session saved but never registered on this node is refused: it registers once.
|
|
22281
22382
|
activate: (signal) => {
|
|
22282
22383
|
assertCurrent();
|
|
22283
|
-
|
|
22384
|
+
const activationSignal = AbortSignal.any([signal, graph.signal]);
|
|
22385
|
+
if (primary && primary.delegationCid === session.delegationCid) {
|
|
22386
|
+
return this.activateSignedSession(primary, primary.siwe, host, activationSignal);
|
|
22387
|
+
}
|
|
22388
|
+
return this.activateResourceSession(session.delegationHeader, [spaceId], host, activationSignal);
|
|
22284
22389
|
}
|
|
22285
22390
|
});
|
|
22286
22391
|
assertCurrent();
|
|
@@ -22416,14 +22521,38 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22416
22521
|
get requests() {
|
|
22417
22522
|
return this._requestLog === void 0 ? void 0 : readOnlyRequestLog(this._requestLog);
|
|
22418
22523
|
}
|
|
22419
|
-
|
|
22524
|
+
throwRegistryRefusal(status, text) {
|
|
22525
|
+
if (status !== 403 && status !== 503 || !text.startsWith("registry_unavailable:") && !text.startsWith("registry_hosting_denied:")) return;
|
|
22526
|
+
const code = status === 503 ? "registry_unavailable" : "node_registry_entry_exists";
|
|
22527
|
+
throw Object.assign(new Error(status === 503 ? "The location registry is unavailable for this resource." : "The registry does not authorize this node for the requested resource."), { code, meta: { status } });
|
|
22528
|
+
}
|
|
22529
|
+
createServiceGraphLifetime(session) {
|
|
22530
|
+
const routedFetch = createResourceRoutingFetch(
|
|
22531
|
+
async (url, init2) => {
|
|
22532
|
+
try {
|
|
22533
|
+
const response = await globalThis.fetch(url, init2);
|
|
22534
|
+
if (response.status === 403 || response.status === 503) {
|
|
22535
|
+
this.throwRegistryRefusal(response.status, await response.clone().text());
|
|
22536
|
+
}
|
|
22537
|
+
return response;
|
|
22538
|
+
} catch (error) {
|
|
22539
|
+
if (routingFailure3(error)) throw error;
|
|
22540
|
+
if (new URL(url).pathname.startsWith("/encryption/") && !init2?.signal?.aborted) {
|
|
22541
|
+
throw new NodeNotRespondingError2([new URL(url).origin], error);
|
|
22542
|
+
}
|
|
22543
|
+
throw error;
|
|
22544
|
+
}
|
|
22545
|
+
},
|
|
22546
|
+
{
|
|
22547
|
+
resolveResource: (resource, access) => this.routingDestinations(resource, access),
|
|
22548
|
+
bindAudience: (authorization, nodeDid) => this.bindRoutedAudience(authorization, nodeDid, session),
|
|
22549
|
+
verifyDestination: (target) => verifyResourceDestination2(target, globalThis.fetch.bind(globalThis))
|
|
22550
|
+
}
|
|
22551
|
+
);
|
|
22420
22552
|
return new ServiceGraphLifetime(
|
|
22421
22553
|
this.invokeWithRuntimePermissions,
|
|
22422
22554
|
this.invokeAnyWithRuntimePermissions,
|
|
22423
|
-
|
|
22424
|
-
// signal while preserving the SDK's existing injectable global fetch
|
|
22425
|
-
// behavior (including adapters that install it after construction).
|
|
22426
|
-
(url, init2) => globalThis.fetch(url, init2),
|
|
22555
|
+
routedFetch,
|
|
22427
22556
|
(context) => {
|
|
22428
22557
|
this.storageFull.observe(context);
|
|
22429
22558
|
if (this._requestLog) observeReplicaReads(context, this._requestLog);
|
|
@@ -22431,6 +22560,75 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22431
22560
|
this._requestLog
|
|
22432
22561
|
);
|
|
22433
22562
|
}
|
|
22563
|
+
async routingDestinations(resource, access, noEntryHosts) {
|
|
22564
|
+
const session = this.currentTinyCloudSession();
|
|
22565
|
+
if (session) this.refreshRegistryOwner(pkhDid2(session.address, session.chainId));
|
|
22566
|
+
if (this.auth) return this.auth.resolveResourceDestinations(resource, access, noEntryHosts);
|
|
22567
|
+
const owner = resource.startsWith("urn:tinycloud:encryption:") ? parseNetworkId2(resource.split("/")[0]).ownerDid : parseSpaceUri2(resource)?.owner ?? (() => {
|
|
22568
|
+
const key2 = /^tinycloud:key:(z[^:]+):[^/]+$/.exec(resource);
|
|
22569
|
+
return key2 ? `did:key:${key2[1]}` : void 0;
|
|
22570
|
+
})();
|
|
22571
|
+
if (!owner) throw new Error(`Cannot determine registry owner for ${resource}`);
|
|
22572
|
+
const subject = owner.startsWith("did:pkh:") ? pkhDid2(owner.slice(owner.lastIndexOf(":") + 1), this.config.registryChainId ?? 1) : owner;
|
|
22573
|
+
const resolved = await resolveRegistryResource2(subject, resource, access, {
|
|
22574
|
+
registryUrl: this.config.tinycloudRegistryUrl,
|
|
22575
|
+
registryChainId: this.config.registryChainId,
|
|
22576
|
+
sequenceStore: this.config.registrySequenceStore,
|
|
22577
|
+
cacheStore: this.config.registryCacheStore,
|
|
22578
|
+
onRegistryFallback: this.config.onRegistryFallback
|
|
22579
|
+
});
|
|
22580
|
+
if (resolved.verdict.status === "unregistered") {
|
|
22581
|
+
const hint = noEntryHosts === void 0 ? this.explicitHost ?? this.config.host : noEntryHosts[0];
|
|
22582
|
+
const host = hint ?? this.config.newUserHost ?? (this.config.tinycloudFallbackHosts === void 0 ? DEFAULT_HOST : this.config.tinycloudFallbackHosts?.[0]);
|
|
22583
|
+
if (!host || !hint && this.config.newUserHost === null) throw new NodeNotFoundError2(subject, resolved.verdict);
|
|
22584
|
+
const url = exactHttpOrigin2(host, "new-user host");
|
|
22585
|
+
warnRegistryDefaultNode2(resolved.verdict, this.config.registryCacheStore, this.config.onRegistryFallback);
|
|
22586
|
+
return [{ url }];
|
|
22587
|
+
}
|
|
22588
|
+
const destinations = resolved.hosts.flatMap((host) => host.urls.map((url) => ({ url, nodeDid: host.nodeDid })));
|
|
22589
|
+
return destinations;
|
|
22590
|
+
}
|
|
22591
|
+
/** Transport hints cannot override verified full-resource registry routing. */
|
|
22592
|
+
async resolveRegisteredDelegationHost(permissions, noEntryHost) {
|
|
22593
|
+
const resources = /* @__PURE__ */ new Map();
|
|
22594
|
+
let hasData = false;
|
|
22595
|
+
for (const permission of permissions) {
|
|
22596
|
+
const encryption = this.isEncryptionNetworkOperation(this.invocationServiceName(permission.service), permission.path, permission.space);
|
|
22597
|
+
const resource = encryption ? permission.path.split("/")[0] : permission.space;
|
|
22598
|
+
if (!resource) throw new ResourceNotRoutedError("delegation");
|
|
22599
|
+
resources.set(resource, encryption ? "encryption" : "host");
|
|
22600
|
+
hasData || (hasData = !encryption);
|
|
22601
|
+
}
|
|
22602
|
+
let dataHost;
|
|
22603
|
+
let encryptionHost;
|
|
22604
|
+
let unserved;
|
|
22605
|
+
for (const [resource, access] of resources) {
|
|
22606
|
+
try {
|
|
22607
|
+
const destinations = await this.routingDestinations(resource, access, [noEntryHost]);
|
|
22608
|
+
if (destinations.some(({ nodeDid }) => nodeDid === void 0)) return void 0;
|
|
22609
|
+
if (access === "host") dataHost ?? (dataHost = destinations[0]?.url);
|
|
22610
|
+
else encryptionHost ?? (encryptionHost = destinations[0]?.url);
|
|
22611
|
+
} catch (error) {
|
|
22612
|
+
if (!(error instanceof NodeNotFoundError2) || error.verdict.status !== "registered") throw error;
|
|
22613
|
+
unserved ?? (unserved = error);
|
|
22614
|
+
}
|
|
22615
|
+
}
|
|
22616
|
+
const host = hasData ? dataHost : encryptionHost;
|
|
22617
|
+
if (!host) throw unserved ?? new ResourceNotRoutedError("delegation");
|
|
22618
|
+
return host;
|
|
22619
|
+
}
|
|
22620
|
+
async bindRoutedAudience(authorization, nodeDid, stagedSession) {
|
|
22621
|
+
const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(authorization.split(".")[1])));
|
|
22622
|
+
const issuer = typeof payload === "object" && payload !== null && "iss" in payload ? payload.iss : void 0;
|
|
22623
|
+
const session = [
|
|
22624
|
+
stagedSession,
|
|
22625
|
+
this._serviceContext?.session,
|
|
22626
|
+
this.auth?.tinyCloudSession,
|
|
22627
|
+
...this.runtimePermissionGrants.map((grant) => grant.session)
|
|
22628
|
+
].find((candidate) => candidate?.verificationMethod === issuer);
|
|
22629
|
+
if (!session) throw new Error("Invocation signing session is not active");
|
|
22630
|
+
return rewriteInvocationAudience(authorization, nodeDid, session.jwk);
|
|
22631
|
+
}
|
|
22434
22632
|
syncResolvedHostFromAuth() {
|
|
22435
22633
|
const host = this.auth?.hosts[0];
|
|
22436
22634
|
if (host) {
|
|
@@ -22544,6 +22742,29 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22544
22742
|
const session = this.currentTinyCloudSession();
|
|
22545
22743
|
return session?.siwe ? this.projectSignedRecapCapabilities(session.siwe) : [];
|
|
22546
22744
|
}
|
|
22745
|
+
/** Start one background refresh for each owner derived from verified authority. */
|
|
22746
|
+
refreshRegistryForCapabilities(permissions) {
|
|
22747
|
+
for (const permission of permissions) {
|
|
22748
|
+
try {
|
|
22749
|
+
const owner = permission.service === "tinycloud.encryption" && permission.path.startsWith("urn:tinycloud:encryption:") ? parseNetworkId2(permission.path.split("/")[0]).ownerDid : permission.space ? this.ownerDidFromSpaceId(permission.space) : void 0;
|
|
22750
|
+
if (owner) this.refreshRegistryOwner(owner);
|
|
22751
|
+
} catch {
|
|
22752
|
+
}
|
|
22753
|
+
}
|
|
22754
|
+
}
|
|
22755
|
+
refreshRegistryOwner(owner) {
|
|
22756
|
+
if (this.config.tinycloudRegistryUrl === null) return;
|
|
22757
|
+
const subject = owner.startsWith("did:pkh:") ? pkhDid2(owner.slice(owner.lastIndexOf(":") + 1), this.config.registryChainId ?? 1) : owner;
|
|
22758
|
+
const key2 = registryOwnerKeyV2(subject);
|
|
22759
|
+
if (this.registryRefreshOwners.has(key2)) return;
|
|
22760
|
+
this.registryRefreshOwners.add(key2);
|
|
22761
|
+
void refreshOwnerRegistry(subject, {
|
|
22762
|
+
registryUrl: this.config.tinycloudRegistryUrl,
|
|
22763
|
+
registryChainId: this.config.registryChainId,
|
|
22764
|
+
sequenceStore: this.config.registrySequenceStore,
|
|
22765
|
+
cacheStore: this.config.registryCacheStore
|
|
22766
|
+
}).catch(() => void 0);
|
|
22767
|
+
}
|
|
22547
22768
|
/** Normalize signed capabilities without collapsing nested encryption into raw authority. */
|
|
22548
22769
|
projectSignedRecapCapabilities(siwe) {
|
|
22549
22770
|
const projected = this.parseRecapWithCaveats(siwe).map((entry) => {
|
|
@@ -22975,6 +23196,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22975
23196
|
const primarySession = this.currentTinyCloudSession();
|
|
22976
23197
|
if (primarySession) {
|
|
22977
23198
|
this.registerPrimarySessionGrant(primarySession);
|
|
23199
|
+
this.refreshRegistryOwner(pkhDid2(primarySession.address, primarySession.chainId));
|
|
23200
|
+
this.refreshRegistryForCapabilities(this.getVerifiedSessionCapabilities());
|
|
22978
23201
|
if (this.auth?.spaceHosting === "unknown") {
|
|
22979
23202
|
await this.checkSpaceHosting();
|
|
22980
23203
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
@@ -23197,8 +23420,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23197
23420
|
const primarySession = auth.tinyCloudSession;
|
|
23198
23421
|
const defaultSpaceId = this.ownedSpaceId("default");
|
|
23199
23422
|
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest === BOOTSTRAP_SESSION_REQUESTS.default;
|
|
23200
|
-
|
|
23201
|
-
await this.assertMayCreateSpace();
|
|
23423
|
+
for (const step of steps) {
|
|
23424
|
+
if (step.kind === "host") await this.assertMayCreateSpace(step.spaceId);
|
|
23202
23425
|
}
|
|
23203
23426
|
for (const step of steps) {
|
|
23204
23427
|
if (step.kind !== "session") continue;
|
|
@@ -23247,10 +23470,20 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23247
23470
|
if (!session) {
|
|
23248
23471
|
throw new Error(`Missing bootstrap session for ${step.space}`);
|
|
23249
23472
|
}
|
|
23250
|
-
const
|
|
23251
|
-
|
|
23252
|
-
|
|
23253
|
-
|
|
23473
|
+
const destinations = await this.routingDestinations(step.spaceId, "host");
|
|
23474
|
+
let activated;
|
|
23475
|
+
for (const destination of destinations) {
|
|
23476
|
+
try {
|
|
23477
|
+
await verifyResourceDestination2(destination, globalThis.fetch.bind(globalThis));
|
|
23478
|
+
const result = await activateSessionWithHost2(destination.url, session.delegationHeader, graph.signal);
|
|
23479
|
+
if (!result.success) throw Object.assign(new Error("Bootstrap activation failed"), { cause: result });
|
|
23480
|
+
activated = result;
|
|
23481
|
+
} catch (error) {
|
|
23482
|
+
graph.assertActive();
|
|
23483
|
+
throw error;
|
|
23484
|
+
}
|
|
23485
|
+
}
|
|
23486
|
+
if (!activated) throw new Error("Bootstrap space has no destination");
|
|
23254
23487
|
graph.assertActive();
|
|
23255
23488
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
23256
23489
|
throw Object.assign(
|
|
@@ -23833,6 +24066,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23833
24066
|
if (!session) {
|
|
23834
24067
|
throw new Error("Owned space hosting requires an active session");
|
|
23835
24068
|
}
|
|
24069
|
+
await this.assertMayCreateSpace(spaceId);
|
|
24070
|
+
if (this.auth.registryRecordPresent) {
|
|
24071
|
+
const hosted = await this.hostOwnedSpaceOnce(spaceId, signal);
|
|
24072
|
+
if (!hosted.success) throw Object.assign(new Error(`Failed to activate listed space ${spaceId}: ${describeHostFailure2(hosted)}`), { cause: hosted });
|
|
24073
|
+
if (this.auth.tinyCloudSession === session) this.confirmedHostedSpaceIds.add(spaceId);
|
|
24074
|
+
return;
|
|
24075
|
+
}
|
|
23836
24076
|
if (this.confirmedHostedSpaceIds.has(spaceId) || this.hostedOwnedSpaceIds.has(spaceId)) {
|
|
23837
24077
|
return;
|
|
23838
24078
|
}
|
|
@@ -23851,7 +24091,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23851
24091
|
{ cause: activation }
|
|
23852
24092
|
);
|
|
23853
24093
|
}
|
|
23854
|
-
await this.assertMayCreateSpace();
|
|
24094
|
+
await this.assertMayCreateSpace(spaceId);
|
|
23855
24095
|
if (signal?.aborted) throw signal.reason;
|
|
23856
24096
|
const created = await this.hostOwnedSpaceOnce(spaceId, signal);
|
|
23857
24097
|
if (!created.success) {
|
|
@@ -23912,17 +24152,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23912
24152
|
{ cause: hosted }
|
|
23913
24153
|
);
|
|
23914
24154
|
}
|
|
23915
|
-
|
|
23916
|
-
|
|
23917
|
-
|
|
23918
|
-
|
|
23919
|
-
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
23920
|
-
throw Object.assign(
|
|
23921
|
-
new Error(
|
|
23922
|
-
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
23923
|
-
),
|
|
23924
|
-
{ cause: activation }
|
|
24155
|
+
if (!this.auth.registryRecordPresent) {
|
|
24156
|
+
const activation = await activateSessionWithHost2(
|
|
24157
|
+
host,
|
|
24158
|
+
session.delegationHeader
|
|
23925
24159
|
);
|
|
24160
|
+
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
24161
|
+
throw Object.assign(
|
|
24162
|
+
new Error(
|
|
24163
|
+
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
24164
|
+
),
|
|
24165
|
+
{ cause: activation }
|
|
24166
|
+
);
|
|
24167
|
+
}
|
|
23926
24168
|
}
|
|
23927
24169
|
if (this.auth?.tinyCloudSession === session) this.hostedOwnedSpaceIds.add(spaceId);
|
|
23928
24170
|
try {
|
|
@@ -23966,11 +24208,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23966
24208
|
* session's recap doesn't cover it and the registry has no record; the host
|
|
23967
24209
|
* SIWE is idempotent server-side. Must be called after {@link signIn}.
|
|
23968
24210
|
*
|
|
23969
|
-
*
|
|
23970
|
-
*
|
|
23971
|
-
*
|
|
23972
|
-
* verdict. {@link hostOwnedSpace} itself is an explicit action and is not
|
|
23973
|
-
* guarded.
|
|
24211
|
+
* Current signed per-space membership is checked before both automatic and
|
|
24212
|
+
* explicit hosting. Registered replicas use the session grant; no-entry
|
|
24213
|
+
* onboarding retains the host-SIWE flow.
|
|
23974
24214
|
*
|
|
23975
24215
|
* @param name - The owned space name (e.g. `"secrets"`).
|
|
23976
24216
|
* @returns The hosted owned-space URI.
|
|
@@ -23980,27 +24220,20 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23980
24220
|
throw new Error("Not signed in. Call signIn() first.");
|
|
23981
24221
|
}
|
|
23982
24222
|
const spaceId = this.ownedSpaceId(name);
|
|
24223
|
+
await this.assertMayCreateSpace(spaceId);
|
|
23983
24224
|
if (this.hostedOwnedSpaceIds.has(spaceId) || await this.isOwnedSpaceRegistered(spaceId)) {
|
|
23984
24225
|
return spaceId;
|
|
23985
24226
|
}
|
|
23986
|
-
await this.assertMayCreateSpace();
|
|
23987
24227
|
return this.hostOwnedSpace(name);
|
|
23988
24228
|
}
|
|
23989
|
-
/**
|
|
23990
|
-
|
|
23991
|
-
|
|
23992
|
-
* {@link ensurePublicSpace}. Only `registryPolicy: "fail-closed"` consults
|
|
23993
|
-
* the registry ({@link NodeUserAuthorization.assertMayCreateSpace}); the
|
|
23994
|
-
* default policy performs no lookup.
|
|
23995
|
-
*/
|
|
23996
|
-
async assertMayCreateSpace() {
|
|
23997
|
-
if (this.config.registryPolicy !== "fail-closed") return;
|
|
23998
|
-
await this.auth.assertMayCreateSpace();
|
|
24229
|
+
/** Refresh full-space membership before any automatic or explicit hosting. */
|
|
24230
|
+
async assertMayCreateSpace(spaceId) {
|
|
24231
|
+
await this.routingDestinations(spaceId, "host");
|
|
23999
24232
|
}
|
|
24000
24233
|
/** Registry-policy settings shared by every authorization this client creates. */
|
|
24001
24234
|
registryPolicyConfig() {
|
|
24002
|
-
const { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound } = this.config;
|
|
24003
|
-
return { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound };
|
|
24235
|
+
const { registryPolicy, newUserHost, registryChainId, registrySequenceStore, registryCacheStore, onNodeNotFound, onRegistryFallback } = this.config;
|
|
24236
|
+
return { registryPolicy, newUserHost, registryChainId, registrySequenceStore, registryCacheStore, onNodeNotFound, onRegistryFallback };
|
|
24004
24237
|
}
|
|
24005
24238
|
/**
|
|
24006
24239
|
* Submit the host delegation for an owned space, sharing one in-flight
|
|
@@ -24206,12 +24439,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24206
24439
|
}
|
|
24207
24440
|
stagedSessionExpiry = signedExpiry ?? persistedPolicyExpiry ?? persistedExpiry(void 0);
|
|
24208
24441
|
}
|
|
24209
|
-
const
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
sessionData.chainId
|
|
24213
|
-
);
|
|
24214
|
-
const stagedHost = resolvedHost ?? this.config.host;
|
|
24442
|
+
const restoreHints = this.explicitHost ? [this.explicitHost] : sessionData.tinycloudHosts ?? [];
|
|
24443
|
+
const resolvedHost = this.config.replication?.enabled ? (await this.routingDestinations(sessionData.spaceId, "read", restoreHints))[0]?.url : void 0;
|
|
24444
|
+
const stagedHost = resolvedHost ?? exactHttpOrigin2(restoreHints[0] ?? this.config.host, "restored host hint");
|
|
24215
24445
|
let restoredNodeFeatures;
|
|
24216
24446
|
let replicaProtocolMismatch = false;
|
|
24217
24447
|
if (this.config.replication?.enabled) {
|
|
@@ -24328,7 +24558,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24328
24558
|
this.sessionManager = stagedManager;
|
|
24329
24559
|
this.sessionKeyId = stagedKeyId;
|
|
24330
24560
|
this.sessionKeyJwk = stagedJwk;
|
|
24331
|
-
|
|
24561
|
+
this.config.host = stagedHost;
|
|
24332
24562
|
if (spaceOwnerKey(serviceSession.spaceId) !== this.currentStorageOwner()) {
|
|
24333
24563
|
this.storageFull.clear();
|
|
24334
24564
|
this._requestLog?.clear();
|
|
@@ -24395,6 +24625,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24395
24625
|
if (attempt === this.latestSessionAttempt) await this.endSession();
|
|
24396
24626
|
this.assertSessionEpoch(epoch, "Session restore");
|
|
24397
24627
|
}
|
|
24628
|
+
if (this.config.replication?.enabled) {
|
|
24629
|
+
if (stagedAddress !== void 0) this.refreshRegistryOwner(pkhDid2(stagedAddress, stagedChainId));
|
|
24630
|
+
this.refreshRegistryForCapabilities(this.getVerifiedSessionCapabilities());
|
|
24631
|
+
}
|
|
24398
24632
|
}
|
|
24399
24633
|
stagePrimarySessionState(session, verificationMethod, host, sessionExpiry, recap) {
|
|
24400
24634
|
if (!session?.siwe) return { cache: void 0, grants: [] };
|
|
@@ -24443,7 +24677,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24443
24677
|
};
|
|
24444
24678
|
}
|
|
24445
24679
|
stageRestoredServiceGraph(input) {
|
|
24446
|
-
const graph = this.createServiceGraphLifetime();
|
|
24680
|
+
const graph = this.createServiceGraphLifetime(input.serviceSession);
|
|
24447
24681
|
const core = this.auth ? new TinyCloud(this.auth, {
|
|
24448
24682
|
invokeAny: graph.invokeAny,
|
|
24449
24683
|
telemetry: this.config.telemetry,
|
|
@@ -24668,56 +24902,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24668
24902
|
spaceService.updateConfig({ sharingService });
|
|
24669
24903
|
return { core, graph, serviceContext, kv, sql, duckdb, hooks, vault, encryption, capabilityRegistry, keyProvider, sharingService, delegationManager, spaceService };
|
|
24670
24904
|
}
|
|
24671
|
-
/**
|
|
24672
|
-
* Resolve the host a restored session should target.
|
|
24673
|
-
*
|
|
24674
|
-
* Mirrors fresh sign-in host resolution but for the restore path:
|
|
24675
|
-
* an explicit/pinned host always wins, then the hosts the session was
|
|
24676
|
-
* persisted with, then a lazy registry/fallback resolution for sessions
|
|
24677
|
-
* that predate the persisted `tinycloudHosts` field. Returns `undefined`
|
|
24678
|
-
* only when there's nothing to resolve from (no explicit host, no
|
|
24679
|
-
* persisted hosts, and no address/chainId) — in which case the existing
|
|
24680
|
-
* `config.host` (default) is left in place.
|
|
24681
|
-
*
|
|
24682
|
-
* Resolution failures are surfaced, not swallowed: a genuinely broken
|
|
24683
|
-
* registry lookup throws rather than silently falling back to a wrong host.
|
|
24684
|
-
*/
|
|
24685
|
-
async resolveRestoredHost(persistedHosts, address, chainId) {
|
|
24686
|
-
if (this.explicitHost) {
|
|
24687
|
-
return this.explicitHost;
|
|
24688
|
-
}
|
|
24689
|
-
if (persistedHosts && persistedHosts.length > 0) {
|
|
24690
|
-
return persistedHosts[0];
|
|
24691
|
-
}
|
|
24692
|
-
if (address === void 0 || chainId === void 0) {
|
|
24693
|
-
return void 0;
|
|
24694
|
-
}
|
|
24695
|
-
if (this.config.registryPolicy === "fail-closed") {
|
|
24696
|
-
const resolved2 = await resolveFailClosedTinyCloudHosts2(address, {
|
|
24697
|
-
registryUrl: this.config.tinycloudRegistryUrl,
|
|
24698
|
-
registryChainId: this.config.registryChainId,
|
|
24699
|
-
newUserHost: this.config.newUserHost,
|
|
24700
|
-
sequenceStore: this.config.registrySequenceStore,
|
|
24701
|
-
onNodeNotFound: this.config.onNodeNotFound,
|
|
24702
|
-
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
24703
|
-
localNodeUrl: this.config.localNodeUrl,
|
|
24704
|
-
localLinkName: this.config.localLinkName,
|
|
24705
|
-
expectedNodeDid: this.config.expectedNodeDid,
|
|
24706
|
-
localNodeIdentityStore: this.config.localNodeIdentityStore
|
|
24707
|
-
});
|
|
24708
|
-
return resolved2.hosts[0];
|
|
24709
|
-
}
|
|
24710
|
-
const resolved = await resolveTinyCloudHosts2(pkhDid2(address, chainId), {
|
|
24711
|
-
registryUrl: this.config.tinycloudRegistryUrl,
|
|
24712
|
-
fallbackHosts: this.config.tinycloudFallbackHosts,
|
|
24713
|
-
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
24714
|
-
localNodeUrl: this.config.localNodeUrl,
|
|
24715
|
-
localLinkName: this.config.localLinkName,
|
|
24716
|
-
expectedNodeDid: this.config.expectedNodeDid,
|
|
24717
|
-
localNodeIdentityStore: this.config.localNodeIdentityStore
|
|
24718
|
-
});
|
|
24719
|
-
return resolved.hosts[0];
|
|
24720
|
-
}
|
|
24721
24905
|
/**
|
|
24722
24906
|
* Resolve the currently-active TinyCloudSession, preferring the auth
|
|
24723
24907
|
* layer's value (wallet mode) and falling back to the node-level
|
|
@@ -25192,10 +25376,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25192
25376
|
* second time. Only a value recorded for this exact host qualifies; older
|
|
25193
25377
|
* nodes that omit `nodeId` fall through to the fetch.
|
|
25194
25378
|
*/
|
|
25195
|
-
async fetchNodeId() {
|
|
25196
|
-
const cached = this.auth?.nodeIdForHost(
|
|
25379
|
+
async fetchNodeId(host = this.config.host) {
|
|
25380
|
+
const cached = this.auth?.nodeIdForHost(host);
|
|
25197
25381
|
if (cached) return cached;
|
|
25198
|
-
const response = await fetch(`${
|
|
25382
|
+
const response = await fetch(`${host}/info`);
|
|
25199
25383
|
if (!response.ok) {
|
|
25200
25384
|
throw await httpResponseError(response, "Failed to fetch node info");
|
|
25201
25385
|
}
|
|
@@ -25243,10 +25427,24 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25243
25427
|
)
|
|
25244
25428
|
};
|
|
25245
25429
|
}
|
|
25246
|
-
async
|
|
25247
|
-
const
|
|
25248
|
-
|
|
25249
|
-
);
|
|
25430
|
+
async encryptionDestination(networkId) {
|
|
25431
|
+
const destination = (await this.routingDestinations(networkId, "encryption"))[0];
|
|
25432
|
+
if (!destination) throw new Error("No encryption destination is registered");
|
|
25433
|
+
await verifyResourceDestination2(destination, globalThis.fetch.bind(globalThis));
|
|
25434
|
+
return { ...destination, nodeDid: destination.nodeDid ?? await this.fetchNodeId(destination.url) };
|
|
25435
|
+
}
|
|
25436
|
+
async fetchEncryptionNetworkAt(host, networkId, fetchFn, callerSignal) {
|
|
25437
|
+
let response;
|
|
25438
|
+
const timeout = AbortSignal.timeout(5e3);
|
|
25439
|
+
try {
|
|
25440
|
+
response = await fetchFn(`${host}/encryption/networks/${encodeURIComponent(networkId)}`, {
|
|
25441
|
+
signal: callerSignal ? AbortSignal.any([callerSignal, timeout]) : timeout,
|
|
25442
|
+
redirect: "error"
|
|
25443
|
+
});
|
|
25444
|
+
} catch (error) {
|
|
25445
|
+
if (routingFailure3(error) || callerSignal?.aborted || !timeout.aborted && error instanceof Error && error.name === "AbortError") throw error;
|
|
25446
|
+
throw new NodeNotRespondingError2([host], error);
|
|
25447
|
+
}
|
|
25250
25448
|
if (response.status === 404) return null;
|
|
25251
25449
|
if (!response.ok) {
|
|
25252
25450
|
throw await httpResponseError(response, `Failed to fetch encryption network ${networkId}`);
|
|
@@ -25256,18 +25454,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25256
25454
|
}
|
|
25257
25455
|
createEncryptionService(binding) {
|
|
25258
25456
|
const graph = binding?.graph ?? this._serviceGraph;
|
|
25259
|
-
const host = binding?.host ?? this.config.host;
|
|
25260
25457
|
const session = binding?.session ?? this.requireEncryptionSession();
|
|
25261
25458
|
const did = binding?.did ?? this.did;
|
|
25262
25459
|
const address = binding?.address ?? this._address;
|
|
25263
25460
|
const chainId = binding?.chainId ?? this._chainId;
|
|
25264
25461
|
const crypto3 = this.createEncryptionCrypto();
|
|
25265
|
-
const descriptorCache = /* @__PURE__ */ new Map();
|
|
25266
25462
|
const transport = {
|
|
25267
|
-
postDecrypt: async ({ networkId, authorization, canonicalBody, signal }) => {
|
|
25463
|
+
postDecrypt: async ({ targetNode, networkId, authorization, canonicalBody, signal }) => {
|
|
25268
25464
|
graph.assertActive();
|
|
25465
|
+
const destination = await this.encryptionDestination(networkId);
|
|
25466
|
+
if (destination.nodeDid !== targetNode) throw new NodeIdentityMismatchError(destination.url, destination.nodeDid, targetNode);
|
|
25269
25467
|
const response = await graph.fetch(
|
|
25270
|
-
`${
|
|
25468
|
+
`${destination.url}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
|
|
25271
25469
|
{
|
|
25272
25470
|
method: "POST",
|
|
25273
25471
|
headers: {
|
|
@@ -25295,6 +25493,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25295
25493
|
}
|
|
25296
25494
|
};
|
|
25297
25495
|
return new EncryptionService({
|
|
25496
|
+
resolveTargetNode: async (networkId) => (await this.encryptionDestination(networkId)).nodeDid,
|
|
25298
25497
|
crypto: crypto3,
|
|
25299
25498
|
signer: {
|
|
25300
25499
|
signDecryptInvocation: async (input) => {
|
|
@@ -25318,18 +25517,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25318
25517
|
node: {
|
|
25319
25518
|
fetchByNetworkId: async (networkId) => {
|
|
25320
25519
|
graph.assertActive();
|
|
25321
|
-
|
|
25322
|
-
|
|
25323
|
-
pending = this.fetchEncryptionNetworkAt(host, networkId, graph.fetch).then((descriptor2) => {
|
|
25324
|
-
if (descriptor2 === null) descriptorCache.delete(networkId);
|
|
25325
|
-
return descriptor2;
|
|
25326
|
-
}).catch((error) => {
|
|
25327
|
-
descriptorCache.delete(networkId);
|
|
25328
|
-
throw error;
|
|
25329
|
-
});
|
|
25330
|
-
descriptorCache.set(networkId, pending);
|
|
25331
|
-
}
|
|
25332
|
-
const descriptor = await pending;
|
|
25520
|
+
const destination = await this.encryptionDestination(networkId);
|
|
25521
|
+
const descriptor = await this.fetchEncryptionNetworkAt(destination.url, networkId, graph.fetch, graph.signal);
|
|
25333
25522
|
graph.assertActive();
|
|
25334
25523
|
return descriptor;
|
|
25335
25524
|
}
|
|
@@ -25337,13 +25526,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25337
25526
|
wellKnown: {
|
|
25338
25527
|
fetchWellKnown: async (principal, discoveryKey) => {
|
|
25339
25528
|
graph.assertActive();
|
|
25529
|
+
const destination = await this.encryptionDestination(this.getDefaultEncryptionNetworkId());
|
|
25530
|
+
if (this.auth?.registryRecordPresent) return null;
|
|
25340
25531
|
if (!address || !didPrincipalMatches2(principal, did)) {
|
|
25341
25532
|
return null;
|
|
25342
25533
|
}
|
|
25343
25534
|
const publicSpaceId = makePublicSpaceId(address, chainId);
|
|
25344
25535
|
const encodedKey = discoveryKey.split("/").map(encodeURIComponent).join("/");
|
|
25345
25536
|
const response = await graph.fetch(
|
|
25346
|
-
`${
|
|
25537
|
+
`${destination.url}/public/${encodeURIComponent(publicSpaceId)}/kv/${encodedKey}`,
|
|
25347
25538
|
{ method: "GET" }
|
|
25348
25539
|
);
|
|
25349
25540
|
graph.assertActive();
|
|
@@ -25713,7 +25904,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25713
25904
|
const signature2 = await this.signer.signMessage(prepared.siwe);
|
|
25714
25905
|
assertOwnerGraphActive();
|
|
25715
25906
|
const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature: signature2 });
|
|
25716
|
-
const activation = await
|
|
25907
|
+
const activation = await this.activateSignedSession(delegationSession, prepared.siwe, host);
|
|
25717
25908
|
assertOwnerGraphActive();
|
|
25718
25909
|
if (!activation.success) {
|
|
25719
25910
|
throw Object.assign(
|
|
@@ -26032,15 +26223,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26032
26223
|
async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
|
|
26033
26224
|
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
26034
26225
|
return this.fetchEncryptionNetworkAt(
|
|
26035
|
-
this.
|
|
26226
|
+
(await this.encryptionDestination(networkId)).url,
|
|
26036
26227
|
networkId,
|
|
26037
26228
|
globalThis.fetch.bind(globalThis)
|
|
26038
26229
|
);
|
|
26039
26230
|
}
|
|
26040
26231
|
async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
26041
|
-
const targetNode = await this.fetchNodeId();
|
|
26042
26232
|
const ownerDid = this.did;
|
|
26043
26233
|
const networkId = this.getDefaultEncryptionNetworkId(name);
|
|
26234
|
+
const destination = await this.encryptionDestination(networkId);
|
|
26235
|
+
const targetNode = destination.nodeDid;
|
|
26044
26236
|
const body = {
|
|
26045
26237
|
name,
|
|
26046
26238
|
ownerDid,
|
|
@@ -26063,7 +26255,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26063
26255
|
action: NETWORK_CREATE_ACTION2,
|
|
26064
26256
|
facts
|
|
26065
26257
|
});
|
|
26066
|
-
const response = await fetch(`${
|
|
26258
|
+
const response = await this._serviceGraph.fetch(`${destination.url}/encryption/networks`, {
|
|
26067
26259
|
method: "POST",
|
|
26068
26260
|
headers: {
|
|
26069
26261
|
Authorization: signed2.authorization,
|
|
@@ -26403,6 +26595,97 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26403
26595
|
}
|
|
26404
26596
|
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
26405
26597
|
}
|
|
26598
|
+
async activateResourceSession(delegationHeader, resources, hostHint, signal) {
|
|
26599
|
+
const targets = /* @__PURE__ */ new Map();
|
|
26600
|
+
const routedSpaces = [];
|
|
26601
|
+
let unserved;
|
|
26602
|
+
let requestedResource;
|
|
26603
|
+
for (const resource of new Set(resources)) {
|
|
26604
|
+
requestedResource ?? (requestedResource = resource);
|
|
26605
|
+
signal?.throwIfAborted();
|
|
26606
|
+
try {
|
|
26607
|
+
const encryption = resource.startsWith("urn:tinycloud:encryption:");
|
|
26608
|
+
const destinations = await this.routingDestinations(
|
|
26609
|
+
resource,
|
|
26610
|
+
encryption ? "encryption" : "host",
|
|
26611
|
+
[hostHint ?? this.config.host]
|
|
26612
|
+
);
|
|
26613
|
+
if (!encryption && destinations.some(({ nodeDid }) => nodeDid !== void 0)) routedSpaces.push(resource);
|
|
26614
|
+
for (const destination of destinations) {
|
|
26615
|
+
let target = targets.get(destination.url);
|
|
26616
|
+
if (!target) {
|
|
26617
|
+
target = { destination, spaces: [] };
|
|
26618
|
+
targets.set(destination.url, target);
|
|
26619
|
+
}
|
|
26620
|
+
if (!encryption && destination.nodeDid !== void 0) target.spaces.push(resource);
|
|
26621
|
+
}
|
|
26622
|
+
} catch (error) {
|
|
26623
|
+
if (!(error instanceof NodeNotFoundError2)) throw error;
|
|
26624
|
+
unserved ?? (unserved = error);
|
|
26625
|
+
}
|
|
26626
|
+
}
|
|
26627
|
+
if (targets.size === 0) throw unserved ?? new ResourceNotRoutedError(requestedResource ?? "session grant");
|
|
26628
|
+
const succeeded = [];
|
|
26629
|
+
const accepted = [];
|
|
26630
|
+
const failed = [];
|
|
26631
|
+
let refusal;
|
|
26632
|
+
for (const { destination: target, spaces } of targets.values()) {
|
|
26633
|
+
signal?.throwIfAborted();
|
|
26634
|
+
try {
|
|
26635
|
+
await verifyResourceDestination2(target, globalThis.fetch.bind(globalThis));
|
|
26636
|
+
const timeout = AbortSignal.timeout(5e3);
|
|
26637
|
+
const result = await activateSessionWithHost2(
|
|
26638
|
+
target.url,
|
|
26639
|
+
delegationHeader,
|
|
26640
|
+
signal ? AbortSignal.any([signal, timeout]) : timeout
|
|
26641
|
+
);
|
|
26642
|
+
this.throwRegistryRefusal(result.status, result.error ?? "");
|
|
26643
|
+
if (result.success) {
|
|
26644
|
+
const skipped = result.skipped?.find((space) => spaces.some((expected) => this.spaceIdsEqual(space, expected)));
|
|
26645
|
+
if (skipped) {
|
|
26646
|
+
failed.push({ url: target.url, status: result.status, cause: new ResourceNotRoutedError(skipped) });
|
|
26647
|
+
continue;
|
|
26648
|
+
}
|
|
26649
|
+
succeeded.push(target.url);
|
|
26650
|
+
accepted.push(result);
|
|
26651
|
+
} else {
|
|
26652
|
+
refusal = result;
|
|
26653
|
+
failed.push({ url: target.url, status: result.status, cause: result });
|
|
26654
|
+
}
|
|
26655
|
+
} catch (error) {
|
|
26656
|
+
if (signal?.aborted) throw error;
|
|
26657
|
+
failed.push({ url: target.url, cause: routingFailure3(error) ? error : new NodeNotRespondingError2([target.url], error) });
|
|
26658
|
+
}
|
|
26659
|
+
}
|
|
26660
|
+
if (failed.length > 0) {
|
|
26661
|
+
if (targets.size > 1) throw new PartialNodeWriteError2(succeeded, failed);
|
|
26662
|
+
if (refusal) return refusal;
|
|
26663
|
+
throw failed[0].cause;
|
|
26664
|
+
}
|
|
26665
|
+
const activated = new Set(accepted.flatMap((result) => result.activated ?? []));
|
|
26666
|
+
return {
|
|
26667
|
+
...accepted[0],
|
|
26668
|
+
activated: [...activated],
|
|
26669
|
+
skipped: [...new Set(accepted.flatMap((result) => result.skipped ?? []))].filter((space) => !activated.has(space) && !routedSpaces.some((expected) => this.spaceIdsEqual(space, expected)))
|
|
26670
|
+
};
|
|
26671
|
+
}
|
|
26672
|
+
activateRoutedDelegation(delegation, signal) {
|
|
26673
|
+
const resources = this.operationsFromDelegation(delegation).map(
|
|
26674
|
+
(operation) => operation.resource?.startsWith("urn:tinycloud:encryption:") ? operation.resource.split("/")[0] : operation.spaceId ?? delegation.spaceId
|
|
26675
|
+
);
|
|
26676
|
+
return this.activateResourceSession(delegation.delegationHeader, resources, delegation.host, signal);
|
|
26677
|
+
}
|
|
26678
|
+
activateSignedSession(session, siwe, hostHint, signal) {
|
|
26679
|
+
const resources = this.parseRecapWithCaveats(siwe).map(
|
|
26680
|
+
(entry) => this.isEncryptionNetworkOperation(this.invocationServiceName(entry.service), entry.path, entry.space) ? entry.path.split("/")[0] : entry.space.startsWith("tinycloud:") ? entry.space : session.spaceId
|
|
26681
|
+
);
|
|
26682
|
+
return this.activateResourceSession(
|
|
26683
|
+
session.delegationHeader,
|
|
26684
|
+
resources.length > 0 ? resources : [session.spaceId],
|
|
26685
|
+
hostHint,
|
|
26686
|
+
signal
|
|
26687
|
+
);
|
|
26688
|
+
}
|
|
26406
26689
|
/**
|
|
26407
26690
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
26408
26691
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -26422,16 +26705,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26422
26705
|
`Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
|
|
26423
26706
|
);
|
|
26424
26707
|
}
|
|
26425
|
-
const targetHost = delegation.host ?? this.config.host;
|
|
26426
26708
|
let activateResult;
|
|
26427
26709
|
try {
|
|
26428
|
-
activateResult = await
|
|
26429
|
-
targetHost,
|
|
26430
|
-
delegation.delegationHeader,
|
|
26431
|
-
graph.signal
|
|
26432
|
-
);
|
|
26710
|
+
activateResult = await this.activateRoutedDelegation(delegation, graph.signal);
|
|
26433
26711
|
} catch (cause) {
|
|
26434
26712
|
graph.assertActive();
|
|
26713
|
+
if (routingFailure3(cause)) throw cause;
|
|
26435
26714
|
throw Object.assign(
|
|
26436
26715
|
new Error("The TinyCloud host could not be reached to activate the delegation."),
|
|
26437
26716
|
{ code: "ACTIVATION_TRANSPORT_FAILED", cause }
|
|
@@ -26587,11 +26866,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26587
26866
|
...prepared,
|
|
26588
26867
|
signature: signature2
|
|
26589
26868
|
});
|
|
26590
|
-
const
|
|
26591
|
-
|
|
26592
|
-
|
|
26593
|
-
|
|
26594
|
-
|
|
26869
|
+
const delegation = this.runtimeDelegationFromSession(
|
|
26870
|
+
delegatedSession,
|
|
26871
|
+
delegatedEntries,
|
|
26872
|
+
spaceId,
|
|
26873
|
+
captured,
|
|
26874
|
+
expiresAt,
|
|
26875
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
26876
|
+
);
|
|
26877
|
+
const activateResult = await this.activateRoutedDelegation(delegation, graph.signal).catch((error) => {
|
|
26595
26878
|
graph.assertActive();
|
|
26596
26879
|
throw error;
|
|
26597
26880
|
});
|
|
@@ -26607,14 +26890,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26607
26890
|
{ cause: activateResult }
|
|
26608
26891
|
);
|
|
26609
26892
|
}
|
|
26610
|
-
const delegation = this.runtimeDelegationFromSession(
|
|
26611
|
-
delegatedSession,
|
|
26612
|
-
delegatedEntries,
|
|
26613
|
-
spaceId,
|
|
26614
|
-
captured,
|
|
26615
|
-
expiresAt,
|
|
26616
|
-
{ siwe: prepared.siwe, signature: signature2 }
|
|
26617
|
-
);
|
|
26618
26893
|
graph.assertActive();
|
|
26619
26894
|
assertCapturedKey?.();
|
|
26620
26895
|
this.runtimePermissionGrants.push({
|
|
@@ -26759,7 +27034,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26759
27034
|
if (!publicSpaceId) {
|
|
26760
27035
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
26761
27036
|
}
|
|
26762
|
-
await this.assertMayCreateSpace();
|
|
27037
|
+
await this.assertMayCreateSpace(publicSpaceId);
|
|
26763
27038
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
26764
27039
|
const kvActions = [KV3.PUT, KV3.GET, KV3.DEL, KV3.LIST, KV3.METADATA];
|
|
26765
27040
|
const abilities = { kv: { "": kvActions } };
|
|
@@ -26782,10 +27057,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26782
27057
|
...prepared,
|
|
26783
27058
|
signature: signature2
|
|
26784
27059
|
});
|
|
26785
|
-
const activateResult = await
|
|
26786
|
-
this.config.host,
|
|
26787
|
-
delegationSession.delegationHeader
|
|
26788
|
-
);
|
|
27060
|
+
const activateResult = await this.activateSignedSession(delegationSession, prepared.siwe);
|
|
26789
27061
|
if (!activateResult.success) {
|
|
26790
27062
|
throw Object.assign(
|
|
26791
27063
|
new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
|
|
@@ -27335,10 +27607,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
27335
27607
|
if (onPrepared) {
|
|
27336
27608
|
await onPrepared(delegation);
|
|
27337
27609
|
}
|
|
27338
|
-
const activateResult = await
|
|
27339
|
-
this.config.host,
|
|
27340
|
-
delegationHeader
|
|
27341
|
-
);
|
|
27610
|
+
const activateResult = await this.activateRoutedDelegation(delegation);
|
|
27342
27611
|
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
27343
27612
|
return delegation;
|
|
27344
27613
|
}
|
|
@@ -27372,10 +27641,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
27372
27641
|
if (onPrepared) {
|
|
27373
27642
|
await onPrepared(delegation);
|
|
27374
27643
|
}
|
|
27375
|
-
const activateResult = await
|
|
27376
|
-
targetHost,
|
|
27377
|
-
delegationHeader
|
|
27378
|
-
);
|
|
27644
|
+
const activateResult = await this.activateRoutedDelegation(delegation);
|
|
27379
27645
|
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
27380
27646
|
return delegation;
|
|
27381
27647
|
}
|
|
@@ -28027,10 +28293,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
28027
28293
|
...prepared,
|
|
28028
28294
|
signature: signature2
|
|
28029
28295
|
});
|
|
28030
|
-
const activateResult = await
|
|
28031
|
-
this.config.host,
|
|
28032
|
-
delegationSession.delegationHeader
|
|
28033
|
-
);
|
|
28296
|
+
const activateResult = await this.activateSignedSession(delegationSession, prepared.siwe);
|
|
28034
28297
|
if (!activateResult.success) {
|
|
28035
28298
|
throw Object.assign(
|
|
28036
28299
|
new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
|
|
@@ -28075,10 +28338,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
28075
28338
|
...publicPrepared,
|
|
28076
28339
|
signature: publicSignature
|
|
28077
28340
|
});
|
|
28078
|
-
const publicActivateResult = await
|
|
28079
|
-
this.config.host,
|
|
28080
|
-
publicSession.delegationHeader
|
|
28081
|
-
);
|
|
28341
|
+
const publicActivateResult = await this.activateSignedSession(publicSession, publicPrepared.siwe);
|
|
28082
28342
|
if (publicActivateResult.success) {
|
|
28083
28343
|
result.publicDelegation = {
|
|
28084
28344
|
cid: publicSession.delegationCid,
|
|
@@ -28184,11 +28444,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
28184
28444
|
...prepared,
|
|
28185
28445
|
signature: signature2
|
|
28186
28446
|
});
|
|
28187
|
-
const activateResult = await
|
|
28188
|
-
targetHost,
|
|
28189
|
-
invokerSession.delegationHeader,
|
|
28190
|
-
graph.signal
|
|
28191
|
-
).catch((error) => {
|
|
28447
|
+
const activateResult = await this.activateSignedSession(invokerSession, prepared.siwe, targetHost, graph.signal).catch((error) => {
|
|
28192
28448
|
graph.assertActive();
|
|
28193
28449
|
throw error;
|
|
28194
28450
|
});
|
|
@@ -28315,10 +28571,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
28315
28571
|
...prepared,
|
|
28316
28572
|
signature: signature2
|
|
28317
28573
|
});
|
|
28318
|
-
const activateResult = await
|
|
28319
|
-
targetHost,
|
|
28320
|
-
subDelegationSession.delegationHeader
|
|
28321
|
-
);
|
|
28574
|
+
const activateResult = await this.activateSignedSession(subDelegationSession, prepared.siwe, targetHost);
|
|
28322
28575
|
if (!activateResult.success) {
|
|
28323
28576
|
throw Object.assign(
|
|
28324
28577
|
new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
|
|
@@ -28382,6 +28635,7 @@ registerReplicationLoaders({
|
|
|
28382
28635
|
|
|
28383
28636
|
// src/index.ts
|
|
28384
28637
|
import { TinyCloud as TinyCloud2 } from "@tinycloud/sdk-core";
|
|
28638
|
+
import { NodeNotRespondingError as NodeNotRespondingError3, NodeIdentityMismatchError as NodeIdentityMismatchError2, PartialNodeWriteError as PartialNodeWriteError3 } from "@tinycloud/sdk-services";
|
|
28385
28639
|
import {
|
|
28386
28640
|
SilentNotificationHandler as SilentNotificationHandler2,
|
|
28387
28641
|
AutoApproveSpaceCreationHandler as AutoApproveSpaceCreationHandler2,
|
|
@@ -28699,7 +28953,7 @@ import {
|
|
|
28699
28953
|
SpaceService as SpaceService2,
|
|
28700
28954
|
SpaceErrorCodes,
|
|
28701
28955
|
createSpaceService,
|
|
28702
|
-
parseSpaceUri as
|
|
28956
|
+
parseSpaceUri as parseSpaceUri4,
|
|
28703
28957
|
buildSpaceUri,
|
|
28704
28958
|
makePublicSpaceId as makePublicSpaceId2,
|
|
28705
28959
|
Space
|
|
@@ -31270,8 +31524,11 @@ export {
|
|
|
31270
31524
|
MemorySessionStorage,
|
|
31271
31525
|
NETWORK_NAME_PATTERN,
|
|
31272
31526
|
NetworkIdError,
|
|
31527
|
+
NodeIdentityMismatchError2 as NodeIdentityMismatchError,
|
|
31528
|
+
NodeNotRespondingError3 as NodeNotRespondingError,
|
|
31273
31529
|
NodeUserAuthorization,
|
|
31274
31530
|
NodeWasmBindings,
|
|
31531
|
+
PartialNodeWriteError3 as PartialNodeWriteError,
|
|
31275
31532
|
PermissionNotInManifestError2 as PermissionNotInManifestError,
|
|
31276
31533
|
PrefixedKVService,
|
|
31277
31534
|
PrivateKeySigner,
|
|
@@ -31379,7 +31636,7 @@ export {
|
|
|
31379
31636
|
parseNetworkId3 as parseNetworkId,
|
|
31380
31637
|
parsePkhDid,
|
|
31381
31638
|
parseSecretCatalogKey,
|
|
31382
|
-
|
|
31639
|
+
parseSpaceUri4 as parseSpaceUri,
|
|
31383
31640
|
pkhDid4 as pkhDid,
|
|
31384
31641
|
principalDid3 as principalDid,
|
|
31385
31642
|
principalDidEquals4 as principalDidEquals,
|