@tinycloud/node-sdk 2.1.0-beta.0 → 2.1.0-beta.2
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.cjs +519 -99
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +232 -4
- package/dist/core.d.ts +232 -4
- package/dist/core.js +451 -19
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +523 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +453 -19
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/core.cjs
CHANGED
|
@@ -20,55 +20,64 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/core.ts
|
|
21
21
|
var core_exports = {};
|
|
22
22
|
__export(core_exports, {
|
|
23
|
-
AutoApproveSpaceCreationHandler: () =>
|
|
24
|
-
CapabilityKeyRegistry: () =>
|
|
25
|
-
CapabilityKeyRegistryErrorCodes: () =>
|
|
26
|
-
DataVaultService: () =>
|
|
27
|
-
DatabaseHandle: () =>
|
|
23
|
+
AutoApproveSpaceCreationHandler: () => import_sdk_core7.AutoApproveSpaceCreationHandler,
|
|
24
|
+
CapabilityKeyRegistry: () => import_sdk_core14.CapabilityKeyRegistry,
|
|
25
|
+
CapabilityKeyRegistryErrorCodes: () => import_sdk_core14.CapabilityKeyRegistryErrorCodes,
|
|
26
|
+
DataVaultService: () => import_sdk_core12.DataVaultService,
|
|
27
|
+
DatabaseHandle: () => import_sdk_core10.DatabaseHandle,
|
|
28
28
|
DelegatedAccess: () => DelegatedAccess,
|
|
29
|
-
DelegationErrorCodes: () =>
|
|
30
|
-
DelegationManager: () =>
|
|
31
|
-
DuckDbAction: () =>
|
|
32
|
-
DuckDbDatabaseHandle: () =>
|
|
33
|
-
DuckDbService: () =>
|
|
29
|
+
DelegationErrorCodes: () => import_sdk_core13.DelegationErrorCodes,
|
|
30
|
+
DelegationManager: () => import_sdk_core13.DelegationManager,
|
|
31
|
+
DuckDbAction: () => import_sdk_core11.DuckDbAction,
|
|
32
|
+
DuckDbDatabaseHandle: () => import_sdk_core11.DuckDbDatabaseHandle,
|
|
33
|
+
DuckDbService: () => import_sdk_core11.DuckDbService,
|
|
34
34
|
FileSessionStorage: () => FileSessionStorage,
|
|
35
|
-
KVService: () =>
|
|
35
|
+
KVService: () => import_sdk_core9.KVService,
|
|
36
|
+
ManifestValidationError: () => import_sdk_core8.ManifestValidationError,
|
|
36
37
|
MemorySessionStorage: () => MemorySessionStorage,
|
|
37
38
|
NodeUserAuthorization: () => NodeUserAuthorization,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
PermissionNotInManifestError: () => import_sdk_core8.PermissionNotInManifestError,
|
|
40
|
+
PrefixedKVService: () => import_sdk_core9.PrefixedKVService,
|
|
41
|
+
ProtocolMismatchError: () => import_sdk_core16.ProtocolMismatchError,
|
|
42
|
+
SQLAction: () => import_sdk_core10.SQLAction,
|
|
43
|
+
SQLService: () => import_sdk_core10.SQLService,
|
|
44
|
+
ServiceContext: () => import_sdk_core17.ServiceContext,
|
|
45
|
+
SessionExpiredError: () => import_sdk_core8.SessionExpiredError,
|
|
46
|
+
SharingService: () => import_sdk_core13.SharingService,
|
|
47
|
+
SilentNotificationHandler: () => import_sdk_core7.SilentNotificationHandler,
|
|
48
|
+
Space: () => import_sdk_core15.Space,
|
|
49
|
+
SpaceErrorCodes: () => import_sdk_core15.SpaceErrorCodes,
|
|
50
|
+
SpaceService: () => import_sdk_core15.SpaceService,
|
|
51
|
+
TinyCloud: () => import_sdk_core6.TinyCloud,
|
|
49
52
|
TinyCloudNode: () => TinyCloudNode,
|
|
50
|
-
UnsupportedFeatureError: () =>
|
|
51
|
-
VaultHeaders: () =>
|
|
52
|
-
VaultPublicSpaceKVActions: () =>
|
|
53
|
-
VersionCheckError: () =>
|
|
53
|
+
UnsupportedFeatureError: () => import_sdk_core16.UnsupportedFeatureError,
|
|
54
|
+
VaultHeaders: () => import_sdk_core12.VaultHeaders,
|
|
55
|
+
VaultPublicSpaceKVActions: () => import_sdk_core12.VaultPublicSpaceKVActions,
|
|
56
|
+
VersionCheckError: () => import_sdk_core16.VersionCheckError,
|
|
54
57
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
55
|
-
buildSpaceUri: () =>
|
|
56
|
-
checkNodeInfo: () =>
|
|
57
|
-
createCapabilityKeyRegistry: () =>
|
|
58
|
-
createSharingService: () =>
|
|
59
|
-
createSpaceService: () =>
|
|
60
|
-
createVaultCrypto: () =>
|
|
58
|
+
buildSpaceUri: () => import_sdk_core15.buildSpaceUri,
|
|
59
|
+
checkNodeInfo: () => import_sdk_core16.checkNodeInfo,
|
|
60
|
+
createCapabilityKeyRegistry: () => import_sdk_core14.createCapabilityKeyRegistry,
|
|
61
|
+
createSharingService: () => import_sdk_core13.createSharingService,
|
|
62
|
+
createSpaceService: () => import_sdk_core15.createSpaceService,
|
|
63
|
+
createVaultCrypto: () => import_sdk_core12.createVaultCrypto,
|
|
61
64
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
62
65
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
63
|
-
defaultSpaceCreationHandler: () =>
|
|
66
|
+
defaultSpaceCreationHandler: () => import_sdk_core7.defaultSpaceCreationHandler,
|
|
64
67
|
deserializeDelegation: () => deserializeDelegation,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
expandActionShortNames: () => import_sdk_core8.expandActionShortNames,
|
|
69
|
+
isCapabilitySubset: () => import_sdk_core8.isCapabilitySubset,
|
|
70
|
+
loadManifest: () => import_sdk_core8.loadManifest,
|
|
71
|
+
makePublicSpaceId: () => import_sdk_core15.makePublicSpaceId,
|
|
72
|
+
parseExpiry: () => import_sdk_core8.parseExpiry,
|
|
73
|
+
parseSpaceUri: () => import_sdk_core15.parseSpaceUri,
|
|
74
|
+
resolveManifest: () => import_sdk_core8.resolveManifest,
|
|
75
|
+
serializeDelegation: () => serializeDelegation,
|
|
76
|
+
validateManifest: () => import_sdk_core8.validateManifest
|
|
68
77
|
});
|
|
69
78
|
module.exports = __toCommonJS(core_exports);
|
|
70
|
-
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
71
79
|
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
80
|
+
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
72
81
|
|
|
73
82
|
// src/storage/MemorySessionStorage.ts
|
|
74
83
|
var MemorySessionStorage = class {
|
|
@@ -330,8 +339,25 @@ var NodeUserAuthorization = class {
|
|
|
330
339
|
this.enablePublicSpace = config.enablePublicSpace ?? true;
|
|
331
340
|
this.nonce = config.nonce;
|
|
332
341
|
this.siweConfig = config.siweConfig;
|
|
342
|
+
this._manifest = config.manifest;
|
|
333
343
|
this.sessionManager = this.wasm.createSessionManager();
|
|
334
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Return the manifest currently driving sign-in behavior, or
|
|
347
|
+
* `undefined` if none is set. Used by TinyCloudWeb/TinyCloudNode
|
|
348
|
+
* internals to surface the manifest for requestPermissions flows
|
|
349
|
+
* without forcing the caller to track it separately.
|
|
350
|
+
*/
|
|
351
|
+
get manifest() {
|
|
352
|
+
return this._manifest;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Install or replace the stored manifest. Takes effect on the next
|
|
356
|
+
* `signIn()` call — the current session (if any) is not touched.
|
|
357
|
+
*/
|
|
358
|
+
setManifest(manifest) {
|
|
359
|
+
this._manifest = manifest;
|
|
360
|
+
}
|
|
335
361
|
/**
|
|
336
362
|
* The current active session (web-core compatible).
|
|
337
363
|
*/
|
|
@@ -348,6 +374,39 @@ var NodeUserAuthorization = class {
|
|
|
348
374
|
get nodeFeatures() {
|
|
349
375
|
return this._nodeFeatures;
|
|
350
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Compute the `abilities` map the WASM `prepareSession` call should
|
|
379
|
+
* see at sign-in time.
|
|
380
|
+
*
|
|
381
|
+
* When a manifest is installed, we resolve it and union together:
|
|
382
|
+
* - the app's own `resources` (what it needs at runtime)
|
|
383
|
+
* - every `additionalDelegates[*].permissions` list (what it will
|
|
384
|
+
* re-delegate to other DIDs post sign-in)
|
|
385
|
+
*
|
|
386
|
+
* into the short-service / path / full-URN-actions shape the WASM
|
|
387
|
+
* layer expects. This is the key invariant that lets
|
|
388
|
+
* {@link TinyCloudNode.delegateTo} issue manifest-declared
|
|
389
|
+
* delegations via the session key (no wallet prompt): the session's
|
|
390
|
+
* own recap already covers every action those delegations need.
|
|
391
|
+
*
|
|
392
|
+
* When no manifest is installed, we fall back to the
|
|
393
|
+
* {@link defaultActions} table so existing callers see no change.
|
|
394
|
+
*
|
|
395
|
+
* This is a pure function of `this._manifest` + `this.defaultActions`
|
|
396
|
+
* — the manifest resolution performs no I/O and throws a
|
|
397
|
+
* {@link ManifestValidationError} on structural problems (missing
|
|
398
|
+
* id/name, unparseable expiry, etc), which will surface at sign-in
|
|
399
|
+
* rather than being silently swallowed.
|
|
400
|
+
*
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
resolveSignInAbilities() {
|
|
404
|
+
if (this._manifest === void 0) {
|
|
405
|
+
return this.defaultActions;
|
|
406
|
+
}
|
|
407
|
+
const resolved = (0, import_sdk_core2.resolveManifest)(this._manifest);
|
|
408
|
+
return (0, import_sdk_core2.manifestAbilitiesUnion)(resolved);
|
|
409
|
+
}
|
|
351
410
|
/**
|
|
352
411
|
* Build SIWE overrides from the top-level nonce and siweConfig.
|
|
353
412
|
* - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
|
|
@@ -551,7 +610,7 @@ var NodeUserAuthorization = class {
|
|
|
551
610
|
const now = /* @__PURE__ */ new Date();
|
|
552
611
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
553
612
|
const prepared = this.wasm.prepareSession({
|
|
554
|
-
abilities: this.
|
|
613
|
+
abilities: this.resolveSignInAbilities(),
|
|
555
614
|
address,
|
|
556
615
|
chainId,
|
|
557
616
|
domain: this.domain,
|
|
@@ -694,7 +753,7 @@ var NodeUserAuthorization = class {
|
|
|
694
753
|
const now = /* @__PURE__ */ new Date();
|
|
695
754
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
696
755
|
const prepared = this.wasm.prepareSession({
|
|
697
|
-
abilities: this.
|
|
756
|
+
abilities: this.resolveSignInAbilities(),
|
|
698
757
|
address,
|
|
699
758
|
chainId,
|
|
700
759
|
domain: this.domain,
|
|
@@ -862,7 +921,7 @@ var NodeUserAuthorization = class {
|
|
|
862
921
|
};
|
|
863
922
|
|
|
864
923
|
// src/TinyCloudNode.ts
|
|
865
|
-
var
|
|
924
|
+
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
866
925
|
|
|
867
926
|
// src/DelegatedAccess.ts
|
|
868
927
|
var import_sdk_core3 = require("@tinycloud/sdk-core");
|
|
@@ -1017,9 +1076,69 @@ function createWasmKeyProvider(sessionManager) {
|
|
|
1017
1076
|
return new WasmKeyProvider({ sessionManager });
|
|
1018
1077
|
}
|
|
1019
1078
|
|
|
1079
|
+
// src/delegateToHelpers.ts
|
|
1080
|
+
var import_sdk_core4 = require("@tinycloud/sdk-core");
|
|
1081
|
+
function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
1082
|
+
const byService = /* @__PURE__ */ new Map();
|
|
1083
|
+
for (const a of actions) {
|
|
1084
|
+
const slashIdx = a.indexOf("/");
|
|
1085
|
+
if (slashIdx === -1) {
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
const service = a.slice(0, slashIdx);
|
|
1089
|
+
if (!service.startsWith("tinycloud.")) {
|
|
1090
|
+
continue;
|
|
1091
|
+
}
|
|
1092
|
+
const list = byService.get(service);
|
|
1093
|
+
if (list === void 0) {
|
|
1094
|
+
byService.set(service, [a]);
|
|
1095
|
+
} else {
|
|
1096
|
+
list.push(a);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
const space = spaceIdOverride ?? "default";
|
|
1100
|
+
const entries = [];
|
|
1101
|
+
for (const [service, actionList] of byService) {
|
|
1102
|
+
entries.push({
|
|
1103
|
+
service,
|
|
1104
|
+
space,
|
|
1105
|
+
path,
|
|
1106
|
+
actions: actionList
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
return entries;
|
|
1110
|
+
}
|
|
1111
|
+
function resolveExpiryMs(expiry) {
|
|
1112
|
+
if (expiry === void 0) {
|
|
1113
|
+
return 60 * 60 * 1e3;
|
|
1114
|
+
}
|
|
1115
|
+
if (typeof expiry === "number") {
|
|
1116
|
+
if (!Number.isFinite(expiry) || expiry <= 0) {
|
|
1117
|
+
throw new Error(
|
|
1118
|
+
`delegateTo expiry must be a positive finite number (got ${expiry})`
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
return expiry;
|
|
1122
|
+
}
|
|
1123
|
+
return (0, import_sdk_core4.parseExpiry)(expiry);
|
|
1124
|
+
}
|
|
1125
|
+
function extractSiweExpiration(siwe) {
|
|
1126
|
+
const parsed = new import_sdk_core4.SiweMessage(siwe);
|
|
1127
|
+
if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
|
|
1128
|
+
return void 0;
|
|
1129
|
+
}
|
|
1130
|
+
const d = new Date(parsed.expirationTime);
|
|
1131
|
+
if (Number.isNaN(d.getTime())) {
|
|
1132
|
+
throw new Error(
|
|
1133
|
+
`Session SIWE has unparseable expirationTime: ${parsed.expirationTime}`
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
return d;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1020
1139
|
// src/TinyCloudNode.ts
|
|
1021
1140
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
1022
|
-
var
|
|
1141
|
+
var _TinyCloudNode = class _TinyCloudNode {
|
|
1023
1142
|
/**
|
|
1024
1143
|
* Create a new TinyCloudNode instance.
|
|
1025
1144
|
*
|
|
@@ -1074,12 +1193,12 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1074
1193
|
throw new Error("Failed to get session key JWK");
|
|
1075
1194
|
}
|
|
1076
1195
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
1077
|
-
this._capabilityRegistry = new
|
|
1196
|
+
this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
|
|
1078
1197
|
this._keyProvider = new WasmKeyProvider({
|
|
1079
1198
|
sessionManager: this.sessionManager
|
|
1080
1199
|
});
|
|
1081
|
-
this.notificationHandler = config.notificationHandler ?? new
|
|
1082
|
-
this._sharingService = new
|
|
1200
|
+
this.notificationHandler = config.notificationHandler ?? new import_sdk_core5.SilentNotificationHandler();
|
|
1201
|
+
this._sharingService = new import_sdk_core5.SharingService({
|
|
1083
1202
|
hosts: [this.config.host],
|
|
1084
1203
|
// session: undefined - not needed for receive()
|
|
1085
1204
|
invoke: this.wasmBindings.invoke,
|
|
@@ -1089,8 +1208,8 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1089
1208
|
// delegationManager: undefined - not needed for receive()
|
|
1090
1209
|
createKVService: (config2) => {
|
|
1091
1210
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
1092
|
-
const kvService = new
|
|
1093
|
-
const kvContext = new
|
|
1211
|
+
const kvService = new import_sdk_core5.KVService({ prefix });
|
|
1212
|
+
const kvContext = new import_sdk_core5.ServiceContext({
|
|
1094
1213
|
invoke: config2.invoke,
|
|
1095
1214
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
1096
1215
|
hosts: config2.hosts
|
|
@@ -1143,12 +1262,35 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1143
1262
|
enablePublicSpace: config.enablePublicSpace ?? true,
|
|
1144
1263
|
spaceCreationHandler: config.spaceCreationHandler,
|
|
1145
1264
|
nonce: config.nonce,
|
|
1146
|
-
siweConfig: config.siweConfig
|
|
1265
|
+
siweConfig: config.siweConfig,
|
|
1266
|
+
manifest: config.manifest
|
|
1147
1267
|
});
|
|
1148
|
-
this.tc = new
|
|
1268
|
+
this.tc = new import_sdk_core5.TinyCloud(this.auth, {
|
|
1149
1269
|
invokeAny: this.wasmBindings.invokeAny
|
|
1150
1270
|
});
|
|
1151
1271
|
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Install or replace the manifest that drives the SIWE recap at
|
|
1274
|
+
* sign-in. Takes effect on the next `signIn()` call — the current
|
|
1275
|
+
* session (if any) is not touched. Wire this up from a higher
|
|
1276
|
+
* layer (e.g. TinyCloudWeb.setManifest) so the manifest is kept
|
|
1277
|
+
* in sync across the stack.
|
|
1278
|
+
*/
|
|
1279
|
+
setManifest(manifest) {
|
|
1280
|
+
if (!this.auth) {
|
|
1281
|
+
throw new Error(
|
|
1282
|
+
"setManifest requires wallet mode. Provide a signer or privateKey in the TinyCloudNode config."
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
this.auth.setManifest(manifest);
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Return the manifest currently installed on the auth handler,
|
|
1289
|
+
* or `undefined` if none is set.
|
|
1290
|
+
*/
|
|
1291
|
+
get manifest() {
|
|
1292
|
+
return this.auth?.manifest;
|
|
1293
|
+
}
|
|
1152
1294
|
/**
|
|
1153
1295
|
* Get the primary identity DID for this user.
|
|
1154
1296
|
* - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
|
|
@@ -1244,22 +1386,22 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1244
1386
|
if (sessionData.chainId) {
|
|
1245
1387
|
this._chainId = sessionData.chainId;
|
|
1246
1388
|
}
|
|
1247
|
-
this._serviceContext = new
|
|
1389
|
+
this._serviceContext = new import_sdk_core5.ServiceContext({
|
|
1248
1390
|
invoke: this.wasmBindings.invoke,
|
|
1249
1391
|
invokeAny: this.wasmBindings.invokeAny,
|
|
1250
1392
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1251
1393
|
hosts: [this.config.host]
|
|
1252
1394
|
});
|
|
1253
|
-
this._kv = new
|
|
1395
|
+
this._kv = new import_sdk_core5.KVService({});
|
|
1254
1396
|
this._kv.initialize(this._serviceContext);
|
|
1255
1397
|
this._serviceContext.registerService("kv", this._kv);
|
|
1256
|
-
this._sql = new
|
|
1398
|
+
this._sql = new import_sdk_core5.SQLService({});
|
|
1257
1399
|
this._sql.initialize(this._serviceContext);
|
|
1258
1400
|
this._serviceContext.registerService("sql", this._sql);
|
|
1259
|
-
this._duckdb = new
|
|
1401
|
+
this._duckdb = new import_sdk_core5.DuckDbService({});
|
|
1260
1402
|
this._duckdb.initialize(this._serviceContext);
|
|
1261
1403
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1262
|
-
this._hooks = new
|
|
1404
|
+
this._hooks = new import_sdk_core5.HooksService({});
|
|
1263
1405
|
this._hooks.initialize(this._serviceContext);
|
|
1264
1406
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1265
1407
|
const serviceSession = {
|
|
@@ -1271,7 +1413,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1271
1413
|
};
|
|
1272
1414
|
this._serviceContext.setSession(serviceSession);
|
|
1273
1415
|
const wasm = this.wasmBindings;
|
|
1274
|
-
const vaultCrypto = (0,
|
|
1416
|
+
const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
|
|
1275
1417
|
vault_encrypt: wasm.vault_encrypt,
|
|
1276
1418
|
vault_decrypt: wasm.vault_decrypt,
|
|
1277
1419
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -1281,7 +1423,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1281
1423
|
vault_sha256: wasm.vault_sha256
|
|
1282
1424
|
});
|
|
1283
1425
|
const self = this;
|
|
1284
|
-
this._vault = new
|
|
1426
|
+
this._vault = new import_sdk_core5.DataVaultService({
|
|
1285
1427
|
spaceId: sessionData.spaceId,
|
|
1286
1428
|
crypto: vaultCrypto,
|
|
1287
1429
|
tc: {
|
|
@@ -1297,8 +1439,8 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1297
1439
|
get publicKV() {
|
|
1298
1440
|
return self._publicKV ?? self.tc.publicKV;
|
|
1299
1441
|
},
|
|
1300
|
-
readPublicSpace: (host, spaceId, key) =>
|
|
1301
|
-
makePublicSpaceId:
|
|
1442
|
+
readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
|
|
1443
|
+
makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
|
|
1302
1444
|
did: this.did,
|
|
1303
1445
|
address: sessionData.address ?? this._address ?? "",
|
|
1304
1446
|
chainId: sessionData.chainId ?? this._chainId,
|
|
@@ -1361,7 +1503,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1361
1503
|
nonce: this.config.nonce,
|
|
1362
1504
|
siweConfig: this.config.siweConfig
|
|
1363
1505
|
});
|
|
1364
|
-
this.tc = new
|
|
1506
|
+
this.tc = new import_sdk_core5.TinyCloud(this.auth, {
|
|
1365
1507
|
invokeAny: this.wasmBindings.invokeAny
|
|
1366
1508
|
});
|
|
1367
1509
|
this.config.prefix = prefix;
|
|
@@ -1401,7 +1543,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1401
1543
|
nonce: this.config.nonce,
|
|
1402
1544
|
siweConfig: this.config.siweConfig
|
|
1403
1545
|
});
|
|
1404
|
-
this.tc = new
|
|
1546
|
+
this.tc = new import_sdk_core5.TinyCloud(this.auth, {
|
|
1405
1547
|
invokeAny: this.wasmBindings.invokeAny
|
|
1406
1548
|
});
|
|
1407
1549
|
this.config.prefix = prefix;
|
|
@@ -1416,27 +1558,27 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1416
1558
|
return;
|
|
1417
1559
|
}
|
|
1418
1560
|
this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
|
|
1419
|
-
this._serviceContext = new
|
|
1561
|
+
this._serviceContext = new import_sdk_core5.ServiceContext({
|
|
1420
1562
|
invoke: this.wasmBindings.invoke,
|
|
1421
1563
|
invokeAny: this.wasmBindings.invokeAny,
|
|
1422
1564
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1423
1565
|
hosts: [this.config.host]
|
|
1424
1566
|
});
|
|
1425
|
-
this._kv = new
|
|
1567
|
+
this._kv = new import_sdk_core5.KVService({});
|
|
1426
1568
|
this._kv.initialize(this._serviceContext);
|
|
1427
1569
|
this._serviceContext.registerService("kv", this._kv);
|
|
1428
1570
|
const features = this.nodeFeatures;
|
|
1429
1571
|
if (features.length === 0 || features.includes("sql")) {
|
|
1430
|
-
this._sql = new
|
|
1572
|
+
this._sql = new import_sdk_core5.SQLService({});
|
|
1431
1573
|
this._sql.initialize(this._serviceContext);
|
|
1432
1574
|
this._serviceContext.registerService("sql", this._sql);
|
|
1433
1575
|
}
|
|
1434
1576
|
if (features.length === 0 || features.includes("duckdb")) {
|
|
1435
|
-
this._duckdb = new
|
|
1577
|
+
this._duckdb = new import_sdk_core5.DuckDbService({});
|
|
1436
1578
|
this._duckdb.initialize(this._serviceContext);
|
|
1437
1579
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1438
1580
|
}
|
|
1439
|
-
this._hooks = new
|
|
1581
|
+
this._hooks = new import_sdk_core5.HooksService({});
|
|
1440
1582
|
this._hooks.initialize(this._serviceContext);
|
|
1441
1583
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1442
1584
|
const serviceSession = {
|
|
@@ -1449,7 +1591,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1449
1591
|
this._serviceContext.setSession(serviceSession);
|
|
1450
1592
|
this.tc.serviceContext.setSession(serviceSession);
|
|
1451
1593
|
const wasm = this.wasmBindings;
|
|
1452
|
-
const vaultCrypto = (0,
|
|
1594
|
+
const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
|
|
1453
1595
|
vault_encrypt: wasm.vault_encrypt,
|
|
1454
1596
|
vault_decrypt: wasm.vault_decrypt,
|
|
1455
1597
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -1459,7 +1601,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1459
1601
|
vault_sha256: wasm.vault_sha256
|
|
1460
1602
|
});
|
|
1461
1603
|
const self = this;
|
|
1462
|
-
this._vault = new
|
|
1604
|
+
this._vault = new import_sdk_core5.DataVaultService({
|
|
1463
1605
|
spaceId: session.spaceId,
|
|
1464
1606
|
crypto: vaultCrypto,
|
|
1465
1607
|
tc: {
|
|
@@ -1475,8 +1617,8 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1475
1617
|
get publicKV() {
|
|
1476
1618
|
return self._publicKV ?? self.tc.publicKV;
|
|
1477
1619
|
},
|
|
1478
|
-
readPublicSpace: (host, spaceId, key) =>
|
|
1479
|
-
makePublicSpaceId:
|
|
1620
|
+
readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
|
|
1621
|
+
makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
|
|
1480
1622
|
did: this.did,
|
|
1481
1623
|
address: this._address,
|
|
1482
1624
|
chainId: this._chainId,
|
|
@@ -1492,7 +1634,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1492
1634
|
* @internal
|
|
1493
1635
|
*/
|
|
1494
1636
|
initializeV2Services(serviceSession) {
|
|
1495
|
-
this._capabilityRegistry = new
|
|
1637
|
+
this._capabilityRegistry = new import_sdk_core5.CapabilityKeyRegistry();
|
|
1496
1638
|
const tcSession = this.auth?.tinyCloudSession;
|
|
1497
1639
|
if (tcSession && this._address) {
|
|
1498
1640
|
const sessionKey = {
|
|
@@ -1566,13 +1708,13 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1566
1708
|
}
|
|
1567
1709
|
this._capabilityRegistry.registerKey(sessionKey, delegations);
|
|
1568
1710
|
}
|
|
1569
|
-
this._delegationManager = new
|
|
1711
|
+
this._delegationManager = new import_sdk_core5.DelegationManager({
|
|
1570
1712
|
hosts: [this.config.host],
|
|
1571
1713
|
session: serviceSession,
|
|
1572
1714
|
invoke: this.wasmBindings.invoke,
|
|
1573
1715
|
fetch: globalThis.fetch.bind(globalThis)
|
|
1574
1716
|
});
|
|
1575
|
-
this._spaceService = new
|
|
1717
|
+
this._spaceService = new import_sdk_core5.SpaceService({
|
|
1576
1718
|
hosts: [this.config.host],
|
|
1577
1719
|
session: serviceSession,
|
|
1578
1720
|
invoke: this.wasmBindings.invoke,
|
|
@@ -1580,9 +1722,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1580
1722
|
capabilityRegistry: this._capabilityRegistry,
|
|
1581
1723
|
userDid: this.did,
|
|
1582
1724
|
createKVService: (spaceId) => {
|
|
1583
|
-
const kvService = new
|
|
1725
|
+
const kvService = new import_sdk_core5.KVService({});
|
|
1584
1726
|
if (this._serviceContext) {
|
|
1585
|
-
const spaceScopedContext = new
|
|
1727
|
+
const spaceScopedContext = new import_sdk_core5.ServiceContext({
|
|
1586
1728
|
invoke: this._serviceContext.invoke,
|
|
1587
1729
|
fetch: this._serviceContext.fetch,
|
|
1588
1730
|
hosts: this._serviceContext.hosts
|
|
@@ -1655,7 +1797,19 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1655
1797
|
}
|
|
1656
1798
|
/**
|
|
1657
1799
|
* Wrapper for the WASM createDelegation function.
|
|
1658
|
-
*
|
|
1800
|
+
*
|
|
1801
|
+
* The WASM call now takes a multi-resource `abilities` map
|
|
1802
|
+
* (matching `prepareSession`'s shape) and emits ONE UCAN that
|
|
1803
|
+
* covers every `(service, path, actions)` entry. We mirror the raw
|
|
1804
|
+
* result back through `CreateDelegationWasmResult`, converting the
|
|
1805
|
+
* seconds-since-epoch `expiry` to a Date and normalizing the
|
|
1806
|
+
* `delegateDid` → `delegateDID` case.
|
|
1807
|
+
*
|
|
1808
|
+
* Both SharingService (single-entry) and
|
|
1809
|
+
* {@link TinyCloudNode.delegateTo} (multi-entry) drive this through
|
|
1810
|
+
* the same code path so there's exactly one place that touches the
|
|
1811
|
+
* WASM boundary.
|
|
1812
|
+
*
|
|
1659
1813
|
* @internal
|
|
1660
1814
|
*/
|
|
1661
1815
|
createDelegationWrapper(params) {
|
|
@@ -1670,18 +1824,19 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1670
1824
|
wasmSession,
|
|
1671
1825
|
params.delegateDID,
|
|
1672
1826
|
params.spaceId,
|
|
1673
|
-
params.
|
|
1674
|
-
params.actions,
|
|
1827
|
+
params.abilities,
|
|
1675
1828
|
params.expirationSecs,
|
|
1676
1829
|
params.notBeforeSecs
|
|
1677
1830
|
);
|
|
1678
1831
|
return {
|
|
1679
1832
|
delegation: result.delegation,
|
|
1680
1833
|
cid: result.cid,
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1834
|
+
// Rust serde `rename_all = "camelCase"` emits `delegateDid`
|
|
1835
|
+
// (lowercase d); the TypeScript interface uses `delegateDID`
|
|
1836
|
+
// (historical, matches Delegation.delegateDID). Normalize here.
|
|
1837
|
+
delegateDID: result.delegateDid ?? result.delegateDID,
|
|
1838
|
+
expiry: new Date(result.expiry * 1e3),
|
|
1839
|
+
resources: result.resources
|
|
1685
1840
|
};
|
|
1686
1841
|
}
|
|
1687
1842
|
/**
|
|
@@ -1721,7 +1876,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1721
1876
|
...prepared,
|
|
1722
1877
|
signature
|
|
1723
1878
|
});
|
|
1724
|
-
const activateResult = await (0,
|
|
1879
|
+
const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
1725
1880
|
host,
|
|
1726
1881
|
delegationSession.delegationHeader
|
|
1727
1882
|
);
|
|
@@ -1788,7 +1943,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1788
1943
|
if (!this._sql) {
|
|
1789
1944
|
const features = this.nodeFeatures;
|
|
1790
1945
|
if (features.length > 0 && !features.includes("sql")) {
|
|
1791
|
-
throw new
|
|
1946
|
+
throw new import_sdk_core5.UnsupportedFeatureError("sql", this.config.host, features);
|
|
1792
1947
|
}
|
|
1793
1948
|
throw new Error("Not signed in. Call signIn() first.");
|
|
1794
1949
|
}
|
|
@@ -1801,7 +1956,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
1801
1956
|
if (!this._duckdb) {
|
|
1802
1957
|
const features = this.nodeFeatures;
|
|
1803
1958
|
if (features.length > 0 && !features.includes("duckdb")) {
|
|
1804
|
-
throw new
|
|
1959
|
+
throw new import_sdk_core5.UnsupportedFeatureError("duckdb", this.config.host, features);
|
|
1805
1960
|
}
|
|
1806
1961
|
throw new Error("Not signed in. Call signIn() first.");
|
|
1807
1962
|
}
|
|
@@ -2040,7 +2195,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2040
2195
|
...prepared,
|
|
2041
2196
|
signature
|
|
2042
2197
|
});
|
|
2043
|
-
const activateResult = await (0,
|
|
2198
|
+
const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
2044
2199
|
this.config.host,
|
|
2045
2200
|
delegationSession.delegationHeader
|
|
2046
2201
|
);
|
|
@@ -2067,8 +2222,8 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2067
2222
|
}]);
|
|
2068
2223
|
}
|
|
2069
2224
|
if (this._serviceContext) {
|
|
2070
|
-
const publicKV = new
|
|
2071
|
-
const publicContext = new
|
|
2225
|
+
const publicKV = new import_sdk_core5.KVService({ prefix: "" });
|
|
2226
|
+
const publicContext = new import_sdk_core5.ServiceContext({
|
|
2072
2227
|
invoke: this.wasmBindings.invoke,
|
|
2073
2228
|
fetch: this._serviceContext.fetch,
|
|
2074
2229
|
hosts: this._serviceContext.hosts
|
|
@@ -2153,6 +2308,209 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2153
2308
|
async checkPermission(path, action) {
|
|
2154
2309
|
return this.delegationManager.checkPermission(path, action);
|
|
2155
2310
|
}
|
|
2311
|
+
/**
|
|
2312
|
+
* Issue a delegation using the capability-chain flow.
|
|
2313
|
+
*
|
|
2314
|
+
* When every requested permission is a subset of the current
|
|
2315
|
+
* session's recap, the delegation is signed by the session key via
|
|
2316
|
+
* WASM — no wallet prompt. When at least one is NOT derivable, a
|
|
2317
|
+
* {@link PermissionNotInManifestError} is raised (carrying the
|
|
2318
|
+
* missing entries) so the caller can trigger an escalation flow
|
|
2319
|
+
* (e.g. `TinyCloudWeb.requestPermissions`). Passing
|
|
2320
|
+
* `forceWalletSign: true` bypasses the derivability check and
|
|
2321
|
+
* always uses the wallet-signed SIWE path — used by the legacy
|
|
2322
|
+
* `createDelegation` fallback and by callers that want explicit
|
|
2323
|
+
* wallet confirmation.
|
|
2324
|
+
*
|
|
2325
|
+
* Multi-entry delegations are now emitted as **one** signed UCAN:
|
|
2326
|
+
* the underlying WASM `createDelegation` takes a full
|
|
2327
|
+
* `HashMap<Service, HashMap<Path, Vec<Ability>>>` abilities map
|
|
2328
|
+
* and produces a single attenuation carrying every
|
|
2329
|
+
* `(service, path, actions)` entry. The returned
|
|
2330
|
+
* {@link DelegateToResult.delegation} is that single blob, and
|
|
2331
|
+
* apps can POST it to their backend exactly like a single-entry
|
|
2332
|
+
* delegation (the server verifies all granted resources from one
|
|
2333
|
+
* UCAN).
|
|
2334
|
+
*
|
|
2335
|
+
* For single-entry requests the `PortableDelegation.path` and
|
|
2336
|
+
* `.actions` fields mirror the one granted entry. For
|
|
2337
|
+
* multi-entry requests they mirror the **first** entry (stable
|
|
2338
|
+
* lexicographic order from the Rust side); consumers that need
|
|
2339
|
+
* the full picture read `PortableDelegation.resources`.
|
|
2340
|
+
*
|
|
2341
|
+
* @throws {@link SessionExpiredError} when there is no session or
|
|
2342
|
+
* the current session has expired (or will within the 60s
|
|
2343
|
+
* safety margin).
|
|
2344
|
+
* @throws {@link PermissionNotInManifestError} when any requested
|
|
2345
|
+
* entry is not a subset of the granted session capabilities and
|
|
2346
|
+
* `forceWalletSign` is not set.
|
|
2347
|
+
*/
|
|
2348
|
+
async delegateTo(did, permissions, options) {
|
|
2349
|
+
const session = this.auth?.tinyCloudSession;
|
|
2350
|
+
if (!session) {
|
|
2351
|
+
throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2352
|
+
}
|
|
2353
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
2354
|
+
if (sessionExpiry !== void 0) {
|
|
2355
|
+
const now2 = Date.now();
|
|
2356
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2357
|
+
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
2358
|
+
throw new import_sdk_core5.SessionExpiredError(sessionExpiry);
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
2362
|
+
throw new Error(
|
|
2363
|
+
"delegateTo requires a non-empty permissions array"
|
|
2364
|
+
);
|
|
2365
|
+
}
|
|
2366
|
+
const expandedEntries = permissions.map((entry) => ({
|
|
2367
|
+
...entry,
|
|
2368
|
+
actions: (0, import_sdk_core5.expandActionShortNames)(entry.service, entry.actions)
|
|
2369
|
+
}));
|
|
2370
|
+
const now = /* @__PURE__ */ new Date();
|
|
2371
|
+
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
2372
|
+
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
2373
|
+
let effectiveExpiration = expirationTime;
|
|
2374
|
+
if (sessionExpiry !== void 0 && sessionExpiry < expirationTime) {
|
|
2375
|
+
effectiveExpiration = sessionExpiry;
|
|
2376
|
+
}
|
|
2377
|
+
if (options?.forceWalletSign) {
|
|
2378
|
+
if (expandedEntries.length > 1) {
|
|
2379
|
+
throw new Error(
|
|
2380
|
+
"delegateTo with forceWalletSign=true supports at most one PermissionEntry. Multi-entry requests must go through the session-key UCAN path (drop forceWalletSign) or the legacy createDelegation method."
|
|
2381
|
+
);
|
|
2382
|
+
}
|
|
2383
|
+
const delegation2 = await this.createDelegationLegacyWalletPath(
|
|
2384
|
+
did,
|
|
2385
|
+
expandedEntries[0],
|
|
2386
|
+
effectiveExpiration
|
|
2387
|
+
);
|
|
2388
|
+
return { delegation: delegation2, prompted: true };
|
|
2389
|
+
}
|
|
2390
|
+
const granted = (0, import_sdk_core5.parseRecapCapabilities)(
|
|
2391
|
+
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
2392
|
+
session.siwe
|
|
2393
|
+
);
|
|
2394
|
+
const { subset, missing } = (0, import_sdk_core5.isCapabilitySubset)(expandedEntries, granted);
|
|
2395
|
+
if (!subset) {
|
|
2396
|
+
throw new import_sdk_core5.PermissionNotInManifestError(missing, granted);
|
|
2397
|
+
}
|
|
2398
|
+
const delegation = await this.createDelegationViaWasmPath(
|
|
2399
|
+
did,
|
|
2400
|
+
expandedEntries,
|
|
2401
|
+
effectiveExpiration,
|
|
2402
|
+
session
|
|
2403
|
+
);
|
|
2404
|
+
return { delegation, prompted: false };
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Issue a delegation via the session-key UCAN WASM path.
|
|
2408
|
+
*
|
|
2409
|
+
* The caller has already verified every entry is derivable from
|
|
2410
|
+
* the current session; we build one multi-resource abilities map
|
|
2411
|
+
* and emit one signed UCAN covering them all.
|
|
2412
|
+
*
|
|
2413
|
+
* All entries must share the same target space (the UCAN is
|
|
2414
|
+
* scoped to a single space). If they don't, this throws — mixing
|
|
2415
|
+
* spaces in a single delegation is not supported by the underlying
|
|
2416
|
+
* Rust create_delegation call and the resulting UCAN would be
|
|
2417
|
+
* under-specified.
|
|
2418
|
+
*
|
|
2419
|
+
* @internal
|
|
2420
|
+
*/
|
|
2421
|
+
async createDelegationViaWasmPath(did, entries, expirationTime, session) {
|
|
2422
|
+
if (entries.length === 0) {
|
|
2423
|
+
throw new Error(
|
|
2424
|
+
"createDelegationViaWasmPath requires a non-empty entries array"
|
|
2425
|
+
);
|
|
2426
|
+
}
|
|
2427
|
+
const resolvedSpaces = /* @__PURE__ */ new Set();
|
|
2428
|
+
for (const entry of entries) {
|
|
2429
|
+
const spaceId2 = entry.space === "default" ? session.spaceId : entry.space;
|
|
2430
|
+
resolvedSpaces.add(spaceId2);
|
|
2431
|
+
}
|
|
2432
|
+
if (resolvedSpaces.size !== 1) {
|
|
2433
|
+
throw new Error(
|
|
2434
|
+
`delegateTo: all permission entries must target the same space, got ${resolvedSpaces.size}: ${JSON.stringify([...resolvedSpaces])}`
|
|
2435
|
+
);
|
|
2436
|
+
}
|
|
2437
|
+
const spaceId = [...resolvedSpaces][0];
|
|
2438
|
+
const abilities = {};
|
|
2439
|
+
for (const entry of entries) {
|
|
2440
|
+
const shortService = import_sdk_core5.SERVICE_LONG_TO_SHORT[entry.service];
|
|
2441
|
+
if (shortService === void 0) {
|
|
2442
|
+
throw new Error(
|
|
2443
|
+
`delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
if (abilities[shortService] === void 0) {
|
|
2447
|
+
abilities[shortService] = {};
|
|
2448
|
+
}
|
|
2449
|
+
const pathsMap = abilities[shortService];
|
|
2450
|
+
const existing = pathsMap[entry.path];
|
|
2451
|
+
if (existing === void 0) {
|
|
2452
|
+
pathsMap[entry.path] = [...entry.actions];
|
|
2453
|
+
} else {
|
|
2454
|
+
const seen = new Set(existing);
|
|
2455
|
+
for (const action of entry.actions) {
|
|
2456
|
+
if (!seen.has(action)) {
|
|
2457
|
+
existing.push(action);
|
|
2458
|
+
seen.add(action);
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
const serviceSession = {
|
|
2464
|
+
delegationHeader: session.delegationHeader,
|
|
2465
|
+
delegationCid: session.delegationCid,
|
|
2466
|
+
jwk: session.jwk,
|
|
2467
|
+
spaceId,
|
|
2468
|
+
verificationMethod: session.verificationMethod
|
|
2469
|
+
};
|
|
2470
|
+
const expirationSecs = Math.floor(expirationTime.getTime() / 1e3);
|
|
2471
|
+
const result = this.createDelegationWrapper({
|
|
2472
|
+
session: serviceSession,
|
|
2473
|
+
delegateDID: did,
|
|
2474
|
+
spaceId,
|
|
2475
|
+
abilities,
|
|
2476
|
+
expirationSecs
|
|
2477
|
+
});
|
|
2478
|
+
const primary = result.resources[0];
|
|
2479
|
+
return {
|
|
2480
|
+
cid: result.cid,
|
|
2481
|
+
delegationHeader: { Authorization: `Bearer ${result.delegation}` },
|
|
2482
|
+
spaceId,
|
|
2483
|
+
path: primary.path,
|
|
2484
|
+
actions: primary.actions,
|
|
2485
|
+
resources: result.resources,
|
|
2486
|
+
disableSubDelegation: false,
|
|
2487
|
+
expiry: result.expiry,
|
|
2488
|
+
delegateDID: did,
|
|
2489
|
+
ownerAddress: session.address,
|
|
2490
|
+
chainId: session.chainId,
|
|
2491
|
+
host: this.config.host
|
|
2492
|
+
};
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Issue a delegation via the legacy wallet-signed SIWE path for a single
|
|
2496
|
+
* {@link PermissionEntry}. Shares the implementation with the public
|
|
2497
|
+
* `createDelegation` method via {@link createDelegationWalletPath} so
|
|
2498
|
+
* both entry points hit exactly the same SIWE / signer / public-space
|
|
2499
|
+
* logic without mutual recursion.
|
|
2500
|
+
*
|
|
2501
|
+
* @internal
|
|
2502
|
+
*/
|
|
2503
|
+
async createDelegationLegacyWalletPath(delegateDID, entry, expirationTime) {
|
|
2504
|
+
const spaceIdOverride = entry.space === "default" ? void 0 : entry.space;
|
|
2505
|
+
return this.createDelegationWalletPath({
|
|
2506
|
+
path: entry.path,
|
|
2507
|
+
actions: entry.actions,
|
|
2508
|
+
delegateDID,
|
|
2509
|
+
includePublicSpace: true,
|
|
2510
|
+
expiryMs: Math.max(0, expirationTime.getTime() - Date.now()),
|
|
2511
|
+
spaceIdOverride
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2156
2514
|
/**
|
|
2157
2515
|
* Create a delegation from this user to another user.
|
|
2158
2516
|
*
|
|
@@ -2163,6 +2521,49 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2163
2521
|
* @returns A portable delegation that can be sent to the recipient
|
|
2164
2522
|
*/
|
|
2165
2523
|
async createDelegation(params) {
|
|
2524
|
+
if (!this.signer) {
|
|
2525
|
+
throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
|
|
2526
|
+
}
|
|
2527
|
+
if (!this.auth?.tinyCloudSession) {
|
|
2528
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2529
|
+
}
|
|
2530
|
+
let resolvedDelegateDID = params.delegateDID;
|
|
2531
|
+
if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
2532
|
+
const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
|
|
2533
|
+
if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
|
|
2534
|
+
resolvedDelegateDID = `did:pkh:eip155:1:${address}`;
|
|
2535
|
+
}
|
|
2536
|
+
const entries = legacyParamsToPermissionEntries(
|
|
2537
|
+
params.actions,
|
|
2538
|
+
params.path,
|
|
2539
|
+
params.spaceIdOverride
|
|
2540
|
+
);
|
|
2541
|
+
try {
|
|
2542
|
+
const result = await this.delegateTo(
|
|
2543
|
+
resolvedDelegateDID,
|
|
2544
|
+
entries,
|
|
2545
|
+
params.expiryMs !== void 0 ? { expiry: params.expiryMs } : void 0
|
|
2546
|
+
);
|
|
2547
|
+
return result.delegation;
|
|
2548
|
+
} catch (err) {
|
|
2549
|
+
if (err instanceof import_sdk_core5.PermissionNotInManifestError) {
|
|
2550
|
+
} else {
|
|
2551
|
+
throw err;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
return this.createDelegationWalletPath({
|
|
2555
|
+
...params,
|
|
2556
|
+
delegateDID: resolvedDelegateDID
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Legacy wallet-signed SIWE delegation path. Lifted from the original
|
|
2561
|
+
* `createDelegation` body verbatim so both the legacy public method and
|
|
2562
|
+
* `delegateTo({ forceWalletSign: true })` hit the same code.
|
|
2563
|
+
*
|
|
2564
|
+
* @internal
|
|
2565
|
+
*/
|
|
2566
|
+
async createDelegationWalletPath(params) {
|
|
2166
2567
|
if (!this.signer) {
|
|
2167
2568
|
throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
|
|
2168
2569
|
}
|
|
@@ -2170,11 +2571,6 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2170
2571
|
if (!session) {
|
|
2171
2572
|
throw new Error("Not signed in. Call signIn() first.");
|
|
2172
2573
|
}
|
|
2173
|
-
if (params.delegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
2174
|
-
const address = await this.config.ensResolver.resolveAddress(params.delegateDID);
|
|
2175
|
-
if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);
|
|
2176
|
-
params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };
|
|
2177
|
-
}
|
|
2178
2574
|
const abilities = {};
|
|
2179
2575
|
const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
|
|
2180
2576
|
const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
|
|
@@ -2207,7 +2603,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2207
2603
|
...prepared,
|
|
2208
2604
|
signature
|
|
2209
2605
|
});
|
|
2210
|
-
const activateResult = await (0,
|
|
2606
|
+
const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
2211
2607
|
this.config.host,
|
|
2212
2608
|
delegationSession.delegationHeader
|
|
2213
2609
|
);
|
|
@@ -2229,7 +2625,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2229
2625
|
};
|
|
2230
2626
|
const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
|
|
2231
2627
|
if (hasKvActions && params.includePublicSpace !== false) {
|
|
2232
|
-
const publicSpaceId = (0,
|
|
2628
|
+
const publicSpaceId = (0, import_sdk_core5.makePublicSpaceId)(
|
|
2233
2629
|
this.wasmBindings.ensureEip55(session.address),
|
|
2234
2630
|
session.chainId
|
|
2235
2631
|
);
|
|
@@ -2252,7 +2648,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2252
2648
|
...publicPrepared,
|
|
2253
2649
|
signature: publicSignature
|
|
2254
2650
|
});
|
|
2255
|
-
const publicActivateResult = await (0,
|
|
2651
|
+
const publicActivateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
2256
2652
|
this.config.host,
|
|
2257
2653
|
publicSession.delegationHeader
|
|
2258
2654
|
);
|
|
@@ -2351,7 +2747,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2351
2747
|
...prepared,
|
|
2352
2748
|
signature
|
|
2353
2749
|
});
|
|
2354
|
-
const activateResult = await (0,
|
|
2750
|
+
const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
2355
2751
|
targetHost,
|
|
2356
2752
|
invokerSession.delegationHeader
|
|
2357
2753
|
);
|
|
@@ -2440,7 +2836,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2440
2836
|
...prepared,
|
|
2441
2837
|
signature
|
|
2442
2838
|
});
|
|
2443
|
-
const activateResult = await (0,
|
|
2839
|
+
const activateResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
2444
2840
|
targetHost,
|
|
2445
2841
|
subDelegationSession.delegationHeader
|
|
2446
2842
|
);
|
|
@@ -2462,6 +2858,21 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
2462
2858
|
};
|
|
2463
2859
|
}
|
|
2464
2860
|
};
|
|
2861
|
+
// ===========================================================================
|
|
2862
|
+
// Capability-chain delegation (spec: .claude/specs/capability-chain.md)
|
|
2863
|
+
// ===========================================================================
|
|
2864
|
+
/**
|
|
2865
|
+
* Safety margin before the session's own expiry at which {@link delegateTo}
|
|
2866
|
+
* will refuse to issue a derived delegation. Prevents issuing sub-delegations
|
|
2867
|
+
* that would be invalid by the time the recipient used them. Spec: 60 seconds.
|
|
2868
|
+
*
|
|
2869
|
+
* @internal
|
|
2870
|
+
*/
|
|
2871
|
+
_TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
2872
|
+
var TinyCloudNode = _TinyCloudNode;
|
|
2873
|
+
|
|
2874
|
+
// src/core.ts
|
|
2875
|
+
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
2465
2876
|
|
|
2466
2877
|
// src/delegation.ts
|
|
2467
2878
|
function serializeDelegation(delegation) {
|
|
@@ -2480,8 +2891,6 @@ function deserializeDelegation(data) {
|
|
|
2480
2891
|
}
|
|
2481
2892
|
|
|
2482
2893
|
// src/core.ts
|
|
2483
|
-
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
2484
|
-
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
2485
2894
|
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
2486
2895
|
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
2487
2896
|
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
@@ -2489,6 +2898,8 @@ var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
|
2489
2898
|
var import_sdk_core13 = require("@tinycloud/sdk-core");
|
|
2490
2899
|
var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
2491
2900
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
2901
|
+
var import_sdk_core16 = require("@tinycloud/sdk-core");
|
|
2902
|
+
var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
2492
2903
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2493
2904
|
0 && (module.exports = {
|
|
2494
2905
|
AutoApproveSpaceCreationHandler,
|
|
@@ -2504,13 +2915,16 @@ var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
|
2504
2915
|
DuckDbService,
|
|
2505
2916
|
FileSessionStorage,
|
|
2506
2917
|
KVService,
|
|
2918
|
+
ManifestValidationError,
|
|
2507
2919
|
MemorySessionStorage,
|
|
2508
2920
|
NodeUserAuthorization,
|
|
2921
|
+
PermissionNotInManifestError,
|
|
2509
2922
|
PrefixedKVService,
|
|
2510
2923
|
ProtocolMismatchError,
|
|
2511
2924
|
SQLAction,
|
|
2512
2925
|
SQLService,
|
|
2513
2926
|
ServiceContext,
|
|
2927
|
+
SessionExpiredError,
|
|
2514
2928
|
SharingService,
|
|
2515
2929
|
SilentNotificationHandler,
|
|
2516
2930
|
Space,
|
|
@@ -2533,8 +2947,14 @@ var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
|
2533
2947
|
defaultSignStrategy,
|
|
2534
2948
|
defaultSpaceCreationHandler,
|
|
2535
2949
|
deserializeDelegation,
|
|
2950
|
+
expandActionShortNames,
|
|
2951
|
+
isCapabilitySubset,
|
|
2952
|
+
loadManifest,
|
|
2536
2953
|
makePublicSpaceId,
|
|
2954
|
+
parseExpiry,
|
|
2537
2955
|
parseSpaceUri,
|
|
2538
|
-
|
|
2956
|
+
resolveManifest,
|
|
2957
|
+
serializeDelegation,
|
|
2958
|
+
validateManifest
|
|
2539
2959
|
});
|
|
2540
2960
|
//# sourceMappingURL=core.cjs.map
|