@tinycloud/node-sdk 3.1.0-beta.1 → 3.1.0-beta.11
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-Bm76PnOz.d.cts → core-CJiLya1s.d.cts} +80 -6
- package/dist/{core-Bm76PnOz.d.ts → core-CJiLya1s.d.ts} +80 -6
- package/dist/core.cjs +348 -137
- 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 +354 -138
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +406 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +412 -171
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -4404,19 +4404,19 @@ var init_lib4 = __esm({
|
|
|
4404
4404
|
resolve(value);
|
|
4405
4405
|
});
|
|
4406
4406
|
}
|
|
4407
|
-
return new (P || (P = Promise))(function(resolve,
|
|
4407
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
4408
4408
|
function fulfilled(value) {
|
|
4409
4409
|
try {
|
|
4410
4410
|
step(generator.next(value));
|
|
4411
4411
|
} catch (e) {
|
|
4412
|
-
|
|
4412
|
+
reject2(e);
|
|
4413
4413
|
}
|
|
4414
4414
|
}
|
|
4415
4415
|
function rejected(value) {
|
|
4416
4416
|
try {
|
|
4417
4417
|
step(generator["throw"](value));
|
|
4418
4418
|
} catch (e) {
|
|
4419
|
-
|
|
4419
|
+
reject2(e);
|
|
4420
4420
|
}
|
|
4421
4421
|
}
|
|
4422
4422
|
function step(result) {
|
|
@@ -8040,19 +8040,19 @@ var init_typed_data = __esm({
|
|
|
8040
8040
|
resolve(value);
|
|
8041
8041
|
});
|
|
8042
8042
|
}
|
|
8043
|
-
return new (P || (P = Promise))(function(resolve,
|
|
8043
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
8044
8044
|
function fulfilled(value) {
|
|
8045
8045
|
try {
|
|
8046
8046
|
step(generator.next(value));
|
|
8047
8047
|
} catch (e) {
|
|
8048
|
-
|
|
8048
|
+
reject2(e);
|
|
8049
8049
|
}
|
|
8050
8050
|
}
|
|
8051
8051
|
function rejected(value) {
|
|
8052
8052
|
try {
|
|
8053
8053
|
step(generator["throw"](value));
|
|
8054
8054
|
} catch (e) {
|
|
8055
|
-
|
|
8055
|
+
reject2(e);
|
|
8056
8056
|
}
|
|
8057
8057
|
}
|
|
8058
8058
|
function step(result) {
|
|
@@ -14898,14 +14898,14 @@ var require_scrypt = __commonJS({
|
|
|
14898
14898
|
}
|
|
14899
14899
|
const lib = {
|
|
14900
14900
|
scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
|
|
14901
|
-
return new Promise(function(resolve,
|
|
14901
|
+
return new Promise(function(resolve, reject2) {
|
|
14902
14902
|
let lastProgress = 0;
|
|
14903
14903
|
if (progressCallback) {
|
|
14904
14904
|
progressCallback(0);
|
|
14905
14905
|
}
|
|
14906
14906
|
_scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
|
|
14907
14907
|
if (error) {
|
|
14908
|
-
|
|
14908
|
+
reject2(error);
|
|
14909
14909
|
} else if (key2) {
|
|
14910
14910
|
if (progressCallback && lastProgress !== 1) {
|
|
14911
14911
|
progressCallback(1);
|
|
@@ -15294,19 +15294,19 @@ var init_keystore = __esm({
|
|
|
15294
15294
|
resolve(value);
|
|
15295
15295
|
});
|
|
15296
15296
|
}
|
|
15297
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15297
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15298
15298
|
function fulfilled(value) {
|
|
15299
15299
|
try {
|
|
15300
15300
|
step(generator.next(value));
|
|
15301
15301
|
} catch (e) {
|
|
15302
|
-
|
|
15302
|
+
reject2(e);
|
|
15303
15303
|
}
|
|
15304
15304
|
}
|
|
15305
15305
|
function rejected(value) {
|
|
15306
15306
|
try {
|
|
15307
15307
|
step(generator["throw"](value));
|
|
15308
15308
|
} catch (e) {
|
|
15309
|
-
|
|
15309
|
+
reject2(e);
|
|
15310
15310
|
}
|
|
15311
15311
|
}
|
|
15312
15312
|
function step(result) {
|
|
@@ -15607,19 +15607,19 @@ var init_lib25 = __esm({
|
|
|
15607
15607
|
resolve(value);
|
|
15608
15608
|
});
|
|
15609
15609
|
}
|
|
15610
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15610
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15611
15611
|
function fulfilled(value) {
|
|
15612
15612
|
try {
|
|
15613
15613
|
step(generator.next(value));
|
|
15614
15614
|
} catch (e) {
|
|
15615
|
-
|
|
15615
|
+
reject2(e);
|
|
15616
15616
|
}
|
|
15617
15617
|
}
|
|
15618
15618
|
function rejected(value) {
|
|
15619
15619
|
try {
|
|
15620
15620
|
step(generator["throw"](value));
|
|
15621
15621
|
} catch (e) {
|
|
15622
|
-
|
|
15622
|
+
reject2(e);
|
|
15623
15623
|
}
|
|
15624
15624
|
}
|
|
15625
15625
|
function step(result) {
|
|
@@ -15689,19 +15689,19 @@ var init_lib26 = __esm({
|
|
|
15689
15689
|
resolve(value);
|
|
15690
15690
|
});
|
|
15691
15691
|
}
|
|
15692
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15692
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15693
15693
|
function fulfilled(value) {
|
|
15694
15694
|
try {
|
|
15695
15695
|
step(generator.next(value));
|
|
15696
15696
|
} catch (e) {
|
|
15697
|
-
|
|
15697
|
+
reject2(e);
|
|
15698
15698
|
}
|
|
15699
15699
|
}
|
|
15700
15700
|
function rejected(value) {
|
|
15701
15701
|
try {
|
|
15702
15702
|
step(generator["throw"](value));
|
|
15703
15703
|
} catch (e) {
|
|
15704
|
-
|
|
15704
|
+
reject2(e);
|
|
15705
15705
|
}
|
|
15706
15706
|
}
|
|
15707
15707
|
function step(result) {
|
|
@@ -16011,19 +16011,19 @@ var init_lib27 = __esm({
|
|
|
16011
16011
|
resolve(value);
|
|
16012
16012
|
});
|
|
16013
16013
|
}
|
|
16014
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16014
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16015
16015
|
function fulfilled(value) {
|
|
16016
16016
|
try {
|
|
16017
16017
|
step(generator.next(value));
|
|
16018
16018
|
} catch (e) {
|
|
16019
|
-
|
|
16019
|
+
reject2(e);
|
|
16020
16020
|
}
|
|
16021
16021
|
}
|
|
16022
16022
|
function rejected(value) {
|
|
16023
16023
|
try {
|
|
16024
16024
|
step(generator["throw"](value));
|
|
16025
16025
|
} catch (e) {
|
|
16026
|
-
|
|
16026
|
+
reject2(e);
|
|
16027
16027
|
}
|
|
16028
16028
|
}
|
|
16029
16029
|
function step(result) {
|
|
@@ -16249,19 +16249,19 @@ var init_geturl = __esm({
|
|
|
16249
16249
|
resolve(value);
|
|
16250
16250
|
});
|
|
16251
16251
|
}
|
|
16252
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16252
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16253
16253
|
function fulfilled(value) {
|
|
16254
16254
|
try {
|
|
16255
16255
|
step(generator.next(value));
|
|
16256
16256
|
} catch (e) {
|
|
16257
|
-
|
|
16257
|
+
reject2(e);
|
|
16258
16258
|
}
|
|
16259
16259
|
}
|
|
16260
16260
|
function rejected(value) {
|
|
16261
16261
|
try {
|
|
16262
16262
|
step(generator["throw"](value));
|
|
16263
16263
|
} catch (e) {
|
|
16264
|
-
|
|
16264
|
+
reject2(e);
|
|
16265
16265
|
}
|
|
16266
16266
|
}
|
|
16267
16267
|
function step(result) {
|
|
@@ -16402,14 +16402,14 @@ function _fetchData(connection, body, processFunc) {
|
|
|
16402
16402
|
options.headers = flatHeaders;
|
|
16403
16403
|
const runningTimeout = (function() {
|
|
16404
16404
|
let timer = null;
|
|
16405
|
-
const promise = new Promise(function(resolve,
|
|
16405
|
+
const promise = new Promise(function(resolve, reject2) {
|
|
16406
16406
|
if (timeout) {
|
|
16407
16407
|
timer = setTimeout(() => {
|
|
16408
16408
|
if (timer == null) {
|
|
16409
16409
|
return;
|
|
16410
16410
|
}
|
|
16411
16411
|
timer = null;
|
|
16412
|
-
|
|
16412
|
+
reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
|
|
16413
16413
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
|
16414
16414
|
requestMethod: options.method,
|
|
16415
16415
|
timeout,
|
|
@@ -16572,7 +16572,7 @@ function poll(func, options) {
|
|
|
16572
16572
|
if (options.interval == null) {
|
|
16573
16573
|
options.interval = 250;
|
|
16574
16574
|
}
|
|
16575
|
-
return new Promise(function(resolve,
|
|
16575
|
+
return new Promise(function(resolve, reject2) {
|
|
16576
16576
|
let timer = null;
|
|
16577
16577
|
let done = false;
|
|
16578
16578
|
const cancel = () => {
|
|
@@ -16588,7 +16588,7 @@ function poll(func, options) {
|
|
|
16588
16588
|
if (options.timeout) {
|
|
16589
16589
|
timer = setTimeout(() => {
|
|
16590
16590
|
if (cancel()) {
|
|
16591
|
-
|
|
16591
|
+
reject2(new Error("timeout"));
|
|
16592
16592
|
}
|
|
16593
16593
|
}, options.timeout);
|
|
16594
16594
|
}
|
|
@@ -16608,7 +16608,7 @@ function poll(func, options) {
|
|
|
16608
16608
|
attempt++;
|
|
16609
16609
|
if (attempt > retryLimit) {
|
|
16610
16610
|
if (cancel()) {
|
|
16611
|
-
|
|
16611
|
+
reject2(new Error("retry limit reached"));
|
|
16612
16612
|
}
|
|
16613
16613
|
return;
|
|
16614
16614
|
}
|
|
@@ -16624,7 +16624,7 @@ function poll(func, options) {
|
|
|
16624
16624
|
return null;
|
|
16625
16625
|
}, function(error) {
|
|
16626
16626
|
if (cancel()) {
|
|
16627
|
-
|
|
16627
|
+
reject2(error);
|
|
16628
16628
|
}
|
|
16629
16629
|
});
|
|
16630
16630
|
}
|
|
@@ -16648,19 +16648,19 @@ var init_lib28 = __esm({
|
|
|
16648
16648
|
resolve(value);
|
|
16649
16649
|
});
|
|
16650
16650
|
}
|
|
16651
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16651
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16652
16652
|
function fulfilled(value) {
|
|
16653
16653
|
try {
|
|
16654
16654
|
step(generator.next(value));
|
|
16655
16655
|
} catch (e) {
|
|
16656
|
-
|
|
16656
|
+
reject2(e);
|
|
16657
16657
|
}
|
|
16658
16658
|
}
|
|
16659
16659
|
function rejected(value) {
|
|
16660
16660
|
try {
|
|
16661
16661
|
step(generator["throw"](value));
|
|
16662
16662
|
} catch (e) {
|
|
16663
|
-
|
|
16663
|
+
reject2(e);
|
|
16664
16664
|
}
|
|
16665
16665
|
}
|
|
16666
16666
|
function step(result) {
|
|
@@ -17072,9 +17072,13 @@ __export(index_exports, {
|
|
|
17072
17072
|
PrefixedKVService: () => import_sdk_core13.PrefixedKVService,
|
|
17073
17073
|
PrivateKeySigner: () => PrivateKeySigner,
|
|
17074
17074
|
ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
|
|
17075
|
+
RUNTIME_DELEGATION_REJECTIONS: () => RUNTIME_DELEGATION_REJECTIONS,
|
|
17076
|
+
RuntimeDelegationRejectedError: () => RuntimeDelegationRejectedError,
|
|
17075
17077
|
SECRET_NAME_RE: () => import_sdk_core16.SECRET_NAME_RE,
|
|
17076
17078
|
SQLAction: () => import_sdk_core14.SQLAction,
|
|
17077
17079
|
SQLService: () => import_sdk_core14.SQLService,
|
|
17080
|
+
STORAGE_FULL_MESSAGE: () => import_sdk_core11.STORAGE_FULL_MESSAGE,
|
|
17081
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE: () => import_sdk_core11.STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
17078
17082
|
SecretsService: () => import_sdk_core16.SecretsService,
|
|
17079
17083
|
ServiceContext: () => import_sdk_core23.ServiceContext,
|
|
17080
17084
|
SessionExpiredError: () => import_sdk_core12.SessionExpiredError,
|
|
@@ -17150,6 +17154,7 @@ __export(index_exports, {
|
|
|
17150
17154
|
isCapabilitySubset: () => import_sdk_core12.isCapabilitySubset,
|
|
17151
17155
|
isEvmAddress: () => import_sdk_core11.isEvmAddress,
|
|
17152
17156
|
isNetworkId: () => import_sdk_core17.isNetworkId,
|
|
17157
|
+
isStorageFullError: () => import_sdk_core11.isStorageFullError,
|
|
17153
17158
|
loadManifest: () => import_sdk_core12.loadManifest,
|
|
17154
17159
|
makePkhSpaceId: () => import_sdk_core11.makePkhSpaceId,
|
|
17155
17160
|
makePublicSpaceId: () => import_sdk_core21.makePublicSpaceId,
|
|
@@ -17210,6 +17215,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17210
17215
|
validatePersistedSession(proof) {
|
|
17211
17216
|
return (0, import_node_sdk_wasm.validatePersistedSession)(proof);
|
|
17212
17217
|
}
|
|
17218
|
+
validateSessionGrant(proof) {
|
|
17219
|
+
return (0, import_node_sdk_wasm.validateSessionGrant)(proof);
|
|
17220
|
+
}
|
|
17213
17221
|
createSessionManager() {
|
|
17214
17222
|
return new import_node_sdk_wasm.TCWSessionManager();
|
|
17215
17223
|
}
|
|
@@ -17368,6 +17376,10 @@ var MemorySessionStorage = class {
|
|
|
17368
17376
|
// src/authorization/NodeUserAuthorization.ts
|
|
17369
17377
|
var DECRYPT_ACTION = import_sdk_core2.ENCRYPTION.DECRYPT;
|
|
17370
17378
|
var NETWORK_CREATE_ACTION = import_sdk_core2.ENCRYPTION.NETWORK_CREATE;
|
|
17379
|
+
function describeHostFailure(result) {
|
|
17380
|
+
const text = result.error?.trim();
|
|
17381
|
+
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
17382
|
+
}
|
|
17371
17383
|
function canonicalizeOpenKeyManifestJson(value) {
|
|
17372
17384
|
const json = JSON.stringify(value);
|
|
17373
17385
|
if (json === void 0) {
|
|
@@ -17896,10 +17908,12 @@ var NodeUserAuthorization = class {
|
|
|
17896
17908
|
return;
|
|
17897
17909
|
}
|
|
17898
17910
|
try {
|
|
17899
|
-
const created =
|
|
17900
|
-
if (!created) {
|
|
17901
|
-
const err =
|
|
17902
|
-
|
|
17911
|
+
const created = await this.hostSpace();
|
|
17912
|
+
if (!created.success) {
|
|
17913
|
+
const err = Object.assign(
|
|
17914
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17915
|
+
{ cause: created }
|
|
17916
|
+
);
|
|
17903
17917
|
throw err;
|
|
17904
17918
|
}
|
|
17905
17919
|
} catch (error) {
|
|
@@ -17915,8 +17929,9 @@ var NodeUserAuthorization = class {
|
|
|
17915
17929
|
this._tinyCloudSession.delegationHeader
|
|
17916
17930
|
);
|
|
17917
17931
|
if (!retryResult.success) {
|
|
17918
|
-
const err =
|
|
17919
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17932
|
+
const err = Object.assign(
|
|
17933
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17934
|
+
{ cause: retryResult }
|
|
17920
17935
|
);
|
|
17921
17936
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17922
17937
|
throw err;
|
|
@@ -17933,10 +17948,12 @@ var NodeUserAuthorization = class {
|
|
|
17933
17948
|
return;
|
|
17934
17949
|
}
|
|
17935
17950
|
try {
|
|
17936
|
-
const created =
|
|
17937
|
-
if (!created) {
|
|
17938
|
-
const err =
|
|
17939
|
-
|
|
17951
|
+
const created = await this.hostSpace();
|
|
17952
|
+
if (!created.success) {
|
|
17953
|
+
const err = Object.assign(
|
|
17954
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17955
|
+
{ cause: created }
|
|
17956
|
+
);
|
|
17940
17957
|
throw err;
|
|
17941
17958
|
}
|
|
17942
17959
|
} catch (error) {
|
|
@@ -17952,8 +17969,9 @@ var NodeUserAuthorization = class {
|
|
|
17952
17969
|
this._tinyCloudSession.delegationHeader
|
|
17953
17970
|
);
|
|
17954
17971
|
if (!retryResult.success) {
|
|
17955
|
-
const err =
|
|
17956
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17972
|
+
const err = Object.assign(
|
|
17973
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17974
|
+
{ cause: retryResult }
|
|
17957
17975
|
);
|
|
17958
17976
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17959
17977
|
throw err;
|
|
@@ -17961,7 +17979,10 @@ var NodeUserAuthorization = class {
|
|
|
17961
17979
|
handler.onSpaceCreated?.(creationContext);
|
|
17962
17980
|
return;
|
|
17963
17981
|
}
|
|
17964
|
-
throw
|
|
17982
|
+
throw Object.assign(
|
|
17983
|
+
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
17984
|
+
{ cause: result }
|
|
17985
|
+
);
|
|
17965
17986
|
}
|
|
17966
17987
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
17967
17988
|
if (result.success) {
|
|
@@ -18751,14 +18772,14 @@ var NodeUserAuthorization = class {
|
|
|
18751
18772
|
* Request signature via event emitter with timeout.
|
|
18752
18773
|
*/
|
|
18753
18774
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18754
|
-
return new Promise((resolve,
|
|
18775
|
+
return new Promise((resolve, reject2) => {
|
|
18755
18776
|
const timeoutId = setTimeout(() => {
|
|
18756
|
-
|
|
18777
|
+
reject2(new Error("Sign request timed out"));
|
|
18757
18778
|
}, timeout);
|
|
18758
18779
|
const respond = async (response) => {
|
|
18759
18780
|
clearTimeout(timeoutId);
|
|
18760
18781
|
if (!response.approved) {
|
|
18761
|
-
|
|
18782
|
+
reject2(
|
|
18762
18783
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18763
18784
|
);
|
|
18764
18785
|
} else {
|
|
@@ -19337,6 +19358,25 @@ function jsonFromVerifier(value) {
|
|
|
19337
19358
|
function verifierRecapEntries(entries) {
|
|
19338
19359
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19339
19360
|
}
|
|
19361
|
+
function exactVerifiedRecap(verified) {
|
|
19362
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19363
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19364
|
+
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
19365
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19366
|
+
)
|
|
19367
|
+
)) {
|
|
19368
|
+
throw new UnsupportedSessionRestoreError(
|
|
19369
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19370
|
+
);
|
|
19371
|
+
}
|
|
19372
|
+
return exactRecap.map((entry) => ({
|
|
19373
|
+
service: entry.service,
|
|
19374
|
+
space: entry.space,
|
|
19375
|
+
path: entry.path,
|
|
19376
|
+
actions: [...entry.actions],
|
|
19377
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19378
|
+
}));
|
|
19379
|
+
}
|
|
19340
19380
|
var ServiceGraphLifetime = class {
|
|
19341
19381
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19342
19382
|
this.invokeFn = invokeFn;
|
|
@@ -19432,7 +19472,7 @@ function persistedExpiry(value) {
|
|
|
19432
19472
|
function sameInstant(left, right) {
|
|
19433
19473
|
return left.getTime() === right.getTime();
|
|
19434
19474
|
}
|
|
19435
|
-
function
|
|
19475
|
+
function describeHostFailure2(result) {
|
|
19436
19476
|
const text = result.error?.trim();
|
|
19437
19477
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
19438
19478
|
}
|
|
@@ -20178,12 +20218,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20178
20218
|
if (!auth) {
|
|
20179
20219
|
throw new Error("Account bootstrap requires an active wallet session");
|
|
20180
20220
|
}
|
|
20221
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core7.ACCOUNT_REGISTRY_SPACE);
|
|
20181
20222
|
const skipped = auth.lastActivationSkippedSpaceIds;
|
|
20223
|
+
if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
|
|
20182
20224
|
if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
|
|
20183
|
-
return { action: "run", mode: "
|
|
20225
|
+
return { action: "run", mode: "repair" };
|
|
20184
20226
|
}
|
|
20185
20227
|
try {
|
|
20186
|
-
const accountSpaceId = this.ownedSpaceId(import_sdk_core7.ACCOUNT_REGISTRY_SPACE);
|
|
20187
20228
|
const markerPermission = {
|
|
20188
20229
|
service: "tinycloud.kv",
|
|
20189
20230
|
space: accountSpaceId,
|
|
@@ -20195,7 +20236,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20195
20236
|
}
|
|
20196
20237
|
const marker = await this.readBootstrapCompletionMarker();
|
|
20197
20238
|
if (marker.ok) {
|
|
20198
|
-
if (this.isAcceptedBootstrapCompletionMarker(marker.data.data)) {
|
|
20239
|
+
if (this.isAcceptedBootstrapCompletionMarker(marker.data.data, steps.map((step) => step.id))) {
|
|
20199
20240
|
return { action: "skip" };
|
|
20200
20241
|
}
|
|
20201
20242
|
return { action: "run", mode: "repair" };
|
|
@@ -20239,15 +20280,22 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20239
20280
|
marker
|
|
20240
20281
|
);
|
|
20241
20282
|
if (!written.ok) {
|
|
20242
|
-
throw
|
|
20283
|
+
throw Object.assign(
|
|
20284
|
+
new Error(`Failed to write bootstrap completion marker: ${written.error.message}`),
|
|
20285
|
+
{ cause: written.error }
|
|
20286
|
+
);
|
|
20243
20287
|
}
|
|
20244
20288
|
}
|
|
20245
|
-
|
|
20289
|
+
/**
|
|
20290
|
+
* A marker written before a canonical space was added triggers one bounded repair.
|
|
20291
|
+
*/
|
|
20292
|
+
isAcceptedBootstrapCompletionMarker(value, canonicalStepIds) {
|
|
20246
20293
|
if (typeof value !== "object" || value === null) return false;
|
|
20247
20294
|
const entries = Object.entries(value);
|
|
20248
20295
|
const markerValue = (name) => entries.find(([key2]) => key2 === name)?.[1];
|
|
20249
20296
|
const version23 = markerValue("v");
|
|
20250
|
-
|
|
20297
|
+
const stepIds = markerValue("stepIds");
|
|
20298
|
+
return typeof version23 === "number" && Number.isInteger(version23) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version23) && Array.isArray(stepIds) && canonicalStepIds.every((stepId) => stepIds.includes(stepId));
|
|
20251
20299
|
}
|
|
20252
20300
|
markerReadIsUnhostedSpace(meta) {
|
|
20253
20301
|
return meta?.status === 404;
|
|
@@ -20285,17 +20333,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20285
20333
|
rawAbilities
|
|
20286
20334
|
});
|
|
20287
20335
|
} catch (err) {
|
|
20288
|
-
throw
|
|
20289
|
-
|
|
20336
|
+
throw Object.assign(
|
|
20337
|
+
new Error(
|
|
20338
|
+
`Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
|
|
20339
|
+
),
|
|
20340
|
+
{ cause: err }
|
|
20290
20341
|
);
|
|
20291
20342
|
}
|
|
20292
20343
|
sessions.set(step.space, session);
|
|
20293
20344
|
}
|
|
20294
20345
|
for (const step of steps) {
|
|
20295
20346
|
if (step.kind !== "host") continue;
|
|
20296
|
-
const hosted = await auth.
|
|
20297
|
-
if (!hosted) {
|
|
20298
|
-
throw
|
|
20347
|
+
const hosted = await auth.hostOwnedSpaceResult(step.spaceId, "bootstrap-host");
|
|
20348
|
+
if (!hosted.success) {
|
|
20349
|
+
throw Object.assign(
|
|
20350
|
+
new Error(`Failed to host bootstrap space ${step.spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20351
|
+
{ cause: hosted }
|
|
20352
|
+
);
|
|
20299
20353
|
}
|
|
20300
20354
|
}
|
|
20301
20355
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -20307,8 +20361,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20307
20361
|
}
|
|
20308
20362
|
const activated = await (0, import_sdk_core7.activateSessionWithHost)(host, session.delegationHeader);
|
|
20309
20363
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
20310
|
-
throw
|
|
20311
|
-
|
|
20364
|
+
throw Object.assign(
|
|
20365
|
+
new Error(
|
|
20366
|
+
`Failed to activate bootstrap session for ${step.spaceId}: ${activated.success ? "space was skipped" : describeHostFailure2(activated)}`
|
|
20367
|
+
),
|
|
20368
|
+
{ cause: activated }
|
|
20312
20369
|
);
|
|
20313
20370
|
}
|
|
20314
20371
|
this.registerBootstrapRuntimeGrant(
|
|
@@ -20321,33 +20378,43 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20321
20378
|
if (step.kind === "account-index-schema") {
|
|
20322
20379
|
const ensured = await this.account.index.ensure();
|
|
20323
20380
|
if (!ensured.ok) {
|
|
20324
|
-
throw new Error(`Failed to create account index schema: ${ensured.error.message}`);
|
|
20381
|
+
throw Object.assign(new Error(`Failed to create account index schema: ${ensured.error.message}`), { cause: ensured.error });
|
|
20325
20382
|
}
|
|
20326
20383
|
}
|
|
20327
20384
|
if (step.kind === "seed-spaces") {
|
|
20328
|
-
const
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20337
|
-
|
|
20338
|
-
|
|
20339
|
-
|
|
20340
|
-
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20385
|
+
const inputs = step.spaces.map((space) => ({
|
|
20386
|
+
spaceId: space.spaceId,
|
|
20387
|
+
name: space.name,
|
|
20388
|
+
ownerDid: this.did,
|
|
20389
|
+
type: "owned",
|
|
20390
|
+
permissions: ["*"],
|
|
20391
|
+
status: "active"
|
|
20392
|
+
}));
|
|
20393
|
+
if (mode === "fresh") {
|
|
20394
|
+
const registered = await this.account.spaces.registerBatch(inputs);
|
|
20395
|
+
if (!registered.ok) {
|
|
20396
|
+
throw Object.assign(
|
|
20397
|
+
new Error(`Failed to seed account spaces: ${registered.error.message}`),
|
|
20398
|
+
{ cause: registered.error }
|
|
20399
|
+
);
|
|
20400
|
+
}
|
|
20401
|
+
const batchError = registered.data.recoveredFromBatchError;
|
|
20402
|
+
if (batchError) {
|
|
20403
|
+
warnings.push({
|
|
20404
|
+
stepId: step.id,
|
|
20405
|
+
kind: "batch-write-reconciled",
|
|
20406
|
+
code: batchError.code,
|
|
20407
|
+
message: batchError.message
|
|
20408
|
+
});
|
|
20409
|
+
}
|
|
20410
|
+
} else {
|
|
20411
|
+
const ensured = await this.account.spaces.registerMissing(inputs);
|
|
20412
|
+
if (!ensured.ok) {
|
|
20413
|
+
throw Object.assign(
|
|
20414
|
+
new Error(`Failed to seed account spaces: ${ensured.error.message}`),
|
|
20415
|
+
{ cause: ensured.error }
|
|
20416
|
+
);
|
|
20417
|
+
}
|
|
20351
20418
|
}
|
|
20352
20419
|
}
|
|
20353
20420
|
if (step.kind === "seed-applications") {
|
|
@@ -20358,7 +20425,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20358
20425
|
{ assumeUnregistered: true }
|
|
20359
20426
|
);
|
|
20360
20427
|
if (!registered.ok) {
|
|
20361
|
-
throw new Error(`Failed to seed bootstrap applications: ${registered.error.message}`);
|
|
20428
|
+
throw Object.assign(new Error(`Failed to seed bootstrap applications: ${registered.error.message}`), { cause: registered.error });
|
|
20362
20429
|
}
|
|
20363
20430
|
}
|
|
20364
20431
|
if (step.kind === "encryption-network-create") {
|
|
@@ -20376,8 +20443,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20376
20443
|
]
|
|
20377
20444
|
});
|
|
20378
20445
|
if (!migrated.ok) {
|
|
20379
|
-
throw
|
|
20380
|
-
`Failed to create secret_records schema: ${migrated.error.message}`
|
|
20446
|
+
throw Object.assign(
|
|
20447
|
+
new Error(`Failed to create secret_records schema: ${migrated.error.message}`),
|
|
20448
|
+
{ cause: migrated.error }
|
|
20381
20449
|
);
|
|
20382
20450
|
}
|
|
20383
20451
|
}
|
|
@@ -20644,6 +20712,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20644
20712
|
);
|
|
20645
20713
|
return;
|
|
20646
20714
|
}
|
|
20715
|
+
if ((0, import_sdk_core7.isStorageFullError)(error) || (0, import_sdk_core7.isStorageFullError)(error?.cause) || message.includes(import_sdk_core7.STORAGE_FULL_MESSAGE) || message.includes(import_sdk_core7.STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
|
|
20716
|
+
console.warn("TinyCloud account registry sync stopped: storage is full", error);
|
|
20717
|
+
return;
|
|
20718
|
+
}
|
|
20647
20719
|
lastError = error;
|
|
20648
20720
|
if (attempt < delays.length - 1) {
|
|
20649
20721
|
await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
|
|
@@ -20718,14 +20790,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20718
20790
|
}
|
|
20719
20791
|
if (!activation.success && activation.status !== 404) {
|
|
20720
20792
|
throw Object.assign(
|
|
20721
|
-
new Error(`Failed to check owned space ${spaceId}: ${
|
|
20793
|
+
new Error(`Failed to check owned space ${spaceId}: ${describeHostFailure2(activation)}`),
|
|
20722
20794
|
{ cause: activation }
|
|
20723
20795
|
);
|
|
20724
20796
|
}
|
|
20725
20797
|
const created = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20726
20798
|
if (!created.success) {
|
|
20727
20799
|
throw Object.assign(
|
|
20728
|
-
new Error(`Failed to create owned space ${spaceId}: ${
|
|
20800
|
+
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
20729
20801
|
{ cause: created }
|
|
20730
20802
|
);
|
|
20731
20803
|
}
|
|
@@ -20734,7 +20806,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20734
20806
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
20735
20807
|
throw Object.assign(
|
|
20736
20808
|
new Error(
|
|
20737
|
-
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" :
|
|
20809
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" : describeHostFailure2(retry)}`
|
|
20738
20810
|
),
|
|
20739
20811
|
{ cause: retry }
|
|
20740
20812
|
);
|
|
@@ -20771,19 +20843,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20771
20843
|
if (!host) {
|
|
20772
20844
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
20773
20845
|
}
|
|
20774
|
-
const hosted = await this.auth.
|
|
20775
|
-
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20846
|
+
const hosted = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20847
|
+
if (!hosted.success) {
|
|
20848
|
+
throw Object.assign(
|
|
20849
|
+
new Error(`Failed to host owned space ${spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20850
|
+
{ cause: hosted }
|
|
20851
|
+
);
|
|
20779
20852
|
}
|
|
20780
20853
|
const activation = await (0, import_sdk_core7.activateSessionWithHost)(
|
|
20781
20854
|
host,
|
|
20782
20855
|
session.delegationHeader
|
|
20783
20856
|
);
|
|
20784
20857
|
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
20785
|
-
throw
|
|
20786
|
-
|
|
20858
|
+
throw Object.assign(
|
|
20859
|
+
new Error(
|
|
20860
|
+
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
20861
|
+
),
|
|
20862
|
+
{ cause: activation }
|
|
20787
20863
|
);
|
|
20788
20864
|
}
|
|
20789
20865
|
try {
|
|
@@ -20979,23 +21055,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20979
21055
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
20980
21056
|
}
|
|
20981
21057
|
})();
|
|
20982
|
-
|
|
20983
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
20984
|
-
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
20985
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
20986
|
-
)
|
|
20987
|
-
)) {
|
|
20988
|
-
throw new UnsupportedSessionRestoreError(
|
|
20989
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
20990
|
-
);
|
|
20991
|
-
}
|
|
20992
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
20993
|
-
service: entry.service,
|
|
20994
|
-
space: entry.space,
|
|
20995
|
-
path: entry.path,
|
|
20996
|
-
actions: [...entry.actions],
|
|
20997
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
20998
|
-
}));
|
|
21058
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
20999
21059
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
21000
21060
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
21001
21061
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -21799,7 +21859,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21799
21859
|
if (cached) return cached;
|
|
21800
21860
|
const response = await fetch(`${this.config.host}/info`);
|
|
21801
21861
|
if (!response.ok) {
|
|
21802
|
-
throw
|
|
21862
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, "Failed to fetch node info");
|
|
21803
21863
|
}
|
|
21804
21864
|
const info = await response.json();
|
|
21805
21865
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -21849,9 +21909,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21849
21909
|
);
|
|
21850
21910
|
if (response.status === 404) return null;
|
|
21851
21911
|
if (!response.ok) {
|
|
21852
|
-
throw
|
|
21853
|
-
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
21854
|
-
);
|
|
21912
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, `Failed to fetch encryption network ${networkId}`);
|
|
21855
21913
|
}
|
|
21856
21914
|
const body = await response.json();
|
|
21857
21915
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -22352,7 +22410,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22352
22410
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
22353
22411
|
body: (0, import_sdk_core7.canonicalizeEncryptionJson)(request)
|
|
22354
22412
|
});
|
|
22355
|
-
if (!response.ok) throw
|
|
22413
|
+
if (!response.ok) throw await (0, import_sdk_core7.httpResponseError)(response, "V3 share delivery authorization failed");
|
|
22356
22414
|
const verified = (0, import_sdk_core7.validateShareDeliveryAuthorizationV3Bytes)(new Uint8Array(await response.arrayBuffer()), {
|
|
22357
22415
|
request,
|
|
22358
22416
|
senderKeyDid: this.credentialHolderDid,
|
|
@@ -22574,9 +22632,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22574
22632
|
);
|
|
22575
22633
|
}
|
|
22576
22634
|
if (!response.ok) {
|
|
22577
|
-
throw
|
|
22578
|
-
`Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
22579
|
-
);
|
|
22635
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, `Failed to create encryption network ${networkId}`);
|
|
22580
22636
|
}
|
|
22581
22637
|
const created = await response.json();
|
|
22582
22638
|
return created.descriptor;
|
|
@@ -22860,6 +22916,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22860
22916
|
(left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0"))
|
|
22861
22917
|
);
|
|
22862
22918
|
}
|
|
22919
|
+
/**
|
|
22920
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22921
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22922
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22923
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22924
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22925
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22926
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22927
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22928
|
+
* which also refuses decrypt-only grants.
|
|
22929
|
+
*/
|
|
22930
|
+
verifySessionGrant(grant) {
|
|
22931
|
+
const bindings = this.wasmBindings;
|
|
22932
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22933
|
+
if (validate5 === void 0) {
|
|
22934
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22935
|
+
}
|
|
22936
|
+
const verified = validate5({
|
|
22937
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22938
|
+
delegationCid: grant.delegationCid,
|
|
22939
|
+
spaceId: grant.spaceId,
|
|
22940
|
+
jwk: this.sessionKeyJwk,
|
|
22941
|
+
address: (0, import_sdk_core7.canonicalizeAddress)(grant.address),
|
|
22942
|
+
chainId: grant.chainId,
|
|
22943
|
+
siwe: grant.siwe,
|
|
22944
|
+
signature: grant.signature
|
|
22945
|
+
});
|
|
22946
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22947
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22948
|
+
}
|
|
22949
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22950
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22951
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22952
|
+
}
|
|
22953
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22954
|
+
}
|
|
22863
22955
|
/**
|
|
22864
22956
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22865
22957
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -22884,8 +22976,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22884
22976
|
delegation.delegationHeader
|
|
22885
22977
|
);
|
|
22886
22978
|
if (!activateResult.success) {
|
|
22887
|
-
throw
|
|
22888
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
22979
|
+
throw Object.assign(
|
|
22980
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
22981
|
+
{ cause: activateResult }
|
|
22889
22982
|
);
|
|
22890
22983
|
}
|
|
22891
22984
|
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
@@ -22981,8 +23074,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22981
23074
|
delegatedSession.delegationHeader
|
|
22982
23075
|
);
|
|
22983
23076
|
if (!activateResult.success) {
|
|
22984
|
-
throw
|
|
22985
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
23077
|
+
throw Object.assign(
|
|
23078
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
23079
|
+
{ cause: activateResult }
|
|
22986
23080
|
);
|
|
22987
23081
|
}
|
|
22988
23082
|
const delegation = this.runtimeDelegationFromSession(
|
|
@@ -22990,7 +23084,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22990
23084
|
delegatedEntries,
|
|
22991
23085
|
spaceId,
|
|
22992
23086
|
session,
|
|
22993
|
-
expiresAt
|
|
23087
|
+
expiresAt,
|
|
23088
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
22994
23089
|
);
|
|
22995
23090
|
this.runtimePermissionGrants.push({
|
|
22996
23091
|
session: {
|
|
@@ -23167,7 +23262,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23167
23262
|
delegationSession.delegationHeader
|
|
23168
23263
|
);
|
|
23169
23264
|
if (!activateResult.success) {
|
|
23170
|
-
throw
|
|
23265
|
+
throw Object.assign(
|
|
23266
|
+
new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
|
|
23267
|
+
{ cause: activateResult }
|
|
23268
|
+
);
|
|
23171
23269
|
}
|
|
23172
23270
|
if (this._capabilityRegistry && this.session) {
|
|
23173
23271
|
const sessionKey = {
|
|
@@ -23520,8 +23618,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23520
23618
|
delegationHeader
|
|
23521
23619
|
);
|
|
23522
23620
|
if (!activateResult.success) {
|
|
23523
|
-
throw
|
|
23524
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23621
|
+
throw Object.assign(
|
|
23622
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23623
|
+
{ cause: activateResult }
|
|
23525
23624
|
);
|
|
23526
23625
|
}
|
|
23527
23626
|
return {
|
|
@@ -23557,8 +23656,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23557
23656
|
delegationHeader
|
|
23558
23657
|
);
|
|
23559
23658
|
if (!activateResult.success) {
|
|
23560
|
-
throw
|
|
23561
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23659
|
+
throw Object.assign(
|
|
23660
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23661
|
+
{ cause: activateResult }
|
|
23562
23662
|
);
|
|
23563
23663
|
}
|
|
23564
23664
|
return {
|
|
@@ -23771,7 +23871,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23771
23871
|
}
|
|
23772
23872
|
return grants;
|
|
23773
23873
|
}
|
|
23774
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23874
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23775
23875
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23776
23876
|
const primary = resources[0];
|
|
23777
23877
|
return {
|
|
@@ -23786,7 +23886,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23786
23886
|
delegateDID: session.verificationMethod,
|
|
23787
23887
|
ownerAddress: session.address,
|
|
23788
23888
|
chainId: session.chainId,
|
|
23789
|
-
host: this.config.host
|
|
23889
|
+
host: this.config.host,
|
|
23890
|
+
siweProof
|
|
23790
23891
|
};
|
|
23791
23892
|
}
|
|
23792
23893
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -23979,6 +24080,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23979
24080
|
if (grantedAction === requestedAction) {
|
|
23980
24081
|
return true;
|
|
23981
24082
|
}
|
|
24083
|
+
if ((0, import_sdk_core7.isExplicitOnlyAction)(requestedAction)) {
|
|
24084
|
+
return false;
|
|
24085
|
+
}
|
|
23982
24086
|
if (grantedAction.endsWith("/*")) {
|
|
23983
24087
|
const prefix = grantedAction.slice(0, -2);
|
|
23984
24088
|
return requestedAction.startsWith(`${prefix}/`);
|
|
@@ -24165,7 +24269,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24165
24269
|
delegationSession.delegationHeader
|
|
24166
24270
|
);
|
|
24167
24271
|
if (!activateResult.success) {
|
|
24168
|
-
throw
|
|
24272
|
+
throw Object.assign(
|
|
24273
|
+
new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
|
|
24274
|
+
{ cause: activateResult }
|
|
24275
|
+
);
|
|
24169
24276
|
}
|
|
24170
24277
|
const result = {
|
|
24171
24278
|
cid: delegationSession.delegationCid,
|
|
@@ -24315,7 +24422,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24315
24422
|
invokerSession.delegationHeader
|
|
24316
24423
|
);
|
|
24317
24424
|
if (!activateResult.success) {
|
|
24318
|
-
throw
|
|
24425
|
+
throw Object.assign(
|
|
24426
|
+
new Error(`Failed to activate delegated session: ${describeHostFailure2(activateResult)}`),
|
|
24427
|
+
{ cause: activateResult }
|
|
24428
|
+
);
|
|
24319
24429
|
}
|
|
24320
24430
|
const session = {
|
|
24321
24431
|
address: mySession.address,
|
|
@@ -24432,7 +24542,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24432
24542
|
subDelegationSession.delegationHeader
|
|
24433
24543
|
);
|
|
24434
24544
|
if (!activateResult.success) {
|
|
24435
|
-
throw
|
|
24545
|
+
throw Object.assign(
|
|
24546
|
+
new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
|
|
24547
|
+
{ cause: activateResult }
|
|
24548
|
+
);
|
|
24436
24549
|
}
|
|
24437
24550
|
return {
|
|
24438
24551
|
cid: subDelegationSession.delegationCid,
|
|
@@ -24647,6 +24760,29 @@ var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
|
24647
24760
|
|
|
24648
24761
|
// src/delegation.ts
|
|
24649
24762
|
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
24763
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24764
|
+
"host_mismatch",
|
|
24765
|
+
"expired",
|
|
24766
|
+
"cid_mismatch",
|
|
24767
|
+
"authority_invalid",
|
|
24768
|
+
"proof_missing",
|
|
24769
|
+
"proof_invalid",
|
|
24770
|
+
"owner_mismatch",
|
|
24771
|
+
"audience_mismatch",
|
|
24772
|
+
"resources_mismatch",
|
|
24773
|
+
"unsupported",
|
|
24774
|
+
"activation_rejected"
|
|
24775
|
+
];
|
|
24776
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24777
|
+
constructor(reason, message) {
|
|
24778
|
+
super(message);
|
|
24779
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24780
|
+
this.reason = reason;
|
|
24781
|
+
}
|
|
24782
|
+
};
|
|
24783
|
+
function reject(reason, message) {
|
|
24784
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24785
|
+
}
|
|
24650
24786
|
var SERVICE_BY_SHORT_NAME = {
|
|
24651
24787
|
kv: "tinycloud.kv",
|
|
24652
24788
|
sql: "tinycloud.sql",
|
|
@@ -24793,6 +24929,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24793
24929
|
abilities
|
|
24794
24930
|
));
|
|
24795
24931
|
}
|
|
24932
|
+
return canonicalSignedAuthority({
|
|
24933
|
+
issuer: payload.iss,
|
|
24934
|
+
audience: payload.aud,
|
|
24935
|
+
expiry,
|
|
24936
|
+
proofs: [...payload.prf],
|
|
24937
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24938
|
+
}, permissions);
|
|
24939
|
+
}
|
|
24940
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24796
24941
|
if (permissions.length === 0) {
|
|
24797
24942
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24798
24943
|
}
|
|
@@ -24804,15 +24949,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24804
24949
|
actions: [...permission.actions],
|
|
24805
24950
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24806
24951
|
}));
|
|
24807
|
-
return {
|
|
24808
|
-
|
|
24809
|
-
|
|
24810
|
-
|
|
24811
|
-
|
|
24812
|
-
|
|
24813
|
-
|
|
24814
|
-
|
|
24815
|
-
|
|
24952
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24953
|
+
}
|
|
24954
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24955
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24956
|
+
function comparableSpace(space) {
|
|
24957
|
+
const match = PKH_SPACE.exec(space);
|
|
24958
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24959
|
+
}
|
|
24960
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
24961
|
+
const proof = delegation.siweProof;
|
|
24962
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
24963
|
+
reject(
|
|
24964
|
+
"proof_missing",
|
|
24965
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
24966
|
+
);
|
|
24967
|
+
}
|
|
24968
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
24969
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
24970
|
+
}
|
|
24971
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
24972
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
24973
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
24974
|
+
}
|
|
24975
|
+
let verified;
|
|
24976
|
+
try {
|
|
24977
|
+
verified = node.verifySessionGrant({
|
|
24978
|
+
delegationHeader: { Authorization: authorization },
|
|
24979
|
+
delegationCid: cid,
|
|
24980
|
+
spaceId: delegation.spaceId,
|
|
24981
|
+
address: delegation.ownerAddress,
|
|
24982
|
+
chainId: delegation.chainId,
|
|
24983
|
+
siwe: proof.siwe,
|
|
24984
|
+
signature: proof.signature
|
|
24985
|
+
});
|
|
24986
|
+
} catch (error) {
|
|
24987
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
24988
|
+
}
|
|
24989
|
+
const space = comparableSpace(delegation.spaceId);
|
|
24990
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
24991
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
24992
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
24993
|
+
}
|
|
24994
|
+
const groups = /* @__PURE__ */ new Map();
|
|
24995
|
+
for (const entry of verified.recap) {
|
|
24996
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
24997
|
+
const raw = entry.space === "encryption";
|
|
24998
|
+
if (raw) {
|
|
24999
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
25000
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
25001
|
+
}
|
|
25002
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
25003
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
25004
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
25005
|
+
}
|
|
25006
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
25007
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
25008
|
+
}
|
|
25009
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
25010
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, (0, import_sdk_core9.canonicalizeRecapCaveats)(caveats)]);
|
|
25011
|
+
const group = groups.get(key2) ?? {
|
|
25012
|
+
service,
|
|
25013
|
+
...raw ? {} : { space: entry.space },
|
|
25014
|
+
path: entry.path,
|
|
25015
|
+
actions: [],
|
|
25016
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25017
|
+
};
|
|
25018
|
+
for (const action of entry.actions) {
|
|
25019
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25020
|
+
}
|
|
25021
|
+
groups.set(key2, group);
|
|
25022
|
+
}
|
|
25023
|
+
return canonicalSignedAuthority({
|
|
25024
|
+
issuer: owner,
|
|
25025
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25026
|
+
audience: node.sessionDid,
|
|
25027
|
+
expiry: verified.expiresAt,
|
|
25028
|
+
proofs: []
|
|
25029
|
+
}, [...groups.values()]);
|
|
24816
25030
|
}
|
|
24817
25031
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24818
25032
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24848,46 +25062,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24848
25062
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24849
25063
|
const host = normalizedHost(options.host);
|
|
24850
25064
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24851
|
-
|
|
25065
|
+
reject(
|
|
25066
|
+
"host_mismatch",
|
|
24852
25067
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24853
25068
|
);
|
|
24854
25069
|
}
|
|
24855
25070
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24856
|
-
|
|
25071
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24857
25072
|
}
|
|
24858
25073
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24859
|
-
|
|
25074
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24860
25075
|
}
|
|
24861
25076
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24862
25077
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24863
|
-
|
|
25078
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24864
25079
|
}
|
|
24865
25080
|
const cid = node.computeDelegationCid(authorization);
|
|
24866
25081
|
if (cid !== delegation.cid) {
|
|
24867
|
-
|
|
25082
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25083
|
+
}
|
|
25084
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25085
|
+
let signed2;
|
|
25086
|
+
try {
|
|
25087
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25088
|
+
} catch (error) {
|
|
25089
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25090
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24868
25091
|
}
|
|
24869
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24870
25092
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24871
|
-
|
|
25093
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24872
25094
|
}
|
|
24873
25095
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24874
|
-
|
|
25096
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24875
25097
|
}
|
|
24876
25098
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24877
|
-
|
|
25099
|
+
reject(
|
|
25100
|
+
"audience_mismatch",
|
|
24878
25101
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24879
25102
|
);
|
|
24880
25103
|
}
|
|
24881
25104
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24882
|
-
|
|
25105
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
24883
25106
|
}
|
|
24884
|
-
|
|
24885
|
-
|
|
24886
|
-
|
|
25107
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25108
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
25109
|
+
}
|
|
25110
|
+
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
25111
|
+
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24887
25112
|
}
|
|
24888
25113
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24889
25114
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24890
|
-
|
|
25115
|
+
reject(
|
|
25116
|
+
"cid_mismatch",
|
|
24891
25117
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24892
25118
|
);
|
|
24893
25119
|
}
|
|
@@ -24917,22 +25143,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
24917
25143
|
})),
|
|
24918
25144
|
expiry: new Date(signed2.expiry),
|
|
24919
25145
|
delegateDID: signed2.audience,
|
|
24920
|
-
host
|
|
25146
|
+
host,
|
|
25147
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
24921
25148
|
};
|
|
24922
|
-
|
|
24923
|
-
|
|
24924
|
-
|
|
24925
|
-
|
|
25149
|
+
try {
|
|
25150
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && (0, import_sdk_core9.principalDidEquals)(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25151
|
+
await node.useDelegation(installedCandidate);
|
|
25152
|
+
} else {
|
|
25153
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25154
|
+
}
|
|
25155
|
+
} catch (error) {
|
|
25156
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
24926
25157
|
}
|
|
24927
25158
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24928
25159
|
if (!installed) {
|
|
24929
|
-
|
|
25160
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
24930
25161
|
}
|
|
24931
25162
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
24932
25163
|
canonicalResourcesFromPortableDelegation(installed),
|
|
24933
25164
|
signed2.resources
|
|
24934
25165
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
24935
|
-
|
|
25166
|
+
reject(
|
|
25167
|
+
"activation_rejected",
|
|
24936
25168
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
24937
25169
|
);
|
|
24938
25170
|
}
|
|
@@ -25081,9 +25313,13 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
25081
25313
|
PrefixedKVService,
|
|
25082
25314
|
PrivateKeySigner,
|
|
25083
25315
|
ProtocolMismatchError,
|
|
25316
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25317
|
+
RuntimeDelegationRejectedError,
|
|
25084
25318
|
SECRET_NAME_RE,
|
|
25085
25319
|
SQLAction,
|
|
25086
25320
|
SQLService,
|
|
25321
|
+
STORAGE_FULL_MESSAGE,
|
|
25322
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
25087
25323
|
SecretsService,
|
|
25088
25324
|
ServiceContext,
|
|
25089
25325
|
SessionExpiredError,
|
|
@@ -25159,6 +25395,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
25159
25395
|
isCapabilitySubset,
|
|
25160
25396
|
isEvmAddress,
|
|
25161
25397
|
isNetworkId,
|
|
25398
|
+
isStorageFullError,
|
|
25162
25399
|
loadManifest,
|
|
25163
25400
|
makePkhSpaceId,
|
|
25164
25401
|
makePublicSpaceId,
|