@tinycloud/node-sdk 2.11.0 → 3.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{core-Bq8TMY7Y.d.cts → core-C6Czyr52.d.cts} +47 -2
- package/dist/{core-Bq8TMY7Y.d.ts → core-C6Czyr52.d.ts} +47 -2
- package/dist/core.cjs +446 -31
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +448 -32
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +152 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +154 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -17092,6 +17092,7 @@ __export(index_exports, {
|
|
|
17092
17092
|
VaultPublicSpaceKVActions: () => import_sdk_core16.VaultPublicSpaceKVActions,
|
|
17093
17093
|
VersionCheckError: () => import_sdk_core22.VersionCheckError,
|
|
17094
17094
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
17095
|
+
activateCompactRuntimeDelegation: () => activateCompactRuntimeDelegation,
|
|
17095
17096
|
activateValidatedRuntimeDelegation: () => activateValidatedRuntimeDelegation,
|
|
17096
17097
|
addressStorageKey: () => import_sdk_core11.addressStorageKey,
|
|
17097
17098
|
buildCanonicalDecryptRequest: () => import_sdk_core17.buildCanonicalDecryptRequest,
|
|
@@ -19206,6 +19207,18 @@ var ROOT_DELEGATION_ACTIONS = [
|
|
|
19206
19207
|
import_sdk_core7.DUCKDB.ALL
|
|
19207
19208
|
];
|
|
19208
19209
|
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core7.EXPIRY.SESSION_MS;
|
|
19210
|
+
function unifiedRootAttenuation(capabilities) {
|
|
19211
|
+
const attenuation = {};
|
|
19212
|
+
for (const capability of capabilities) {
|
|
19213
|
+
if (attenuation[capability.resource] !== void 0) throw new Error("unified owner root contains a duplicate resource");
|
|
19214
|
+
attenuation[capability.resource] = capability.kind === "encryption" ? { [capability.action]: [{}] } : Object.fromEntries(capability.actions.map((action) => [action, [{
|
|
19215
|
+
type: "xyz.tinycloud.resource/selector",
|
|
19216
|
+
kind: capability.selector,
|
|
19217
|
+
value: capability.resource
|
|
19218
|
+
}]]));
|
|
19219
|
+
}
|
|
19220
|
+
return attenuation;
|
|
19221
|
+
}
|
|
19209
19222
|
function decodeAuthorizationBytes(authorization) {
|
|
19210
19223
|
const encoded = authorization.replace(/^Bearer /i, "");
|
|
19211
19224
|
const match = /^([A-Za-z0-9_-]+)(={1,2})?$/.exec(encoded);
|
|
@@ -19585,6 +19598,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19585
19598
|
* hosting is confirmed against the session that was active at the time.
|
|
19586
19599
|
*/
|
|
19587
19600
|
this.confirmedHostedSpaceIds = /* @__PURE__ */ new Set();
|
|
19601
|
+
/** Serializes account-registry writes for the active node instance. */
|
|
19602
|
+
this.accountRegistryTail = Promise.resolve();
|
|
19588
19603
|
/**
|
|
19589
19604
|
* True when the last signIn() detected an interactive signer and skipped
|
|
19590
19605
|
* client-side bootstrap. Apps can read this to know whether bootstrap was
|
|
@@ -19981,6 +19996,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19981
19996
|
"Cannot signIn() in session-only mode. Provide a privateKey in config to create your own space."
|
|
19982
19997
|
);
|
|
19983
19998
|
}
|
|
19999
|
+
await this.accountRegistryTail;
|
|
19984
20000
|
await this.wasmBindings.ensureInitialized?.();
|
|
19985
20001
|
this._address = (0, import_sdk_core7.canonicalizeAddress)(await this.signer.getAddress());
|
|
19986
20002
|
this._chainId = await this.signer.getChainId();
|
|
@@ -20462,16 +20478,48 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20462
20478
|
}
|
|
20463
20479
|
}
|
|
20464
20480
|
scheduleAccountRegistrySync() {
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20468
|
-
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
20481
|
+
const session = this.currentTinyCloudSession();
|
|
20482
|
+
if (!session || this.pendingAccountRegistrySync?.session === session) {
|
|
20483
|
+
return;
|
|
20484
|
+
}
|
|
20485
|
+
const promise = this.enqueueAccountRegistryOperation(session, async () => {
|
|
20486
|
+
await this.withAccountRegistryRetry(async () => {
|
|
20487
|
+
if (this.currentTinyCloudSession() !== session) {
|
|
20488
|
+
return;
|
|
20489
|
+
}
|
|
20490
|
+
await this.account.index.ensure();
|
|
20491
|
+
if (this.currentTinyCloudSession() !== session) {
|
|
20492
|
+
return;
|
|
20493
|
+
}
|
|
20494
|
+
await this.writeManifestRegistryRecords();
|
|
20495
|
+
if (this.currentTinyCloudSession() !== session) {
|
|
20496
|
+
return;
|
|
20472
20497
|
}
|
|
20498
|
+
if (this.currentSessionCanListSpaces()) {
|
|
20499
|
+
const spaces = await this.account.spaces.syncAccessible();
|
|
20500
|
+
if (!spaces.ok) {
|
|
20501
|
+
throw new Error(`Failed to sync account spaces: ${spaces.error.message}`);
|
|
20502
|
+
}
|
|
20503
|
+
}
|
|
20504
|
+
});
|
|
20505
|
+
});
|
|
20506
|
+
this.pendingAccountRegistrySync = { session, promise };
|
|
20507
|
+
const clearPendingSync = () => {
|
|
20508
|
+
if (this.pendingAccountRegistrySync?.promise === promise) {
|
|
20509
|
+
this.pendingAccountRegistrySync = void 0;
|
|
20510
|
+
}
|
|
20511
|
+
};
|
|
20512
|
+
void promise.then(clearPendingSync, clearPendingSync);
|
|
20513
|
+
}
|
|
20514
|
+
enqueueAccountRegistryOperation(session, task) {
|
|
20515
|
+
const operation = this.accountRegistryTail.then(async () => {
|
|
20516
|
+
if (this.currentTinyCloudSession() === session) {
|
|
20517
|
+
await task();
|
|
20473
20518
|
}
|
|
20474
20519
|
});
|
|
20520
|
+
this.accountRegistryTail = operation.catch(() => {
|
|
20521
|
+
});
|
|
20522
|
+
return operation;
|
|
20475
20523
|
}
|
|
20476
20524
|
/**
|
|
20477
20525
|
* Whether the current primary session may invoke `tinycloud.space/list`.
|
|
@@ -20624,7 +20672,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20624
20672
|
* @returns The hosted space URI.
|
|
20625
20673
|
*/
|
|
20626
20674
|
async hostOwnedSpace(name) {
|
|
20627
|
-
|
|
20675
|
+
const session = this.auth?.tinyCloudSession;
|
|
20676
|
+
if (!this.auth || !session) {
|
|
20628
20677
|
throw new Error("Not signed in. Call signIn() first.");
|
|
20629
20678
|
}
|
|
20630
20679
|
const spaceId = this.ownedSpaceId(name);
|
|
@@ -20640,22 +20689,26 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20640
20689
|
}
|
|
20641
20690
|
const activation = await (0, import_sdk_core7.activateSessionWithHost)(
|
|
20642
20691
|
host,
|
|
20643
|
-
|
|
20692
|
+
session.delegationHeader
|
|
20644
20693
|
);
|
|
20645
20694
|
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
20646
20695
|
throw new Error(
|
|
20647
20696
|
`Failed to activate session for owned space ${spaceId}: ${activation.error ?? "space was skipped"}`
|
|
20648
20697
|
);
|
|
20649
20698
|
}
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
20653
|
-
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20699
|
+
try {
|
|
20700
|
+
await this.enqueueAccountRegistryOperation(session, async () => {
|
|
20701
|
+
await this.account.spaces.register({
|
|
20702
|
+
spaceId,
|
|
20703
|
+
name,
|
|
20704
|
+
ownerDid: this.did,
|
|
20705
|
+
type: "owned",
|
|
20706
|
+
permissions: ["*"],
|
|
20707
|
+
status: "active"
|
|
20708
|
+
});
|
|
20709
|
+
});
|
|
20710
|
+
} catch {
|
|
20711
|
+
}
|
|
20659
20712
|
return spaceId;
|
|
20660
20713
|
}
|
|
20661
20714
|
/**
|
|
@@ -20690,23 +20743,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20690
20743
|
if (!this.auth || !this.auth.tinyCloudSession) {
|
|
20691
20744
|
throw new Error("Not signed in. Call signIn() first.");
|
|
20692
20745
|
}
|
|
20746
|
+
await this.accountRegistryTail;
|
|
20693
20747
|
const spaceId = this.ownedSpaceId(name);
|
|
20694
20748
|
if (await this.isOwnedSpaceRegistered(spaceId)) {
|
|
20695
20749
|
return spaceId;
|
|
20696
20750
|
}
|
|
20697
|
-
|
|
20698
|
-
try {
|
|
20699
|
-
await this.account.spaces.register({
|
|
20700
|
-
spaceId,
|
|
20701
|
-
name,
|
|
20702
|
-
ownerDid: this.did,
|
|
20703
|
-
type: "owned",
|
|
20704
|
-
permissions: ["*"],
|
|
20705
|
-
status: "active"
|
|
20706
|
-
});
|
|
20707
|
-
} catch {
|
|
20708
|
-
}
|
|
20709
|
-
return hosted;
|
|
20751
|
+
return this.hostOwnedSpace(name);
|
|
20710
20752
|
}
|
|
20711
20753
|
/** Resolve and authenticate the owner encoded by an owned-space URI. */
|
|
20712
20754
|
credentialSpaceOwnerDid(spaceId) {
|
|
@@ -21259,6 +21301,46 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21259
21301
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
21260
21302
|
return signBytesWithJwk(bytes, session.jwk);
|
|
21261
21303
|
}
|
|
21304
|
+
/** Author a proofless Policy/v3 owner root with the authenticated holder key. */
|
|
21305
|
+
async createUnifiedOwnerRoot(input) {
|
|
21306
|
+
const ownerDid = this.credentialHolderDid;
|
|
21307
|
+
if (input.ownerDid !== ownerDid) throw new Error("unified owner root signer does not match owner DID");
|
|
21308
|
+
const facts = {
|
|
21309
|
+
role: input.role,
|
|
21310
|
+
mode: input.role === "policy-authority" ? "policy-source" : "conditional-mint",
|
|
21311
|
+
ownerDid,
|
|
21312
|
+
policyId: input.policyId,
|
|
21313
|
+
policyDigestHex: input.policyDigestHex,
|
|
21314
|
+
policyCid: input.policyCid,
|
|
21315
|
+
contentSourceDigestHex: input.contentSourceDigestHex,
|
|
21316
|
+
capabilityCeilingHashHex: input.capabilityCeilingHashHex,
|
|
21317
|
+
nativeProjectionHashHex: input.nativeProjectionHashHex,
|
|
21318
|
+
nodeAudience: input.nodeAudience,
|
|
21319
|
+
...input.role === "policy-enforcement" ? { enforcerDid: input.audienceDid } : {}
|
|
21320
|
+
};
|
|
21321
|
+
const root = await (0, import_sdk_core7.signCompactUcanRootAuthorization)({
|
|
21322
|
+
issuerDid: ownerDid,
|
|
21323
|
+
audienceDid: input.audienceDid,
|
|
21324
|
+
attenuation: unifiedRootAttenuation(input.capabilities),
|
|
21325
|
+
facts: [facts],
|
|
21326
|
+
notBefore: Math.floor(input.notBefore.getTime() / 1e3),
|
|
21327
|
+
expiresAt: Math.floor(input.expiresAt.getTime() / 1e3),
|
|
21328
|
+
nonce: base64UrlEncode(crypto.getRandomValues(new Uint8Array(16))),
|
|
21329
|
+
sign: (bytes) => this.signSessionBytes(bytes)
|
|
21330
|
+
});
|
|
21331
|
+
const kv = input.capabilities.find((capability) => capability.kind === "kv");
|
|
21332
|
+
const resource = kv?.resource ?? "";
|
|
21333
|
+
const marker = resource.indexOf("/kv/");
|
|
21334
|
+
return {
|
|
21335
|
+
cid: root.cid,
|
|
21336
|
+
delegationHeader: { Authorization: root.authorization },
|
|
21337
|
+
delegateDID: input.audienceDid,
|
|
21338
|
+
spaceId: marker === -1 ? "" : resource.slice("tinycloud://".length, marker),
|
|
21339
|
+
path: marker === -1 ? resource : resource.slice(marker + 4),
|
|
21340
|
+
actions: kv?.actions ?? [],
|
|
21341
|
+
expiry: input.expiresAt
|
|
21342
|
+
};
|
|
21343
|
+
}
|
|
21262
21344
|
/** Apply only an already-enabled signing policy to the exact credential request. */
|
|
21263
21345
|
async autoSignCredentialBytes(bytes) {
|
|
21264
21346
|
const strategy = this.config.signStrategy;
|
|
@@ -24497,7 +24579,7 @@ function compactUcanPayload(authorization) {
|
|
|
24497
24579
|
}
|
|
24498
24580
|
try {
|
|
24499
24581
|
const payload = JSON.parse(
|
|
24500
|
-
|
|
24582
|
+
new TextDecoder("utf-8", { fatal: true }).decode((0, import_sdk_core9.decodeBase64Url)(parts[1]))
|
|
24501
24583
|
);
|
|
24502
24584
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
24503
24585
|
throw new Error("payload is not an object");
|
|
@@ -24589,7 +24671,9 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24589
24671
|
));
|
|
24590
24672
|
continue;
|
|
24591
24673
|
}
|
|
24592
|
-
const
|
|
24674
|
+
const nativeMatch = /^(tinycloud:[^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
|
|
24675
|
+
const policyMatch = /^tinycloud:\/\/([^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
|
|
24676
|
+
const match = nativeMatch ?? policyMatch;
|
|
24593
24677
|
if (!match) {
|
|
24594
24678
|
throw new Error(
|
|
24595
24679
|
`Validated runtime delegation has an unsupported signed resource '${resource}'.`
|
|
@@ -24761,6 +24845,40 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
24761
24845
|
host: normalizedHost(installed.host ?? host)
|
|
24762
24846
|
};
|
|
24763
24847
|
}
|
|
24848
|
+
async function activateCompactRuntimeDelegation(node, input) {
|
|
24849
|
+
const authorization = input.authorization;
|
|
24850
|
+
const cid = node.computeDelegationCid(authorization);
|
|
24851
|
+
if (cid !== input.cid) {
|
|
24852
|
+
throw new Error("Compact runtime delegation CID does not match authorization bytes.");
|
|
24853
|
+
}
|
|
24854
|
+
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24855
|
+
const primary = signed2.resources[0];
|
|
24856
|
+
const signedSpace = signed2.permissions.find(
|
|
24857
|
+
(permission) => permission.service !== "tinycloud.encryption"
|
|
24858
|
+
)?.space;
|
|
24859
|
+
const delegation = {
|
|
24860
|
+
cid,
|
|
24861
|
+
delegationHeader: { Authorization: authorization },
|
|
24862
|
+
ownerAddress: input.ownerAddress,
|
|
24863
|
+
chainId: input.chainId,
|
|
24864
|
+
delegatorDID: signed2.issuer,
|
|
24865
|
+
authHeader: authorization,
|
|
24866
|
+
spaceId: signedSpace ?? primary.space,
|
|
24867
|
+
path: primary.path,
|
|
24868
|
+
actions: [...primary.actions],
|
|
24869
|
+
...primary.caveats === void 0 ? {} : { caveats: primary.caveats },
|
|
24870
|
+
resources: signed2.resources.map((resource) => ({
|
|
24871
|
+
...resource,
|
|
24872
|
+
actions: [...resource.actions]
|
|
24873
|
+
})),
|
|
24874
|
+
expiry: new Date(signed2.expiry),
|
|
24875
|
+
delegateDID: signed2.audience,
|
|
24876
|
+
host: normalizedHost(input.host)
|
|
24877
|
+
};
|
|
24878
|
+
return activateValidatedRuntimeDelegation(node, delegation, {
|
|
24879
|
+
host: input.host
|
|
24880
|
+
});
|
|
24881
|
+
}
|
|
24764
24882
|
async function grantAuthRequest(authority, request, options) {
|
|
24765
24883
|
if (request.kind !== "tinycloud.auth.request") {
|
|
24766
24884
|
throw new Error(
|
|
@@ -24883,6 +25001,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
24883
25001
|
VaultPublicSpaceKVActions,
|
|
24884
25002
|
VersionCheckError,
|
|
24885
25003
|
WasmKeyProvider,
|
|
25004
|
+
activateCompactRuntimeDelegation,
|
|
24886
25005
|
activateValidatedRuntimeDelegation,
|
|
24887
25006
|
addressStorageKey,
|
|
24888
25007
|
buildCanonicalDecryptRequest,
|