@tinycloud/node-sdk 3.0.1-beta.0 → 3.1.0-beta.10

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/index.js CHANGED
@@ -4409,19 +4409,19 @@ var init_lib4 = __esm({
4409
4409
  resolve(value);
4410
4410
  });
4411
4411
  }
4412
- return new (P || (P = Promise))(function(resolve, reject) {
4412
+ return new (P || (P = Promise))(function(resolve, reject2) {
4413
4413
  function fulfilled(value) {
4414
4414
  try {
4415
4415
  step(generator.next(value));
4416
4416
  } catch (e) {
4417
- reject(e);
4417
+ reject2(e);
4418
4418
  }
4419
4419
  }
4420
4420
  function rejected(value) {
4421
4421
  try {
4422
4422
  step(generator["throw"](value));
4423
4423
  } catch (e) {
4424
- reject(e);
4424
+ reject2(e);
4425
4425
  }
4426
4426
  }
4427
4427
  function step(result) {
@@ -8045,19 +8045,19 @@ var init_typed_data = __esm({
8045
8045
  resolve(value);
8046
8046
  });
8047
8047
  }
8048
- return new (P || (P = Promise))(function(resolve, reject) {
8048
+ return new (P || (P = Promise))(function(resolve, reject2) {
8049
8049
  function fulfilled(value) {
8050
8050
  try {
8051
8051
  step(generator.next(value));
8052
8052
  } catch (e) {
8053
- reject(e);
8053
+ reject2(e);
8054
8054
  }
8055
8055
  }
8056
8056
  function rejected(value) {
8057
8057
  try {
8058
8058
  step(generator["throw"](value));
8059
8059
  } catch (e) {
8060
- reject(e);
8060
+ reject2(e);
8061
8061
  }
8062
8062
  }
8063
8063
  function step(result) {
@@ -14903,14 +14903,14 @@ var require_scrypt = __commonJS({
14903
14903
  }
14904
14904
  const lib = {
14905
14905
  scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
14906
- return new Promise(function(resolve, reject) {
14906
+ return new Promise(function(resolve, reject2) {
14907
14907
  let lastProgress = 0;
14908
14908
  if (progressCallback) {
14909
14909
  progressCallback(0);
14910
14910
  }
14911
14911
  _scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
14912
14912
  if (error) {
14913
- reject(error);
14913
+ reject2(error);
14914
14914
  } else if (key2) {
14915
14915
  if (progressCallback && lastProgress !== 1) {
14916
14916
  progressCallback(1);
@@ -15299,19 +15299,19 @@ var init_keystore = __esm({
15299
15299
  resolve(value);
15300
15300
  });
15301
15301
  }
15302
- return new (P || (P = Promise))(function(resolve, reject) {
15302
+ return new (P || (P = Promise))(function(resolve, reject2) {
15303
15303
  function fulfilled(value) {
15304
15304
  try {
15305
15305
  step(generator.next(value));
15306
15306
  } catch (e) {
15307
- reject(e);
15307
+ reject2(e);
15308
15308
  }
15309
15309
  }
15310
15310
  function rejected(value) {
15311
15311
  try {
15312
15312
  step(generator["throw"](value));
15313
15313
  } catch (e) {
15314
- reject(e);
15314
+ reject2(e);
15315
15315
  }
15316
15316
  }
15317
15317
  function step(result) {
@@ -15612,19 +15612,19 @@ var init_lib25 = __esm({
15612
15612
  resolve(value);
15613
15613
  });
15614
15614
  }
15615
- return new (P || (P = Promise))(function(resolve, reject) {
15615
+ return new (P || (P = Promise))(function(resolve, reject2) {
15616
15616
  function fulfilled(value) {
15617
15617
  try {
15618
15618
  step(generator.next(value));
15619
15619
  } catch (e) {
15620
- reject(e);
15620
+ reject2(e);
15621
15621
  }
15622
15622
  }
15623
15623
  function rejected(value) {
15624
15624
  try {
15625
15625
  step(generator["throw"](value));
15626
15626
  } catch (e) {
15627
- reject(e);
15627
+ reject2(e);
15628
15628
  }
15629
15629
  }
15630
15630
  function step(result) {
@@ -15694,19 +15694,19 @@ var init_lib26 = __esm({
15694
15694
  resolve(value);
15695
15695
  });
15696
15696
  }
15697
- return new (P || (P = Promise))(function(resolve, reject) {
15697
+ return new (P || (P = Promise))(function(resolve, reject2) {
15698
15698
  function fulfilled(value) {
15699
15699
  try {
15700
15700
  step(generator.next(value));
15701
15701
  } catch (e) {
15702
- reject(e);
15702
+ reject2(e);
15703
15703
  }
15704
15704
  }
15705
15705
  function rejected(value) {
15706
15706
  try {
15707
15707
  step(generator["throw"](value));
15708
15708
  } catch (e) {
15709
- reject(e);
15709
+ reject2(e);
15710
15710
  }
15711
15711
  }
15712
15712
  function step(result) {
@@ -16016,19 +16016,19 @@ var init_lib27 = __esm({
16016
16016
  resolve(value);
16017
16017
  });
16018
16018
  }
16019
- return new (P || (P = Promise))(function(resolve, reject) {
16019
+ return new (P || (P = Promise))(function(resolve, reject2) {
16020
16020
  function fulfilled(value) {
16021
16021
  try {
16022
16022
  step(generator.next(value));
16023
16023
  } catch (e) {
16024
- reject(e);
16024
+ reject2(e);
16025
16025
  }
16026
16026
  }
16027
16027
  function rejected(value) {
16028
16028
  try {
16029
16029
  step(generator["throw"](value));
16030
16030
  } catch (e) {
16031
- reject(e);
16031
+ reject2(e);
16032
16032
  }
16033
16033
  }
16034
16034
  function step(result) {
@@ -16254,19 +16254,19 @@ var init_geturl = __esm({
16254
16254
  resolve(value);
16255
16255
  });
16256
16256
  }
16257
- return new (P || (P = Promise))(function(resolve, reject) {
16257
+ return new (P || (P = Promise))(function(resolve, reject2) {
16258
16258
  function fulfilled(value) {
16259
16259
  try {
16260
16260
  step(generator.next(value));
16261
16261
  } catch (e) {
16262
- reject(e);
16262
+ reject2(e);
16263
16263
  }
16264
16264
  }
16265
16265
  function rejected(value) {
16266
16266
  try {
16267
16267
  step(generator["throw"](value));
16268
16268
  } catch (e) {
16269
- reject(e);
16269
+ reject2(e);
16270
16270
  }
16271
16271
  }
16272
16272
  function step(result) {
@@ -16407,14 +16407,14 @@ function _fetchData(connection, body, processFunc) {
16407
16407
  options.headers = flatHeaders;
16408
16408
  const runningTimeout = (function() {
16409
16409
  let timer = null;
16410
- const promise = new Promise(function(resolve, reject) {
16410
+ const promise = new Promise(function(resolve, reject2) {
16411
16411
  if (timeout) {
16412
16412
  timer = setTimeout(() => {
16413
16413
  if (timer == null) {
16414
16414
  return;
16415
16415
  }
16416
16416
  timer = null;
16417
- reject(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
16417
+ reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
16418
16418
  requestBody: bodyify(options.body, flatHeaders["content-type"]),
16419
16419
  requestMethod: options.method,
16420
16420
  timeout,
@@ -16577,7 +16577,7 @@ function poll(func, options) {
16577
16577
  if (options.interval == null) {
16578
16578
  options.interval = 250;
16579
16579
  }
16580
- return new Promise(function(resolve, reject) {
16580
+ return new Promise(function(resolve, reject2) {
16581
16581
  let timer = null;
16582
16582
  let done = false;
16583
16583
  const cancel = () => {
@@ -16593,7 +16593,7 @@ function poll(func, options) {
16593
16593
  if (options.timeout) {
16594
16594
  timer = setTimeout(() => {
16595
16595
  if (cancel()) {
16596
- reject(new Error("timeout"));
16596
+ reject2(new Error("timeout"));
16597
16597
  }
16598
16598
  }, options.timeout);
16599
16599
  }
@@ -16613,7 +16613,7 @@ function poll(func, options) {
16613
16613
  attempt++;
16614
16614
  if (attempt > retryLimit) {
16615
16615
  if (cancel()) {
16616
- reject(new Error("retry limit reached"));
16616
+ reject2(new Error("retry limit reached"));
16617
16617
  }
16618
16618
  return;
16619
16619
  }
@@ -16629,7 +16629,7 @@ function poll(func, options) {
16629
16629
  return null;
16630
16630
  }, function(error) {
16631
16631
  if (cancel()) {
16632
- reject(error);
16632
+ reject2(error);
16633
16633
  }
16634
16634
  });
16635
16635
  }
@@ -16653,19 +16653,19 @@ var init_lib28 = __esm({
16653
16653
  resolve(value);
16654
16654
  });
16655
16655
  }
16656
- return new (P || (P = Promise))(function(resolve, reject) {
16656
+ return new (P || (P = Promise))(function(resolve, reject2) {
16657
16657
  function fulfilled(value) {
16658
16658
  try {
16659
16659
  step(generator.next(value));
16660
16660
  } catch (e) {
16661
- reject(e);
16661
+ reject2(e);
16662
16662
  }
16663
16663
  }
16664
16664
  function rejected(value) {
16665
16665
  try {
16666
16666
  step(generator["throw"](value));
16667
16667
  } catch (e) {
16668
- reject(e);
16668
+ reject2(e);
16669
16669
  }
16670
16670
  }
16671
16671
  function step(result) {
@@ -17035,6 +17035,7 @@ import {
17035
17035
  prepareSession,
17036
17036
  completeSessionSetup,
17037
17037
  validatePersistedSession,
17038
+ validateSessionGrant,
17038
17039
  ensureEip55,
17039
17040
  makeSpaceId,
17040
17041
  createDelegation,
@@ -17084,6 +17085,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
17084
17085
  validatePersistedSession(proof) {
17085
17086
  return validatePersistedSession(proof);
17086
17087
  }
17088
+ validateSessionGrant(proof) {
17089
+ return validateSessionGrant(proof);
17090
+ }
17087
17091
  createSessionManager() {
17088
17092
  return new TCWSessionManager();
17089
17093
  }
@@ -17162,6 +17166,8 @@ var PrivateKeySigner = class {
17162
17166
  import {
17163
17167
  TinyCloud,
17164
17168
  activateSessionWithHost as activateSessionWithHost2,
17169
+ authorizationVerdictOf,
17170
+ httpResponseError,
17165
17171
  KVService as KVService2,
17166
17172
  SQLService as SQLService2,
17167
17173
  DuckDbService as DuckDbService2,
@@ -17195,6 +17201,7 @@ import {
17195
17201
  recapCaveatsEqual,
17196
17202
  expandPermissionEntries as expandPermissionEntriesCore,
17197
17203
  isCapabilitySubset,
17204
+ isExplicitOnlyAction,
17198
17205
  parseRecapCapabilities,
17199
17206
  SERVICE_LONG_TO_SHORT,
17200
17207
  SERVICE_SHORT_TO_LONG,
@@ -17217,7 +17224,10 @@ import {
17217
17224
  CREDENTIAL_INVITATION_REQUEST_DOMAIN,
17218
17225
  validateShareDeliveryAuthorizationV3Bytes,
17219
17226
  verifyEip191MessageSignature,
17220
- signCompactUcanRootAuthorization
17227
+ signCompactUcanRootAuthorization,
17228
+ isStorageFullError,
17229
+ STORAGE_FULL_MESSAGE,
17230
+ STORAGE_WRITE_TOO_LARGE_MESSAGE
17221
17231
  } from "@tinycloud/sdk-core";
17222
17232
  import {
17223
17233
  parsePermissionHint
@@ -17337,6 +17347,10 @@ var MemorySessionStorage = class {
17337
17347
  // src/authorization/NodeUserAuthorization.ts
17338
17348
  var DECRYPT_ACTION = ENCRYPTION.DECRYPT;
17339
17349
  var NETWORK_CREATE_ACTION = ENCRYPTION.NETWORK_CREATE;
17350
+ function describeHostFailure(result) {
17351
+ const text = result.error?.trim();
17352
+ return text ? `${result.status} - ${text}` : `${result.status}`;
17353
+ }
17340
17354
  function canonicalizeOpenKeyManifestJson(value) {
17341
17355
  const json = JSON.stringify(value);
17342
17356
  if (json === void 0) {
@@ -17801,21 +17815,28 @@ var NodeUserAuthorization = class {
17801
17815
  });
17802
17816
  const signature2 = await this.signMessage(siwe, purpose);
17803
17817
  const headers = this.wasm.siweToDelegationHeaders({ siwe, signature: signature2 });
17804
- const result = await submitHostDelegation(host, headers);
17805
- return result.success;
17818
+ return submitHostDelegation(host, headers);
17806
17819
  }
17807
17820
  /**
17808
17821
  * Create a specific space on the server via host delegation.
17809
17822
  * Used for lazy creation of additional spaces (e.g., public).
17810
17823
  */
17811
17824
  async hostPublicSpace(spaceId) {
17812
- return this.hostSpace(spaceId);
17825
+ return (await this.hostSpace(spaceId)).success;
17813
17826
  }
17814
17827
  /**
17815
17828
  * Create a specific owned space on the server via host delegation.
17816
17829
  * Used by manifest registry setup for the account space.
17817
17830
  */
17818
17831
  async hostOwnedSpace(spaceId, purpose) {
17832
+ return (await this.hostOwnedSpaceResult(spaceId, purpose)).success;
17833
+ }
17834
+ /**
17835
+ * {@link hostOwnedSpace} with the full host-delegation result, so a failure
17836
+ * keeps its HTTP status (e.g. a typed 401/403) instead of collapsing to
17837
+ * `false`.
17838
+ */
17839
+ async hostOwnedSpaceResult(spaceId, purpose) {
17819
17840
  return this.hostSpace(spaceId, purpose);
17820
17841
  }
17821
17842
  /**
@@ -17859,9 +17880,11 @@ var NodeUserAuthorization = class {
17859
17880
  }
17860
17881
  try {
17861
17882
  const created = await this.hostSpace();
17862
- if (!created) {
17863
- const err = new Error(`Failed to create space: ${primarySpaceId}`);
17864
- handler.onSpaceCreationFailed?.(creationContext, err);
17883
+ if (!created.success) {
17884
+ const err = Object.assign(
17885
+ new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
17886
+ { cause: created }
17887
+ );
17865
17888
  throw err;
17866
17889
  }
17867
17890
  } catch (error) {
@@ -17877,8 +17900,9 @@ var NodeUserAuthorization = class {
17877
17900
  this._tinyCloudSession.delegationHeader
17878
17901
  );
17879
17902
  if (!retryResult.success) {
17880
- const err = new Error(
17881
- `Failed to activate session after creating space: ${retryResult.error}`
17903
+ const err = Object.assign(
17904
+ new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
17905
+ { cause: retryResult }
17882
17906
  );
17883
17907
  handler.onSpaceCreationFailed?.(creationContext, err);
17884
17908
  throw err;
@@ -17896,9 +17920,11 @@ var NodeUserAuthorization = class {
17896
17920
  }
17897
17921
  try {
17898
17922
  const created = await this.hostSpace();
17899
- if (!created) {
17900
- const err = new Error(`Failed to create space: ${primarySpaceId}`);
17901
- handler.onSpaceCreationFailed?.(creationContext, err);
17923
+ if (!created.success) {
17924
+ const err = Object.assign(
17925
+ new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
17926
+ { cause: created }
17927
+ );
17902
17928
  throw err;
17903
17929
  }
17904
17930
  } catch (error) {
@@ -17914,8 +17940,9 @@ var NodeUserAuthorization = class {
17914
17940
  this._tinyCloudSession.delegationHeader
17915
17941
  );
17916
17942
  if (!retryResult.success) {
17917
- const err = new Error(
17918
- `Failed to activate session after creating space: ${retryResult.error}`
17943
+ const err = Object.assign(
17944
+ new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
17945
+ { cause: retryResult }
17919
17946
  );
17920
17947
  handler.onSpaceCreationFailed?.(creationContext, err);
17921
17948
  throw err;
@@ -17923,7 +17950,10 @@ var NodeUserAuthorization = class {
17923
17950
  handler.onSpaceCreated?.(creationContext);
17924
17951
  return;
17925
17952
  }
17926
- throw new Error(`Failed to activate session: ${result.error}`);
17953
+ throw Object.assign(
17954
+ new Error(`Failed to activate session: ${describeHostFailure(result)}`),
17955
+ { cause: result }
17956
+ );
17927
17957
  }
17928
17958
  recordActivationSkippedSpaces(result, primarySpaceId) {
17929
17959
  if (result.success) {
@@ -18713,14 +18743,14 @@ var NodeUserAuthorization = class {
18713
18743
  * Request signature via event emitter with timeout.
18714
18744
  */
18715
18745
  requestSignatureViaEmitter(request, emitter, timeout) {
18716
- return new Promise((resolve, reject) => {
18746
+ return new Promise((resolve, reject2) => {
18717
18747
  const timeoutId = setTimeout(() => {
18718
- reject(new Error("Sign request timed out"));
18748
+ reject2(new Error("Sign request timed out"));
18719
18749
  }, timeout);
18720
18750
  const respond = async (response) => {
18721
18751
  clearTimeout(timeoutId);
18722
18752
  if (!response.approved) {
18723
- reject(
18753
+ reject2(
18724
18754
  new Error(response.reason ?? "Sign request rejected via emitter")
18725
18755
  );
18726
18756
  } else {
@@ -19315,6 +19345,25 @@ function jsonFromVerifier(value) {
19315
19345
  function verifierRecapEntries(entries) {
19316
19346
  return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
19317
19347
  }
19348
+ function exactVerifiedRecap(verified) {
19349
+ const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
19350
+ if (!Array.isArray(exactRecap) || !exactRecap.every(
19351
+ (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(
19352
+ (caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
19353
+ )
19354
+ )) {
19355
+ throw new UnsupportedSessionRestoreError(
19356
+ "it cannot reconstruct caveat-preserving persisted ReCap authority"
19357
+ );
19358
+ }
19359
+ return exactRecap.map((entry) => ({
19360
+ service: entry.service,
19361
+ space: entry.space,
19362
+ path: entry.path,
19363
+ actions: [...entry.actions],
19364
+ caveats: cloneRecapCaveats(entry.caveats)
19365
+ }));
19366
+ }
19318
19367
  var ServiceGraphLifetime = class {
19319
19368
  constructor(invokeFn, invokeAnyFn, fetchFn) {
19320
19369
  this.invokeFn = invokeFn;
@@ -19410,6 +19459,10 @@ function persistedExpiry(value) {
19410
19459
  function sameInstant(left, right) {
19411
19460
  return left.getTime() === right.getTime();
19412
19461
  }
19462
+ function describeHostFailure2(result) {
19463
+ const text = result.error?.trim();
19464
+ return text ? `${result.status} - ${text}` : `${result.status}`;
19465
+ }
19413
19466
  function ownerDelegationPermissions(params) {
19414
19467
  const hasPermissions = Object.prototype.hasOwnProperty.call(params, "permissions");
19415
19468
  const hasLegacy = Object.prototype.hasOwnProperty.call(params, "path") || Object.prototype.hasOwnProperty.call(params, "actions");
@@ -20213,7 +20266,10 @@ var _TinyCloudNode = class _TinyCloudNode {
20213
20266
  marker
20214
20267
  );
20215
20268
  if (!written.ok) {
20216
- throw new Error(`Failed to write bootstrap completion marker: ${written.error.message}`);
20269
+ throw Object.assign(
20270
+ new Error(`Failed to write bootstrap completion marker: ${written.error.message}`),
20271
+ { cause: written.error }
20272
+ );
20217
20273
  }
20218
20274
  }
20219
20275
  isAcceptedBootstrapCompletionMarker(value) {
@@ -20259,17 +20315,23 @@ var _TinyCloudNode = class _TinyCloudNode {
20259
20315
  rawAbilities
20260
20316
  });
20261
20317
  } catch (err) {
20262
- throw new Error(
20263
- `Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
20318
+ throw Object.assign(
20319
+ new Error(
20320
+ `Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
20321
+ ),
20322
+ { cause: err }
20264
20323
  );
20265
20324
  }
20266
20325
  sessions.set(step.space, session);
20267
20326
  }
20268
20327
  for (const step of steps) {
20269
20328
  if (step.kind !== "host") continue;
20270
- const hosted = await auth.hostOwnedSpace(step.spaceId, "bootstrap-host");
20271
- if (!hosted) {
20272
- throw new Error(`Failed to host bootstrap space: ${step.spaceId}`);
20329
+ const hosted = await auth.hostOwnedSpaceResult(step.spaceId, "bootstrap-host");
20330
+ if (!hosted.success) {
20331
+ throw Object.assign(
20332
+ new Error(`Failed to host bootstrap space ${step.spaceId}: ${describeHostFailure2(hosted)}`),
20333
+ { cause: hosted }
20334
+ );
20273
20335
  }
20274
20336
  }
20275
20337
  await new Promise((resolve) => setTimeout(resolve, 100));
@@ -20281,8 +20343,11 @@ var _TinyCloudNode = class _TinyCloudNode {
20281
20343
  }
20282
20344
  const activated = await activateSessionWithHost2(host, session.delegationHeader);
20283
20345
  if (!activated.success || activated.skipped?.includes(step.spaceId)) {
20284
- throw new Error(
20285
- `Failed to activate bootstrap session for ${step.spaceId}: ${activated.error ?? "space was skipped"}`
20346
+ throw Object.assign(
20347
+ new Error(
20348
+ `Failed to activate bootstrap session for ${step.spaceId}: ${activated.success ? "space was skipped" : describeHostFailure2(activated)}`
20349
+ ),
20350
+ { cause: activated }
20286
20351
  );
20287
20352
  }
20288
20353
  this.registerBootstrapRuntimeGrant(
@@ -20295,7 +20360,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20295
20360
  if (step.kind === "account-index-schema") {
20296
20361
  const ensured = await this.account.index.ensure();
20297
20362
  if (!ensured.ok) {
20298
- throw new Error(`Failed to create account index schema: ${ensured.error.message}`);
20363
+ throw Object.assign(new Error(`Failed to create account index schema: ${ensured.error.message}`), { cause: ensured.error });
20299
20364
  }
20300
20365
  }
20301
20366
  if (step.kind === "seed-spaces") {
@@ -20310,8 +20375,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20310
20375
  }))
20311
20376
  );
20312
20377
  if (!registered.ok) {
20313
- throw new Error(
20314
- `Failed to seed account spaces: ${registered.error.message}`
20378
+ throw Object.assign(
20379
+ new Error(`Failed to seed account spaces: ${registered.error.message}`),
20380
+ { cause: registered.error }
20315
20381
  );
20316
20382
  }
20317
20383
  const batchError = registered.data.recoveredFromBatchError;
@@ -20332,7 +20398,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20332
20398
  { assumeUnregistered: true }
20333
20399
  );
20334
20400
  if (!registered.ok) {
20335
- throw new Error(`Failed to seed bootstrap applications: ${registered.error.message}`);
20401
+ throw Object.assign(new Error(`Failed to seed bootstrap applications: ${registered.error.message}`), { cause: registered.error });
20336
20402
  }
20337
20403
  }
20338
20404
  if (step.kind === "encryption-network-create") {
@@ -20350,8 +20416,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20350
20416
  ]
20351
20417
  });
20352
20418
  if (!migrated.ok) {
20353
- throw new Error(
20354
- `Failed to create secret_records schema: ${migrated.error.message}`
20419
+ throw Object.assign(
20420
+ new Error(`Failed to create secret_records schema: ${migrated.error.message}`),
20421
+ { cause: migrated.error }
20355
20422
  );
20356
20423
  }
20357
20424
  }
@@ -20523,8 +20590,9 @@ var _TinyCloudNode = class _TinyCloudNode {
20523
20590
  await this.ensureOwnedSpaceHostedById(accountSpaceId);
20524
20591
  const result = await this.account.applications.register(request.manifests);
20525
20592
  if (!result.ok) {
20526
- throw new Error(
20527
- `Failed to write manifest registry records: ${result.error.message}`
20593
+ throw Object.assign(
20594
+ new Error(`Failed to write manifest registry records: ${result.error.message}`),
20595
+ { cause: result.error }
20528
20596
  );
20529
20597
  }
20530
20598
  }
@@ -20549,7 +20617,10 @@ var _TinyCloudNode = class _TinyCloudNode {
20549
20617
  if (this.currentSessionCanListSpaces()) {
20550
20618
  const spaces = await this.account.spaces.syncAccessible();
20551
20619
  if (!spaces.ok) {
20552
- throw new Error(`Failed to sync account spaces: ${spaces.error.message}`);
20620
+ throw Object.assign(
20621
+ new Error(`Failed to sync account spaces: ${spaces.error.message}`),
20622
+ { cause: spaces.error }
20623
+ );
20553
20624
  }
20554
20625
  }
20555
20626
  });
@@ -20604,14 +20675,20 @@ var _TinyCloudNode = class _TinyCloudNode {
20604
20675
  await task();
20605
20676
  return;
20606
20677
  } catch (error) {
20678
+ const verdict = authorizationVerdictOf(error);
20607
20679
  const message = error instanceof Error ? error.message : String(error);
20608
- if (/Unauthorized Action|\b(?:401|403)\b/.test(message)) {
20680
+ const isAuthorizationVerdict = verdict === void 0 ? /Unauthorized Action|\b(?:401|403)\b/.test(message) : verdict !== "other";
20681
+ if (isAuthorizationVerdict) {
20609
20682
  console.warn(
20610
20683
  "TinyCloud account registry sync stopped: authorization verdict is not retryable",
20611
20684
  error
20612
20685
  );
20613
20686
  return;
20614
20687
  }
20688
+ if (isStorageFullError(error) || isStorageFullError(error?.cause) || message.includes(STORAGE_FULL_MESSAGE) || message.includes(STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
20689
+ console.warn("TinyCloud account registry sync stopped: storage is full", error);
20690
+ return;
20691
+ }
20615
20692
  lastError = error;
20616
20693
  if (attempt < delays.length - 1) {
20617
20694
  await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
@@ -20685,19 +20762,26 @@ var _TinyCloudNode = class _TinyCloudNode {
20685
20762
  return;
20686
20763
  }
20687
20764
  if (!activation.success && activation.status !== 404) {
20688
- throw new Error(
20689
- `Failed to check owned space ${spaceId}: ${activation.error ?? activation.status}`
20765
+ throw Object.assign(
20766
+ new Error(`Failed to check owned space ${spaceId}: ${describeHostFailure2(activation)}`),
20767
+ { cause: activation }
20690
20768
  );
20691
20769
  }
20692
- const created = await this.auth.hostOwnedSpace(spaceId);
20693
- if (!created) {
20694
- throw new Error(`Failed to create owned space: ${spaceId}`);
20770
+ const created = await this.auth.hostOwnedSpaceResult(spaceId);
20771
+ if (!created.success) {
20772
+ throw Object.assign(
20773
+ new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
20774
+ { cause: created }
20775
+ );
20695
20776
  }
20696
20777
  await new Promise((resolve) => setTimeout(resolve, 100));
20697
20778
  const retry = await activateSessionWithHost2(host, session.delegationHeader);
20698
20779
  if (!retry.success || retry.skipped?.includes(spaceId)) {
20699
- throw new Error(
20700
- `Failed to activate session after creating owned space ${spaceId}: ${retry.error ?? "space was skipped"}`
20780
+ throw Object.assign(
20781
+ new Error(
20782
+ `Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" : describeHostFailure2(retry)}`
20783
+ ),
20784
+ { cause: retry }
20701
20785
  );
20702
20786
  }
20703
20787
  this.confirmedHostedSpaceIds.add(spaceId);
@@ -20732,19 +20816,23 @@ var _TinyCloudNode = class _TinyCloudNode {
20732
20816
  if (!host) {
20733
20817
  throw new Error("Owned space hosting requires a TinyCloud host");
20734
20818
  }
20735
- const hosted = await this.auth.hostOwnedSpace(
20736
- spaceId
20737
- );
20738
- if (!hosted) {
20739
- throw new Error(`Failed to host owned space: ${spaceId}`);
20819
+ const hosted = await this.auth.hostOwnedSpaceResult(spaceId);
20820
+ if (!hosted.success) {
20821
+ throw Object.assign(
20822
+ new Error(`Failed to host owned space ${spaceId}: ${describeHostFailure2(hosted)}`),
20823
+ { cause: hosted }
20824
+ );
20740
20825
  }
20741
20826
  const activation = await activateSessionWithHost2(
20742
20827
  host,
20743
20828
  session.delegationHeader
20744
20829
  );
20745
20830
  if (!activation.success || activation.skipped?.includes(spaceId)) {
20746
- throw new Error(
20747
- `Failed to activate session for owned space ${spaceId}: ${activation.error ?? "space was skipped"}`
20831
+ throw Object.assign(
20832
+ new Error(
20833
+ `Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
20834
+ ),
20835
+ { cause: activation }
20748
20836
  );
20749
20837
  }
20750
20838
  try {
@@ -20940,23 +21028,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20940
21028
  throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
20941
21029
  }
20942
21030
  })();
20943
- const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
20944
- if (!Array.isArray(exactRecap) || !exactRecap.every(
20945
- (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(
20946
- (caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
20947
- )
20948
- )) {
20949
- throw new UnsupportedSessionRestoreError(
20950
- "it cannot reconstruct caveat-preserving persisted ReCap authority"
20951
- );
20952
- }
20953
- stagedRecap = exactRecap.map((entry) => ({
20954
- service: entry.service,
20955
- space: entry.space,
20956
- path: entry.path,
20957
- actions: [...entry.actions],
20958
- caveats: cloneRecapCaveats(entry.caveats)
20959
- }));
21031
+ stagedRecap = exactVerifiedRecap(verified);
20960
21032
  const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
20961
21033
  const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
20962
21034
  if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
@@ -21760,7 +21832,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21760
21832
  if (cached) return cached;
21761
21833
  const response = await fetch(`${this.config.host}/info`);
21762
21834
  if (!response.ok) {
21763
- throw new Error(`Failed to fetch node info: HTTP ${response.status}`);
21835
+ throw await httpResponseError(response, "Failed to fetch node info");
21764
21836
  }
21765
21837
  const info = await response.json();
21766
21838
  if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
@@ -21810,9 +21882,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21810
21882
  );
21811
21883
  if (response.status === 404) return null;
21812
21884
  if (!response.ok) {
21813
- throw new Error(
21814
- `Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
21815
- );
21885
+ throw await httpResponseError(response, `Failed to fetch encryption network ${networkId}`);
21816
21886
  }
21817
21887
  const body = await response.json();
21818
21888
  return "descriptor" in body && body.descriptor ? body.descriptor : body;
@@ -22245,7 +22315,10 @@ var _TinyCloudNode = class _TinyCloudNode {
22245
22315
  const activation = await activateSessionWithHost2(host, delegationSession.delegationHeader);
22246
22316
  assertOwnerGraphActive();
22247
22317
  if (!activation.success) {
22248
- throw new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim());
22318
+ throw Object.assign(
22319
+ new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim()),
22320
+ { cause: activation }
22321
+ );
22249
22322
  }
22250
22323
  const delegation = {
22251
22324
  cid: delegationSession.delegationCid,
@@ -22310,7 +22383,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22310
22383
  headers: { accept: "application/json", "content-type": "application/json", authorization },
22311
22384
  body: canonicalizeEncryptionJson(request)
22312
22385
  });
22313
- if (!response.ok) throw new Error(`V3 share delivery authorization failed: ${response.status}`);
22386
+ if (!response.ok) throw await httpResponseError(response, "V3 share delivery authorization failed");
22314
22387
  const verified = validateShareDeliveryAuthorizationV3Bytes(new Uint8Array(await response.arrayBuffer()), {
22315
22388
  request,
22316
22389
  senderKeyDid: this.credentialHolderDid,
@@ -22532,9 +22605,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22532
22605
  );
22533
22606
  }
22534
22607
  if (!response.ok) {
22535
- throw new Error(
22536
- `Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
22537
- );
22608
+ throw await httpResponseError(response, `Failed to create encryption network ${networkId}`);
22538
22609
  }
22539
22610
  const created = await response.json();
22540
22611
  return created.descriptor;
@@ -22818,6 +22889,42 @@ var _TinyCloudNode = class _TinyCloudNode {
22818
22889
  (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"))
22819
22890
  );
22820
22891
  }
22892
+ /**
22893
+ * Verify a wallet-signed session grant (a CACAO built from a SIWE and its
22894
+ * EIP-191 signature) issued to this instance's live session key. The
22895
+ * verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
22896
+ * accepted only when its authorization bytes and CID are exactly that CACAO,
22897
+ * its signer is `address`, its audience is this session key, it is valid
22898
+ * now, and its ReCap covers `spaceId` or names only raw encryption networks
22899
+ * (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
22900
+ * Bindings without `validateSessionGrant` fall back to the session verifier,
22901
+ * which also refuses decrypt-only grants.
22902
+ */
22903
+ verifySessionGrant(grant) {
22904
+ const bindings = this.wasmBindings;
22905
+ const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
22906
+ if (validate5 === void 0) {
22907
+ throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
22908
+ }
22909
+ const verified = validate5({
22910
+ delegationHeader: { Authorization: grant.delegationHeader.Authorization },
22911
+ delegationCid: grant.delegationCid,
22912
+ spaceId: grant.spaceId,
22913
+ jwk: this.sessionKeyJwk,
22914
+ address: canonicalizeAddress2(grant.address),
22915
+ chainId: grant.chainId,
22916
+ siwe: grant.siwe,
22917
+ signature: grant.signature
22918
+ });
22919
+ if (typeof verified.expiresAt !== "string") {
22920
+ throw new Error("Session grant has no signed expiry.");
22921
+ }
22922
+ const expiresAt = new Date(verified.expiresAt);
22923
+ if (!Number.isFinite(expiresAt.getTime())) {
22924
+ throw new Error("Session grant has an invalid signed expiry.");
22925
+ }
22926
+ return { recap: exactVerifiedRecap(verified), expiresAt };
22927
+ }
22821
22928
  /**
22822
22929
  * Install a portable runtime permission delegation into this SDK instance so
22823
22930
  * matching service calls and downstream `delegateTo()` calls can use it.
@@ -22842,8 +22949,9 @@ var _TinyCloudNode = class _TinyCloudNode {
22842
22949
  delegation.delegationHeader
22843
22950
  );
22844
22951
  if (!activateResult.success) {
22845
- throw new Error(
22846
- `Failed to activate runtime permission delegation: ${activateResult.error}`
22952
+ throw Object.assign(
22953
+ new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
22954
+ { cause: activateResult }
22847
22955
  );
22848
22956
  }
22849
22957
  this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
@@ -22939,8 +23047,9 @@ var _TinyCloudNode = class _TinyCloudNode {
22939
23047
  delegatedSession.delegationHeader
22940
23048
  );
22941
23049
  if (!activateResult.success) {
22942
- throw new Error(
22943
- `Failed to activate runtime permission delegation: ${activateResult.error}`
23050
+ throw Object.assign(
23051
+ new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
23052
+ { cause: activateResult }
22944
23053
  );
22945
23054
  }
22946
23055
  const delegation = this.runtimeDelegationFromSession(
@@ -22948,7 +23057,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22948
23057
  delegatedEntries,
22949
23058
  spaceId,
22950
23059
  session,
22951
- expiresAt
23060
+ expiresAt,
23061
+ { siwe: prepared.siwe, signature: signature2 }
22952
23062
  );
22953
23063
  this.runtimePermissionGrants.push({
22954
23064
  session: {
@@ -23125,7 +23235,10 @@ var _TinyCloudNode = class _TinyCloudNode {
23125
23235
  delegationSession.delegationHeader
23126
23236
  );
23127
23237
  if (!activateResult.success) {
23128
- throw new Error(`Failed to activate public space delegation: ${activateResult.error}`);
23238
+ throw Object.assign(
23239
+ new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
23240
+ { cause: activateResult }
23241
+ );
23129
23242
  }
23130
23243
  if (this._capabilityRegistry && this.session) {
23131
23244
  const sessionKey = {
@@ -23478,8 +23591,9 @@ var _TinyCloudNode = class _TinyCloudNode {
23478
23591
  delegationHeader
23479
23592
  );
23480
23593
  if (!activateResult.success) {
23481
- throw new Error(
23482
- `Failed to activate delegation with host: ${activateResult.error}`
23594
+ throw Object.assign(
23595
+ new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
23596
+ { cause: activateResult }
23483
23597
  );
23484
23598
  }
23485
23599
  return {
@@ -23515,8 +23629,9 @@ var _TinyCloudNode = class _TinyCloudNode {
23515
23629
  delegationHeader
23516
23630
  );
23517
23631
  if (!activateResult.success) {
23518
- throw new Error(
23519
- `Failed to activate delegation with host: ${activateResult.error}`
23632
+ throw Object.assign(
23633
+ new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
23634
+ { cause: activateResult }
23520
23635
  );
23521
23636
  }
23522
23637
  return {
@@ -23729,7 +23844,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23729
23844
  }
23730
23845
  return grants;
23731
23846
  }
23732
- runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
23847
+ runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
23733
23848
  const resources = this.delegatedResourcesForEntries(entries, spaceId);
23734
23849
  const primary = resources[0];
23735
23850
  return {
@@ -23744,7 +23859,8 @@ var _TinyCloudNode = class _TinyCloudNode {
23744
23859
  delegateDID: session.verificationMethod,
23745
23860
  ownerAddress: session.address,
23746
23861
  chainId: session.chainId,
23747
- host: this.config.host
23862
+ host: this.config.host,
23863
+ siweProof
23748
23864
  };
23749
23865
  }
23750
23866
  runtimeGrantFromDelegation(delegation, session) {
@@ -23937,6 +24053,9 @@ var _TinyCloudNode = class _TinyCloudNode {
23937
24053
  if (grantedAction === requestedAction) {
23938
24054
  return true;
23939
24055
  }
24056
+ if (isExplicitOnlyAction(requestedAction)) {
24057
+ return false;
24058
+ }
23940
24059
  if (grantedAction.endsWith("/*")) {
23941
24060
  const prefix = grantedAction.slice(0, -2);
23942
24061
  return requestedAction.startsWith(`${prefix}/`);
@@ -24123,7 +24242,10 @@ var _TinyCloudNode = class _TinyCloudNode {
24123
24242
  delegationSession.delegationHeader
24124
24243
  );
24125
24244
  if (!activateResult.success) {
24126
- throw new Error(`Failed to activate delegation: ${activateResult.error}`);
24245
+ throw Object.assign(
24246
+ new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
24247
+ { cause: activateResult }
24248
+ );
24127
24249
  }
24128
24250
  const result = {
24129
24251
  cid: delegationSession.delegationCid,
@@ -24273,7 +24395,10 @@ var _TinyCloudNode = class _TinyCloudNode {
24273
24395
  invokerSession.delegationHeader
24274
24396
  );
24275
24397
  if (!activateResult.success) {
24276
- throw new Error(`Failed to activate delegated session: ${activateResult.error}`);
24398
+ throw Object.assign(
24399
+ new Error(`Failed to activate delegated session: ${describeHostFailure2(activateResult)}`),
24400
+ { cause: activateResult }
24401
+ );
24277
24402
  }
24278
24403
  const session = {
24279
24404
  address: mySession.address,
@@ -24390,7 +24515,10 @@ var _TinyCloudNode = class _TinyCloudNode {
24390
24515
  subDelegationSession.delegationHeader
24391
24516
  );
24392
24517
  if (!activateResult.success) {
24393
- throw new Error(`Failed to activate sub-delegation: ${activateResult.error}`);
24518
+ throw Object.assign(
24519
+ new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
24520
+ { cause: activateResult }
24521
+ );
24394
24522
  }
24395
24523
  return {
24396
24524
  cid: subDelegationSession.delegationCid,
@@ -24459,7 +24587,10 @@ import {
24459
24587
  disableTinyCloudDebug,
24460
24588
  getTinyCloudDebugLogs,
24461
24589
  clearTinyCloudDebugLogs,
24462
- installTinyCloudDebugGlobals
24590
+ installTinyCloudDebugGlobals,
24591
+ isStorageFullError as isStorageFullError2,
24592
+ STORAGE_FULL_MESSAGE as STORAGE_FULL_MESSAGE2,
24593
+ STORAGE_WRITE_TOO_LARGE_MESSAGE as STORAGE_WRITE_TOO_LARGE_MESSAGE2
24463
24594
  } from "@tinycloud/sdk-core";
24464
24595
 
24465
24596
  // src/storage/FileSessionStorage.ts
@@ -24655,6 +24786,29 @@ import {
24655
24786
  decodeBase64Url,
24656
24787
  principalDidEquals as principalDidEquals3
24657
24788
  } from "@tinycloud/sdk-core";
24789
+ var RUNTIME_DELEGATION_REJECTIONS = [
24790
+ "host_mismatch",
24791
+ "expired",
24792
+ "cid_mismatch",
24793
+ "authority_invalid",
24794
+ "proof_missing",
24795
+ "proof_invalid",
24796
+ "owner_mismatch",
24797
+ "audience_mismatch",
24798
+ "resources_mismatch",
24799
+ "unsupported",
24800
+ "activation_rejected"
24801
+ ];
24802
+ var RuntimeDelegationRejectedError = class extends Error {
24803
+ constructor(reason, message) {
24804
+ super(message);
24805
+ this.name = "RuntimeDelegationRejectedError";
24806
+ this.reason = reason;
24807
+ }
24808
+ };
24809
+ function reject(reason, message) {
24810
+ throw new RuntimeDelegationRejectedError(reason, message);
24811
+ }
24658
24812
  var SERVICE_BY_SHORT_NAME = {
24659
24813
  kv: "tinycloud.kv",
24660
24814
  sql: "tinycloud.sql",
@@ -24801,6 +24955,15 @@ function signedAuthorityFromCompactUcan(authorization) {
24801
24955
  abilities
24802
24956
  ));
24803
24957
  }
24958
+ return canonicalSignedAuthority({
24959
+ issuer: payload.iss,
24960
+ audience: payload.aud,
24961
+ expiry,
24962
+ proofs: [...payload.prf],
24963
+ ...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
24964
+ }, permissions);
24965
+ }
24966
+ function canonicalSignedAuthority(signed2, permissions) {
24804
24967
  if (permissions.length === 0) {
24805
24968
  throw new Error("Validated runtime delegation has no signed capabilities.");
24806
24969
  }
@@ -24812,15 +24975,84 @@ function signedAuthorityFromCompactUcan(authorization) {
24812
24975
  actions: [...permission.actions],
24813
24976
  ...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
24814
24977
  }));
24815
- return {
24816
- issuer: payload.iss,
24817
- audience: payload.aud,
24818
- expiry,
24819
- proofs: [...payload.prf],
24820
- ...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth },
24821
- permissions: canonicalPermissions,
24822
- resources: canonicalResources
24823
- };
24978
+ return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
24979
+ }
24980
+ var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
24981
+ var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
24982
+ function comparableSpace(space) {
24983
+ const match = PKH_SPACE.exec(space);
24984
+ return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
24985
+ }
24986
+ function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
24987
+ const proof = delegation.siweProof;
24988
+ if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
24989
+ reject(
24990
+ "proof_missing",
24991
+ "Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
24992
+ );
24993
+ }
24994
+ if (typeof node.verifySessionGrant !== "function") {
24995
+ reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
24996
+ }
24997
+ const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
24998
+ if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
24999
+ reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
25000
+ }
25001
+ let verified;
25002
+ try {
25003
+ verified = node.verifySessionGrant({
25004
+ delegationHeader: { Authorization: authorization },
25005
+ delegationCid: cid,
25006
+ spaceId: delegation.spaceId,
25007
+ address: delegation.ownerAddress,
25008
+ chainId: delegation.chainId,
25009
+ siwe: proof.siwe,
25010
+ signature: proof.signature
25011
+ });
25012
+ } catch (error) {
25013
+ reject("proof_invalid", error instanceof Error ? error.message : String(error));
25014
+ }
25015
+ const space = comparableSpace(delegation.spaceId);
25016
+ const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
25017
+ if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
25018
+ reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
25019
+ }
25020
+ const groups = /* @__PURE__ */ new Map();
25021
+ for (const entry of verified.recap) {
25022
+ const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
25023
+ const raw = entry.space === "encryption";
25024
+ if (raw) {
25025
+ if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
25026
+ reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
25027
+ }
25028
+ const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
25029
+ if (!didPrincipalsMatch(networkOwner, owner)) {
25030
+ reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
25031
+ }
25032
+ } else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
25033
+ reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
25034
+ }
25035
+ const caveats = signedCaveats(entry.caveats ?? []);
25036
+ const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, canonicalizeRecapCaveats2(caveats)]);
25037
+ const group = groups.get(key2) ?? {
25038
+ service,
25039
+ ...raw ? {} : { space: entry.space },
25040
+ path: entry.path,
25041
+ actions: [],
25042
+ ...caveats === void 0 ? {} : { caveats }
25043
+ };
25044
+ for (const action of entry.actions) {
25045
+ if (!group.actions.includes(action)) group.actions.push(action);
25046
+ }
25047
+ groups.set(key2, group);
25048
+ }
25049
+ return canonicalSignedAuthority({
25050
+ issuer: owner,
25051
+ // The verifier bound the SIWE audience to this runtime's own session key.
25052
+ audience: node.sessionDid,
25053
+ expiry: verified.expiresAt,
25054
+ proofs: []
25055
+ }, [...groups.values()]);
24824
25056
  }
24825
25057
  function canonicalResourcesFromPortableDelegation(delegation) {
24826
25058
  if (delegation.resources !== void 0 && delegation.resources.length > 0) {
@@ -24856,46 +25088,58 @@ function resourcesMatch(actual, expected) {
24856
25088
  async function activateValidatedRuntimeDelegation(node, delegation, options) {
24857
25089
  const host = normalizedHost(options.host);
24858
25090
  if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
24859
- throw new Error(
25091
+ reject(
25092
+ "host_mismatch",
24860
25093
  `Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
24861
25094
  );
24862
25095
  }
24863
25096
  if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
24864
- throw new Error("Runtime delegation has an invalid expiry.");
25097
+ reject("authority_invalid", "Runtime delegation has an invalid expiry.");
24865
25098
  }
24866
25099
  if (delegation.expiry.getTime() <= Date.now()) {
24867
- throw new Error("Runtime delegation is expired.");
25100
+ reject("expired", "Runtime delegation is expired.");
24868
25101
  }
24869
25102
  const authorization = delegation.delegationHeader?.Authorization;
24870
25103
  if (typeof authorization !== "string" || authorization.length === 0) {
24871
- throw new Error("Runtime delegation is missing authorization bytes.");
25104
+ reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
24872
25105
  }
24873
25106
  const cid = node.computeDelegationCid(authorization);
24874
25107
  if (cid !== delegation.cid) {
24875
- throw new Error("Runtime delegation CID does not match authorization bytes.");
25108
+ reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
25109
+ }
25110
+ const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
25111
+ let signed2;
25112
+ try {
25113
+ signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
25114
+ } catch (error) {
25115
+ if (error instanceof RuntimeDelegationRejectedError) throw error;
25116
+ reject("authority_invalid", error instanceof Error ? error.message : String(error));
24876
25117
  }
24877
- const signed2 = signedAuthorityFromCompactUcan(authorization);
24878
25118
  if (signed2.expiry.getTime() <= Date.now()) {
24879
- throw new Error("Runtime delegation is expired.");
25119
+ reject("expired", "Runtime delegation is expired.");
24880
25120
  }
24881
25121
  if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
24882
- throw new Error("Runtime delegation expiry does not match signed authority.");
25122
+ reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
24883
25123
  }
24884
25124
  if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
24885
- throw new Error(
25125
+ reject(
25126
+ "audience_mismatch",
24886
25127
  `Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
24887
25128
  );
24888
25129
  }
24889
25130
  if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
24890
- throw new Error("Runtime delegation audience does not match signed authority.");
25131
+ reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
25132
+ }
25133
+ if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
25134
+ reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
24891
25135
  }
24892
- const declaredResources = canonicalResourcesFromPortableDelegation(delegation);
24893
- if (!resourcesMatch(declaredResources, signed2.resources)) {
24894
- throw new Error("Runtime delegation resources do not match signed authority.");
25136
+ if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
25137
+ throw new Error("Runtime delegation is not authorized for this runtime.");
24895
25138
  }
24896
25139
  const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
24897
25140
  if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
24898
- throw new Error(
25141
+ reject(
25142
+ "cid_mismatch",
24899
25143
  "A different authorization is already installed for this runtime delegation CID."
24900
25144
  );
24901
25145
  }
@@ -24925,22 +25169,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
24925
25169
  })),
24926
25170
  expiry: new Date(signed2.expiry),
24927
25171
  delegateDID: signed2.audience,
24928
- host
25172
+ host,
25173
+ ...compact ? {} : { siweProof: delegation.siweProof }
24929
25174
  };
24930
- if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
24931
- await node.useDelegation(installedCandidate);
24932
- } else {
24933
- await node.useRuntimeDelegation(installedCandidate);
25175
+ try {
25176
+ if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
25177
+ await node.useDelegation(installedCandidate);
25178
+ } else {
25179
+ await node.useRuntimeDelegation(installedCandidate);
25180
+ }
25181
+ } catch (error) {
25182
+ reject("activation_rejected", error instanceof Error ? error.message : String(error));
24934
25183
  }
24935
25184
  const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
24936
25185
  if (!installed) {
24937
- throw new Error("Runtime delegation activation did not install the validated authority.");
25186
+ reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
24938
25187
  }
24939
25188
  if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
24940
25189
  canonicalResourcesFromPortableDelegation(installed),
24941
25190
  signed2.resources
24942
25191
  ) || normalizedHost(installed.host ?? "") !== host) {
24943
- throw new Error(
25192
+ reject(
25193
+ "activation_rejected",
24944
25194
  "Runtime delegation activation installed authority that differs from the validated authority."
24945
25195
  );
24946
25196
  }
@@ -25171,9 +25421,13 @@ export {
25171
25421
  PrefixedKVService,
25172
25422
  PrivateKeySigner,
25173
25423
  ProtocolMismatchError,
25424
+ RUNTIME_DELEGATION_REJECTIONS,
25425
+ RuntimeDelegationRejectedError,
25174
25426
  SECRET_NAME_RE,
25175
25427
  SQLAction,
25176
25428
  SQLService3 as SQLService,
25429
+ STORAGE_FULL_MESSAGE2 as STORAGE_FULL_MESSAGE,
25430
+ STORAGE_WRITE_TOO_LARGE_MESSAGE2 as STORAGE_WRITE_TOO_LARGE_MESSAGE,
25177
25431
  SecretsService2 as SecretsService,
25178
25432
  ServiceContext3 as ServiceContext,
25179
25433
  SessionExpiredError2 as SessionExpiredError,
@@ -25249,6 +25503,7 @@ export {
25249
25503
  isCapabilitySubset2 as isCapabilitySubset,
25250
25504
  isEvmAddress,
25251
25505
  isNetworkId,
25506
+ isStorageFullError2 as isStorageFullError,
25252
25507
  loadManifest,
25253
25508
  makePkhSpaceId2 as makePkhSpaceId,
25254
25509
  makePublicSpaceId2 as makePublicSpaceId,