@tinycloud/node-sdk 2.0.4 → 2.1.0-beta.1
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 +428 -93
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +102 -3
- package/dist/core.d.ts +102 -3
- package/dist/core.js +363 -17
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +435 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +380 -19
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -17030,11 +17030,13 @@ var require_utils2 = __commonJS({
|
|
|
17030
17030
|
// src/NodeWasmBindings.ts
|
|
17031
17031
|
import {
|
|
17032
17032
|
invoke,
|
|
17033
|
+
invokeAny,
|
|
17033
17034
|
prepareSession,
|
|
17034
17035
|
completeSessionSetup,
|
|
17035
17036
|
ensureEip55,
|
|
17036
17037
|
makeSpaceId,
|
|
17037
17038
|
createDelegation,
|
|
17039
|
+
parseRecapFromSiwe,
|
|
17038
17040
|
generateHostSIWEMessage,
|
|
17039
17041
|
siweToDelegationHeaders,
|
|
17040
17042
|
protocolVersion,
|
|
@@ -17051,11 +17053,13 @@ import {
|
|
|
17051
17053
|
var _NodeWasmBindings = class _NodeWasmBindings {
|
|
17052
17054
|
constructor() {
|
|
17053
17055
|
this.invoke = invoke;
|
|
17056
|
+
this.invokeAny = invokeAny;
|
|
17054
17057
|
this.prepareSession = prepareSession;
|
|
17055
17058
|
this.completeSessionSetup = completeSessionSetup;
|
|
17056
17059
|
this.ensureEip55 = ensureEip55;
|
|
17057
17060
|
this.makeSpaceId = makeSpaceId;
|
|
17058
17061
|
this.createDelegation = createDelegation;
|
|
17062
|
+
this.parseRecapFromSiwe = parseRecapFromSiwe;
|
|
17059
17063
|
this.generateHostSIWEMessage = generateHostSIWEMessage;
|
|
17060
17064
|
this.siweToDelegationHeaders = siweToDelegationHeaders;
|
|
17061
17065
|
this.protocolVersion = protocolVersion;
|
|
@@ -17153,6 +17157,7 @@ import {
|
|
|
17153
17157
|
KVService as KVService2,
|
|
17154
17158
|
SQLService as SQLService2,
|
|
17155
17159
|
DuckDbService as DuckDbService2,
|
|
17160
|
+
HooksService as HooksService2,
|
|
17156
17161
|
DataVaultService,
|
|
17157
17162
|
createVaultCrypto,
|
|
17158
17163
|
ServiceContext as ServiceContext2,
|
|
@@ -17162,7 +17167,12 @@ import {
|
|
|
17162
17167
|
CapabilityKeyRegistry,
|
|
17163
17168
|
SharingService,
|
|
17164
17169
|
UnsupportedFeatureError,
|
|
17165
|
-
makePublicSpaceId
|
|
17170
|
+
makePublicSpaceId,
|
|
17171
|
+
PermissionNotInManifestError,
|
|
17172
|
+
SessionExpiredError,
|
|
17173
|
+
expandActionShortNames,
|
|
17174
|
+
isCapabilitySubset,
|
|
17175
|
+
parseRecapCapabilities
|
|
17166
17176
|
} from "@tinycloud/sdk-core";
|
|
17167
17177
|
|
|
17168
17178
|
// src/authorization/NodeUserAuthorization.ts
|
|
@@ -17292,12 +17302,22 @@ var NodeUserAuthorization = class {
|
|
|
17292
17302
|
},
|
|
17293
17303
|
capabilities: {
|
|
17294
17304
|
"": ["tinycloud.capabilities/read"]
|
|
17305
|
+
},
|
|
17306
|
+
hooks: {
|
|
17307
|
+
"": [
|
|
17308
|
+
"tinycloud.hooks/subscribe",
|
|
17309
|
+
"tinycloud.hooks/register",
|
|
17310
|
+
"tinycloud.hooks/list",
|
|
17311
|
+
"tinycloud.hooks/unregister"
|
|
17312
|
+
]
|
|
17295
17313
|
}
|
|
17296
17314
|
};
|
|
17297
17315
|
this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
|
|
17298
17316
|
this.autoCreateSpace = config.autoCreateSpace ?? false;
|
|
17299
17317
|
this.spaceCreationHandler = config.spaceCreationHandler;
|
|
17300
|
-
this.tinycloudHosts = config.tinycloudHosts ?? [
|
|
17318
|
+
this.tinycloudHosts = config.tinycloudHosts ?? [
|
|
17319
|
+
"https://node.tinycloud.xyz"
|
|
17320
|
+
];
|
|
17301
17321
|
this.enablePublicSpace = config.enablePublicSpace ?? true;
|
|
17302
17322
|
this.nonce = config.nonce;
|
|
17303
17323
|
this.siweConfig = config.siweConfig;
|
|
@@ -17437,7 +17457,10 @@ var NodeUserAuthorization = class {
|
|
|
17437
17457
|
throw err;
|
|
17438
17458
|
}
|
|
17439
17459
|
} catch (error) {
|
|
17440
|
-
handler.onSpaceCreationFailed?.(
|
|
17460
|
+
handler.onSpaceCreationFailed?.(
|
|
17461
|
+
creationContext,
|
|
17462
|
+
error instanceof Error ? error : new Error(String(error))
|
|
17463
|
+
);
|
|
17441
17464
|
throw error;
|
|
17442
17465
|
}
|
|
17443
17466
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -17471,7 +17494,10 @@ var NodeUserAuthorization = class {
|
|
|
17471
17494
|
throw err;
|
|
17472
17495
|
}
|
|
17473
17496
|
} catch (error) {
|
|
17474
|
-
handler.onSpaceCreationFailed?.(
|
|
17497
|
+
handler.onSpaceCreationFailed?.(
|
|
17498
|
+
creationContext,
|
|
17499
|
+
error instanceof Error ? error : new Error(String(error))
|
|
17500
|
+
);
|
|
17475
17501
|
throw error;
|
|
17476
17502
|
}
|
|
17477
17503
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -17580,7 +17606,10 @@ var NodeUserAuthorization = class {
|
|
|
17580
17606
|
this._tinyCloudSession = tinyCloudSession;
|
|
17581
17607
|
this._address = address;
|
|
17582
17608
|
this._chainId = chainId;
|
|
17583
|
-
const nodeInfo = await checkNodeInfo(
|
|
17609
|
+
const nodeInfo = await checkNodeInfo(
|
|
17610
|
+
this.tinycloudHosts[0],
|
|
17611
|
+
this.wasm.protocolVersion()
|
|
17612
|
+
);
|
|
17584
17613
|
this._nodeFeatures = nodeInfo.features;
|
|
17585
17614
|
for (const ext of this.extensions) {
|
|
17586
17615
|
if (ext.afterSignIn) {
|
|
@@ -17740,7 +17769,10 @@ var NodeUserAuthorization = class {
|
|
|
17740
17769
|
this._tinyCloudSession = tinyCloudSession;
|
|
17741
17770
|
this._address = address;
|
|
17742
17771
|
this._chainId = chainId;
|
|
17743
|
-
const nodeInfo = await checkNodeInfo(
|
|
17772
|
+
const nodeInfo = await checkNodeInfo(
|
|
17773
|
+
this.tinycloudHosts[0],
|
|
17774
|
+
this.wasm.protocolVersion()
|
|
17775
|
+
);
|
|
17744
17776
|
this._nodeFeatures = nodeInfo.features;
|
|
17745
17777
|
for (const ext of this.extensions) {
|
|
17746
17778
|
if (ext.afterSignIn) {
|
|
@@ -17791,7 +17823,9 @@ var NodeUserAuthorization = class {
|
|
|
17791
17823
|
);
|
|
17792
17824
|
}
|
|
17793
17825
|
default:
|
|
17794
|
-
throw new Error(
|
|
17826
|
+
throw new Error(
|
|
17827
|
+
`Unknown sign strategy: ${this.signStrategy.type}`
|
|
17828
|
+
);
|
|
17795
17829
|
}
|
|
17796
17830
|
}
|
|
17797
17831
|
/**
|
|
@@ -17821,6 +17855,7 @@ var NodeUserAuthorization = class {
|
|
|
17821
17855
|
// src/DelegatedAccess.ts
|
|
17822
17856
|
import {
|
|
17823
17857
|
KVService,
|
|
17858
|
+
HooksService,
|
|
17824
17859
|
SQLService,
|
|
17825
17860
|
DuckDbService,
|
|
17826
17861
|
ServiceContext
|
|
@@ -17845,6 +17880,9 @@ var DelegatedAccess = class {
|
|
|
17845
17880
|
this._duckdb = new DuckDbService({});
|
|
17846
17881
|
this._duckdb.initialize(this._serviceContext);
|
|
17847
17882
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
17883
|
+
this._hooks = new HooksService({});
|
|
17884
|
+
this._hooks.initialize(this._serviceContext);
|
|
17885
|
+
this._serviceContext.registerService("hooks", this._hooks);
|
|
17848
17886
|
const serviceSession = {
|
|
17849
17887
|
delegationHeader: session.delegationHeader,
|
|
17850
17888
|
delegationCid: session.delegationCid,
|
|
@@ -17890,6 +17928,12 @@ var DelegatedAccess = class {
|
|
|
17890
17928
|
get duckdb() {
|
|
17891
17929
|
return this._duckdb;
|
|
17892
17930
|
}
|
|
17931
|
+
/**
|
|
17932
|
+
* Hooks write-stream subscriptions on the delegated space.
|
|
17933
|
+
*/
|
|
17934
|
+
get hooks() {
|
|
17935
|
+
return this._hooks;
|
|
17936
|
+
}
|
|
17893
17937
|
};
|
|
17894
17938
|
|
|
17895
17939
|
// src/keys/WasmKeyProvider.ts
|
|
@@ -17967,9 +18011,72 @@ function createWasmKeyProvider(sessionManager) {
|
|
|
17967
18011
|
return new WasmKeyProvider({ sessionManager });
|
|
17968
18012
|
}
|
|
17969
18013
|
|
|
18014
|
+
// src/delegateToHelpers.ts
|
|
18015
|
+
import {
|
|
18016
|
+
parseExpiry,
|
|
18017
|
+
SiweMessage
|
|
18018
|
+
} from "@tinycloud/sdk-core";
|
|
18019
|
+
function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
18020
|
+
const byService = /* @__PURE__ */ new Map();
|
|
18021
|
+
for (const a of actions) {
|
|
18022
|
+
const slashIdx = a.indexOf("/");
|
|
18023
|
+
if (slashIdx === -1) {
|
|
18024
|
+
continue;
|
|
18025
|
+
}
|
|
18026
|
+
const service = a.slice(0, slashIdx);
|
|
18027
|
+
if (!service.startsWith("tinycloud.")) {
|
|
18028
|
+
continue;
|
|
18029
|
+
}
|
|
18030
|
+
const list = byService.get(service);
|
|
18031
|
+
if (list === void 0) {
|
|
18032
|
+
byService.set(service, [a]);
|
|
18033
|
+
} else {
|
|
18034
|
+
list.push(a);
|
|
18035
|
+
}
|
|
18036
|
+
}
|
|
18037
|
+
const space = spaceIdOverride ?? "default";
|
|
18038
|
+
const entries = [];
|
|
18039
|
+
for (const [service, actionList] of byService) {
|
|
18040
|
+
entries.push({
|
|
18041
|
+
service,
|
|
18042
|
+
space,
|
|
18043
|
+
path,
|
|
18044
|
+
actions: actionList
|
|
18045
|
+
});
|
|
18046
|
+
}
|
|
18047
|
+
return entries;
|
|
18048
|
+
}
|
|
18049
|
+
function resolveExpiryMs(expiry) {
|
|
18050
|
+
if (expiry === void 0) {
|
|
18051
|
+
return 60 * 60 * 1e3;
|
|
18052
|
+
}
|
|
18053
|
+
if (typeof expiry === "number") {
|
|
18054
|
+
if (!Number.isFinite(expiry) || expiry <= 0) {
|
|
18055
|
+
throw new Error(
|
|
18056
|
+
`delegateTo expiry must be a positive finite number (got ${expiry})`
|
|
18057
|
+
);
|
|
18058
|
+
}
|
|
18059
|
+
return expiry;
|
|
18060
|
+
}
|
|
18061
|
+
return parseExpiry(expiry);
|
|
18062
|
+
}
|
|
18063
|
+
function extractSiweExpiration(siwe) {
|
|
18064
|
+
const parsed = new SiweMessage(siwe);
|
|
18065
|
+
if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
|
|
18066
|
+
return void 0;
|
|
18067
|
+
}
|
|
18068
|
+
const d = new Date(parsed.expirationTime);
|
|
18069
|
+
if (Number.isNaN(d.getTime())) {
|
|
18070
|
+
throw new Error(
|
|
18071
|
+
`Session SIWE has unparseable expirationTime: ${parsed.expirationTime}`
|
|
18072
|
+
);
|
|
18073
|
+
}
|
|
18074
|
+
return d;
|
|
18075
|
+
}
|
|
18076
|
+
|
|
17970
18077
|
// src/TinyCloudNode.ts
|
|
17971
18078
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
17972
|
-
var
|
|
18079
|
+
var _TinyCloudNode = class _TinyCloudNode {
|
|
17973
18080
|
/**
|
|
17974
18081
|
* Create a new TinyCloudNode instance.
|
|
17975
18082
|
*
|
|
@@ -18095,7 +18202,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18095
18202
|
nonce: config.nonce,
|
|
18096
18203
|
siweConfig: config.siweConfig
|
|
18097
18204
|
});
|
|
18098
|
-
this.tc = new TinyCloud(this.auth
|
|
18205
|
+
this.tc = new TinyCloud(this.auth, {
|
|
18206
|
+
invokeAny: this.wasmBindings.invokeAny
|
|
18207
|
+
});
|
|
18099
18208
|
}
|
|
18100
18209
|
/**
|
|
18101
18210
|
* Get the primary identity DID for this user.
|
|
@@ -18164,6 +18273,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18164
18273
|
this._kv = void 0;
|
|
18165
18274
|
this._sql = void 0;
|
|
18166
18275
|
this._duckdb = void 0;
|
|
18276
|
+
this._hooks = void 0;
|
|
18167
18277
|
this._serviceContext = void 0;
|
|
18168
18278
|
await this.tc.signIn();
|
|
18169
18279
|
this.initializeServices();
|
|
@@ -18183,6 +18293,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18183
18293
|
this._kv = void 0;
|
|
18184
18294
|
this._sql = void 0;
|
|
18185
18295
|
this._duckdb = void 0;
|
|
18296
|
+
this._hooks = void 0;
|
|
18186
18297
|
this._serviceContext = void 0;
|
|
18187
18298
|
if (sessionData.address) {
|
|
18188
18299
|
this._address = sessionData.address;
|
|
@@ -18192,6 +18303,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18192
18303
|
}
|
|
18193
18304
|
this._serviceContext = new ServiceContext2({
|
|
18194
18305
|
invoke: this.wasmBindings.invoke,
|
|
18306
|
+
invokeAny: this.wasmBindings.invokeAny,
|
|
18195
18307
|
fetch: globalThis.fetch.bind(globalThis),
|
|
18196
18308
|
hosts: [this.config.host]
|
|
18197
18309
|
});
|
|
@@ -18204,6 +18316,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18204
18316
|
this._duckdb = new DuckDbService2({});
|
|
18205
18317
|
this._duckdb.initialize(this._serviceContext);
|
|
18206
18318
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
18319
|
+
this._hooks = new HooksService2({});
|
|
18320
|
+
this._hooks.initialize(this._serviceContext);
|
|
18321
|
+
this._serviceContext.registerService("hooks", this._hooks);
|
|
18207
18322
|
const serviceSession = {
|
|
18208
18323
|
delegationHeader: sessionData.delegationHeader,
|
|
18209
18324
|
delegationCid: sessionData.delegationCid,
|
|
@@ -18303,7 +18418,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18303
18418
|
nonce: this.config.nonce,
|
|
18304
18419
|
siweConfig: this.config.siweConfig
|
|
18305
18420
|
});
|
|
18306
|
-
this.tc = new TinyCloud(this.auth
|
|
18421
|
+
this.tc = new TinyCloud(this.auth, {
|
|
18422
|
+
invokeAny: this.wasmBindings.invokeAny
|
|
18423
|
+
});
|
|
18307
18424
|
this.config.prefix = prefix;
|
|
18308
18425
|
}
|
|
18309
18426
|
/**
|
|
@@ -18341,7 +18458,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18341
18458
|
nonce: this.config.nonce,
|
|
18342
18459
|
siweConfig: this.config.siweConfig
|
|
18343
18460
|
});
|
|
18344
|
-
this.tc = new TinyCloud(this.auth
|
|
18461
|
+
this.tc = new TinyCloud(this.auth, {
|
|
18462
|
+
invokeAny: this.wasmBindings.invokeAny
|
|
18463
|
+
});
|
|
18345
18464
|
this.config.prefix = prefix;
|
|
18346
18465
|
}
|
|
18347
18466
|
/**
|
|
@@ -18356,6 +18475,7 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18356
18475
|
this.tc.initializeServices(this.wasmBindings.invoke, [this.config.host]);
|
|
18357
18476
|
this._serviceContext = new ServiceContext2({
|
|
18358
18477
|
invoke: this.wasmBindings.invoke,
|
|
18478
|
+
invokeAny: this.wasmBindings.invokeAny,
|
|
18359
18479
|
fetch: globalThis.fetch.bind(globalThis),
|
|
18360
18480
|
hosts: [this.config.host]
|
|
18361
18481
|
});
|
|
@@ -18373,6 +18493,9 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18373
18493
|
this._duckdb.initialize(this._serviceContext);
|
|
18374
18494
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
18375
18495
|
}
|
|
18496
|
+
this._hooks = new HooksService2({});
|
|
18497
|
+
this._hooks.initialize(this._serviceContext);
|
|
18498
|
+
this._serviceContext.registerService("hooks", this._hooks);
|
|
18376
18499
|
const serviceSession = {
|
|
18377
18500
|
delegationHeader: session.delegationHeader,
|
|
18378
18501
|
delegationCid: session.delegationCid,
|
|
@@ -18751,6 +18874,15 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
18751
18874
|
}
|
|
18752
18875
|
return this._vault;
|
|
18753
18876
|
}
|
|
18877
|
+
/**
|
|
18878
|
+
* Hooks write stream subscription API.
|
|
18879
|
+
*/
|
|
18880
|
+
get hooks() {
|
|
18881
|
+
if (!this._hooks) {
|
|
18882
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
18883
|
+
}
|
|
18884
|
+
return this._hooks;
|
|
18885
|
+
}
|
|
18754
18886
|
// ===========================================================================
|
|
18755
18887
|
// v2 Service Accessors
|
|
18756
18888
|
// ===========================================================================
|
|
@@ -19078,6 +19210,150 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
19078
19210
|
async checkPermission(path, action) {
|
|
19079
19211
|
return this.delegationManager.checkPermission(path, action);
|
|
19080
19212
|
}
|
|
19213
|
+
/**
|
|
19214
|
+
* Issue a delegation using the capability-chain flow.
|
|
19215
|
+
*
|
|
19216
|
+
* When the requested permissions are a subset of the current session's
|
|
19217
|
+
* recap, the delegation is signed by the session key via WASM — no wallet
|
|
19218
|
+
* prompt. When they are not, a {@link PermissionNotInManifestError} is
|
|
19219
|
+
* raised so the caller can trigger an escalation flow (e.g.
|
|
19220
|
+
* `TinyCloudWeb.requestPermissions`). Passing `forceWalletSign: true`
|
|
19221
|
+
* bypasses the derivability check and always uses the wallet-signed SIWE
|
|
19222
|
+
* path — used by the legacy `createDelegation` fallback and by callers
|
|
19223
|
+
* that want explicit wallet confirmation.
|
|
19224
|
+
*
|
|
19225
|
+
* Current limitation: exactly one {@link PermissionEntry} per call. For
|
|
19226
|
+
* multi-resource delegation, call `delegateTo` multiple times. This keeps
|
|
19227
|
+
* each delegation a single `(spaceId, path)` grant, which matches the
|
|
19228
|
+
* underlying `PortableDelegation` shape.
|
|
19229
|
+
*
|
|
19230
|
+
* @throws {@link SessionExpiredError} when there is no session or the
|
|
19231
|
+
* current session has expired (or will within the 60s safety margin).
|
|
19232
|
+
* @throws {@link PermissionNotInManifestError} when the requested entries
|
|
19233
|
+
* are not a subset of the granted session capabilities and
|
|
19234
|
+
* `forceWalletSign` is not set.
|
|
19235
|
+
*/
|
|
19236
|
+
async delegateTo(did, permissions, options) {
|
|
19237
|
+
const session = this.auth?.tinyCloudSession;
|
|
19238
|
+
if (!session) {
|
|
19239
|
+
throw new SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19240
|
+
}
|
|
19241
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
19242
|
+
if (sessionExpiry !== void 0) {
|
|
19243
|
+
const now2 = Date.now();
|
|
19244
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
19245
|
+
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
19246
|
+
throw new SessionExpiredError(sessionExpiry);
|
|
19247
|
+
}
|
|
19248
|
+
}
|
|
19249
|
+
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
19250
|
+
throw new Error(
|
|
19251
|
+
"delegateTo requires a non-empty permissions array"
|
|
19252
|
+
);
|
|
19253
|
+
}
|
|
19254
|
+
if (permissions.length > 1) {
|
|
19255
|
+
throw new Error(
|
|
19256
|
+
"delegateTo currently supports one permission entry per call. Call delegateTo multiple times for multi-resource delegation."
|
|
19257
|
+
);
|
|
19258
|
+
}
|
|
19259
|
+
const entry = permissions[0];
|
|
19260
|
+
const expandedEntry = {
|
|
19261
|
+
...entry,
|
|
19262
|
+
actions: expandActionShortNames(entry.service, entry.actions)
|
|
19263
|
+
};
|
|
19264
|
+
const now = /* @__PURE__ */ new Date();
|
|
19265
|
+
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
19266
|
+
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
19267
|
+
let effectiveExpiration = expirationTime;
|
|
19268
|
+
if (sessionExpiry !== void 0 && sessionExpiry < expirationTime) {
|
|
19269
|
+
effectiveExpiration = sessionExpiry;
|
|
19270
|
+
}
|
|
19271
|
+
if (options?.forceWalletSign) {
|
|
19272
|
+
const delegation2 = await this.createDelegationLegacyWalletPath(
|
|
19273
|
+
did,
|
|
19274
|
+
expandedEntry,
|
|
19275
|
+
effectiveExpiration
|
|
19276
|
+
);
|
|
19277
|
+
return { delegation: delegation2, prompted: true };
|
|
19278
|
+
}
|
|
19279
|
+
const granted = parseRecapCapabilities(
|
|
19280
|
+
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
19281
|
+
session.siwe
|
|
19282
|
+
);
|
|
19283
|
+
const requested = [expandedEntry];
|
|
19284
|
+
const { subset, missing } = isCapabilitySubset(requested, granted);
|
|
19285
|
+
if (!subset) {
|
|
19286
|
+
throw new PermissionNotInManifestError(missing, granted);
|
|
19287
|
+
}
|
|
19288
|
+
const delegation = await this.createDelegationViaWasmPath(
|
|
19289
|
+
did,
|
|
19290
|
+
expandedEntry,
|
|
19291
|
+
effectiveExpiration,
|
|
19292
|
+
session
|
|
19293
|
+
);
|
|
19294
|
+
return { delegation, prompted: false };
|
|
19295
|
+
}
|
|
19296
|
+
/**
|
|
19297
|
+
* Issue a delegation via the session-key UCAN WASM path.
|
|
19298
|
+
*
|
|
19299
|
+
* The caller has already verified the request is derivable from the
|
|
19300
|
+
* current session; we just need to shape the inputs for
|
|
19301
|
+
* {@link createDelegationWrapper}.
|
|
19302
|
+
*
|
|
19303
|
+
* @internal
|
|
19304
|
+
*/
|
|
19305
|
+
async createDelegationViaWasmPath(did, entry, expirationTime, session) {
|
|
19306
|
+
const spaceId = entry.space === "default" ? session.spaceId : entry.space;
|
|
19307
|
+
const serviceSession = {
|
|
19308
|
+
delegationHeader: session.delegationHeader,
|
|
19309
|
+
delegationCid: session.delegationCid,
|
|
19310
|
+
jwk: session.jwk,
|
|
19311
|
+
spaceId,
|
|
19312
|
+
verificationMethod: session.verificationMethod
|
|
19313
|
+
};
|
|
19314
|
+
const expirationSecs = Math.floor(expirationTime.getTime() / 1e3);
|
|
19315
|
+
const result = this.createDelegationWrapper({
|
|
19316
|
+
session: serviceSession,
|
|
19317
|
+
delegateDID: did,
|
|
19318
|
+
spaceId,
|
|
19319
|
+
path: entry.path,
|
|
19320
|
+
actions: entry.actions,
|
|
19321
|
+
expirationSecs
|
|
19322
|
+
});
|
|
19323
|
+
return {
|
|
19324
|
+
cid: result.cid,
|
|
19325
|
+
delegationHeader: { Authorization: `Bearer ${result.delegation}` },
|
|
19326
|
+
spaceId,
|
|
19327
|
+
path: entry.path,
|
|
19328
|
+
actions: entry.actions,
|
|
19329
|
+
disableSubDelegation: false,
|
|
19330
|
+
expiry: result.expiry,
|
|
19331
|
+
delegateDID: did,
|
|
19332
|
+
ownerAddress: session.address,
|
|
19333
|
+
chainId: session.chainId,
|
|
19334
|
+
host: this.config.host
|
|
19335
|
+
};
|
|
19336
|
+
}
|
|
19337
|
+
/**
|
|
19338
|
+
* Issue a delegation via the legacy wallet-signed SIWE path for a single
|
|
19339
|
+
* {@link PermissionEntry}. Shares the implementation with the public
|
|
19340
|
+
* `createDelegation` method via {@link createDelegationWalletPath} so
|
|
19341
|
+
* both entry points hit exactly the same SIWE / signer / public-space
|
|
19342
|
+
* logic without mutual recursion.
|
|
19343
|
+
*
|
|
19344
|
+
* @internal
|
|
19345
|
+
*/
|
|
19346
|
+
async createDelegationLegacyWalletPath(delegateDID, entry, expirationTime) {
|
|
19347
|
+
const spaceIdOverride = entry.space === "default" ? void 0 : entry.space;
|
|
19348
|
+
return this.createDelegationWalletPath({
|
|
19349
|
+
path: entry.path,
|
|
19350
|
+
actions: entry.actions,
|
|
19351
|
+
delegateDID,
|
|
19352
|
+
includePublicSpace: true,
|
|
19353
|
+
expiryMs: Math.max(0, expirationTime.getTime() - Date.now()),
|
|
19354
|
+
spaceIdOverride
|
|
19355
|
+
});
|
|
19356
|
+
}
|
|
19081
19357
|
/**
|
|
19082
19358
|
* Create a delegation from this user to another user.
|
|
19083
19359
|
*
|
|
@@ -19088,6 +19364,51 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
19088
19364
|
* @returns A portable delegation that can be sent to the recipient
|
|
19089
19365
|
*/
|
|
19090
19366
|
async createDelegation(params) {
|
|
19367
|
+
if (!this.signer) {
|
|
19368
|
+
throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
|
|
19369
|
+
}
|
|
19370
|
+
if (!this.auth?.tinyCloudSession) {
|
|
19371
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19372
|
+
}
|
|
19373
|
+
let resolvedDelegateDID = params.delegateDID;
|
|
19374
|
+
if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
19375
|
+
const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
|
|
19376
|
+
if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
|
|
19377
|
+
resolvedDelegateDID = `did:pkh:eip155:1:${address}`;
|
|
19378
|
+
}
|
|
19379
|
+
const entries = legacyParamsToPermissionEntries(
|
|
19380
|
+
params.actions,
|
|
19381
|
+
params.path,
|
|
19382
|
+
params.spaceIdOverride
|
|
19383
|
+
);
|
|
19384
|
+
if (entries.length === 1) {
|
|
19385
|
+
try {
|
|
19386
|
+
const result = await this.delegateTo(
|
|
19387
|
+
resolvedDelegateDID,
|
|
19388
|
+
[entries[0]],
|
|
19389
|
+
params.expiryMs !== void 0 ? { expiry: params.expiryMs } : void 0
|
|
19390
|
+
);
|
|
19391
|
+
return result.delegation;
|
|
19392
|
+
} catch (err) {
|
|
19393
|
+
if (err instanceof PermissionNotInManifestError) {
|
|
19394
|
+
} else {
|
|
19395
|
+
throw err;
|
|
19396
|
+
}
|
|
19397
|
+
}
|
|
19398
|
+
}
|
|
19399
|
+
return this.createDelegationWalletPath({
|
|
19400
|
+
...params,
|
|
19401
|
+
delegateDID: resolvedDelegateDID
|
|
19402
|
+
});
|
|
19403
|
+
}
|
|
19404
|
+
/**
|
|
19405
|
+
* Legacy wallet-signed SIWE delegation path. Lifted from the original
|
|
19406
|
+
* `createDelegation` body verbatim so both the legacy public method and
|
|
19407
|
+
* `delegateTo({ forceWalletSign: true })` hit the same code.
|
|
19408
|
+
*
|
|
19409
|
+
* @internal
|
|
19410
|
+
*/
|
|
19411
|
+
async createDelegationWalletPath(params) {
|
|
19091
19412
|
if (!this.signer) {
|
|
19092
19413
|
throw new Error("Cannot createDelegation() in session-only mode. Requires wallet mode.");
|
|
19093
19414
|
}
|
|
@@ -19095,11 +19416,6 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
19095
19416
|
if (!session) {
|
|
19096
19417
|
throw new Error("Not signed in. Call signIn() first.");
|
|
19097
19418
|
}
|
|
19098
|
-
if (params.delegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
19099
|
-
const address = await this.config.ensResolver.resolveAddress(params.delegateDID);
|
|
19100
|
-
if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);
|
|
19101
|
-
params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };
|
|
19102
|
-
}
|
|
19103
19419
|
const abilities = {};
|
|
19104
19420
|
const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
|
|
19105
19421
|
const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
|
|
@@ -19387,6 +19703,18 @@ var TinyCloudNode = class _TinyCloudNode {
|
|
|
19387
19703
|
};
|
|
19388
19704
|
}
|
|
19389
19705
|
};
|
|
19706
|
+
// ===========================================================================
|
|
19707
|
+
// Capability-chain delegation (spec: .claude/specs/capability-chain.md)
|
|
19708
|
+
// ===========================================================================
|
|
19709
|
+
/**
|
|
19710
|
+
* Safety margin before the session's own expiry at which {@link delegateTo}
|
|
19711
|
+
* will refuse to issue a derived delegation. Prevents issuing sub-delegations
|
|
19712
|
+
* that would be invalid by the time the recipient used them. Spec: 60 seconds.
|
|
19713
|
+
*
|
|
19714
|
+
* @internal
|
|
19715
|
+
*/
|
|
19716
|
+
_TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
19717
|
+
var TinyCloudNode = _TinyCloudNode;
|
|
19390
19718
|
|
|
19391
19719
|
// src/nodeDefaults.ts
|
|
19392
19720
|
TinyCloudNode.registerNodeDefaults({
|
|
@@ -19522,6 +19850,19 @@ var FileSessionStorage = class {
|
|
|
19522
19850
|
}
|
|
19523
19851
|
};
|
|
19524
19852
|
|
|
19853
|
+
// src/index.ts
|
|
19854
|
+
import {
|
|
19855
|
+
PermissionNotInManifestError as PermissionNotInManifestError2,
|
|
19856
|
+
SessionExpiredError as SessionExpiredError2,
|
|
19857
|
+
ManifestValidationError,
|
|
19858
|
+
resolveManifest,
|
|
19859
|
+
validateManifest,
|
|
19860
|
+
loadManifest,
|
|
19861
|
+
isCapabilitySubset as isCapabilitySubset2,
|
|
19862
|
+
expandActionShortNames as expandActionShortNames2,
|
|
19863
|
+
parseExpiry as parseExpiry2
|
|
19864
|
+
} from "@tinycloud/sdk-core";
|
|
19865
|
+
|
|
19525
19866
|
// src/delegation.ts
|
|
19526
19867
|
function serializeDelegation(delegation) {
|
|
19527
19868
|
return JSON.stringify({
|
|
@@ -19541,8 +19882,18 @@ function deserializeDelegation(data) {
|
|
|
19541
19882
|
// src/index.ts
|
|
19542
19883
|
import { KVService as KVService3, PrefixedKVService } from "@tinycloud/sdk-core";
|
|
19543
19884
|
import { SQLService as SQLService3, SQLAction, DatabaseHandle } from "@tinycloud/sdk-core";
|
|
19544
|
-
import {
|
|
19545
|
-
|
|
19885
|
+
import {
|
|
19886
|
+
DuckDbService as DuckDbService3,
|
|
19887
|
+
DuckDbDatabaseHandle,
|
|
19888
|
+
DuckDbAction
|
|
19889
|
+
} from "@tinycloud/sdk-core";
|
|
19890
|
+
import {
|
|
19891
|
+
DataVaultService as DataVaultService2,
|
|
19892
|
+
VaultHeaders,
|
|
19893
|
+
VaultPublicSpaceKVActions,
|
|
19894
|
+
createVaultCrypto as createVaultCrypto2
|
|
19895
|
+
} from "@tinycloud/sdk-core";
|
|
19896
|
+
import { HooksService as HooksService3 } from "@tinycloud/sdk-core";
|
|
19546
19897
|
import {
|
|
19547
19898
|
DelegationManager as DelegationManager2,
|
|
19548
19899
|
SharingService as SharingService2,
|
|
@@ -19583,16 +19934,20 @@ export {
|
|
|
19583
19934
|
DuckDbDatabaseHandle,
|
|
19584
19935
|
DuckDbService3 as DuckDbService,
|
|
19585
19936
|
FileSessionStorage,
|
|
19937
|
+
HooksService3 as HooksService,
|
|
19586
19938
|
KVService3 as KVService,
|
|
19939
|
+
ManifestValidationError,
|
|
19587
19940
|
MemorySessionStorage,
|
|
19588
19941
|
NodeUserAuthorization,
|
|
19589
19942
|
NodeWasmBindings,
|
|
19943
|
+
PermissionNotInManifestError2 as PermissionNotInManifestError,
|
|
19590
19944
|
PrefixedKVService,
|
|
19591
19945
|
PrivateKeySigner,
|
|
19592
19946
|
ProtocolMismatchError,
|
|
19593
19947
|
SQLAction,
|
|
19594
19948
|
SQLService3 as SQLService,
|
|
19595
19949
|
ServiceContext3 as ServiceContext,
|
|
19950
|
+
SessionExpiredError2 as SessionExpiredError,
|
|
19596
19951
|
SharingService2 as SharingService,
|
|
19597
19952
|
SilentNotificationHandler2 as SilentNotificationHandler,
|
|
19598
19953
|
Space,
|
|
@@ -19615,9 +19970,15 @@ export {
|
|
|
19615
19970
|
defaultSignStrategy,
|
|
19616
19971
|
defaultSpaceCreationHandler,
|
|
19617
19972
|
deserializeDelegation,
|
|
19973
|
+
expandActionShortNames2 as expandActionShortNames,
|
|
19974
|
+
isCapabilitySubset2 as isCapabilitySubset,
|
|
19975
|
+
loadManifest,
|
|
19618
19976
|
makePublicSpaceId2 as makePublicSpaceId,
|
|
19977
|
+
parseExpiry2 as parseExpiry,
|
|
19619
19978
|
parseSpaceUri,
|
|
19620
|
-
|
|
19979
|
+
resolveManifest,
|
|
19980
|
+
serializeDelegation,
|
|
19981
|
+
validateManifest
|
|
19621
19982
|
};
|
|
19622
19983
|
/*! Bundled license information:
|
|
19623
19984
|
|