@tinycloud/node-sdk 2.11.0-beta.10 → 2.11.0-beta.12

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.cjs CHANGED
@@ -17025,10 +17025,13 @@ var require_utils2 = __commonJS({
17025
17025
  // src/index.ts
17026
17026
  var index_exports = {};
17027
17027
  __export(index_exports, {
17028
+ ACCEPTED_MARKER_VERSIONS: () => ACCEPTED_MARKER_VERSIONS,
17028
17029
  ACCOUNT_REGISTRY_PATH: () => import_sdk_core12.ACCOUNT_REGISTRY_PATH,
17029
17030
  ACCOUNT_REGISTRY_SPACE: () => import_sdk_core12.ACCOUNT_REGISTRY_SPACE,
17030
17031
  AccountService: () => import_sdk_core3.AccountService,
17031
17032
  AutoApproveSpaceCreationHandler: () => import_sdk_core11.AutoApproveSpaceCreationHandler,
17033
+ BOOTSTRAP_COMPLETION_MARKER_KEY: () => BOOTSTRAP_COMPLETION_MARKER_KEY,
17034
+ BOOTSTRAP_COMPLETION_MARKER_VERSION: () => BOOTSTRAP_COMPLETION_MARKER_VERSION,
17032
17035
  CapabilityKeyRegistry: () => import_sdk_core20.CapabilityKeyRegistry,
17033
17036
  CapabilityKeyRegistryErrorCodes: () => import_sdk_core20.CapabilityKeyRegistryErrorCodes,
17034
17037
  CaveatedDelegationUnsupportedError: () => import_sdk_core12.CaveatedDelegationUnsupportedError,
@@ -17399,6 +17402,16 @@ function addRawAbility(rawAbilities, resource, action) {
17399
17402
  actions.push(action);
17400
17403
  }
17401
17404
  }
17405
+ function cloneAbilitiesMap(actions) {
17406
+ return Object.fromEntries(
17407
+ Object.entries(actions).map(([service, paths]) => [
17408
+ service,
17409
+ Object.fromEntries(
17410
+ Object.entries(paths).map(([path, pathActions]) => [path, [...pathActions]])
17411
+ )
17412
+ ])
17413
+ );
17414
+ }
17402
17415
  var NodeUserAuthorization = class {
17403
17416
  constructor(config) {
17404
17417
  this.activeSessionKeyId = "default";
@@ -17670,23 +17683,41 @@ var NodeUserAuthorization = class {
17670
17683
  const defaultNetworkId = this.defaultEncryptionNetworkId(address, chainId);
17671
17684
  const primarySpaceId2 = (0, import_sdk_core2.makePkhSpaceId)(address, chainId, this.spacePrefix);
17672
17685
  const secretsSpaceId = (0, import_sdk_core2.makePkhSpaceId)(address, chainId, "secrets");
17673
- return {
17674
- abilities: this.defaultActions,
17675
- spaceId: primarySpaceId2,
17676
- spaceAbilities: {
17677
- [primarySpaceId2]: this.defaultActions,
17678
- [secretsSpaceId]: {
17679
- kv: {
17680
- "vault/secrets/": [
17681
- import_sdk_core2.KV.GET,
17682
- import_sdk_core2.KV.PUT,
17683
- import_sdk_core2.KV.DEL,
17684
- import_sdk_core2.KV.LIST,
17685
- import_sdk_core2.KV.METADATA
17686
- ]
17686
+ const primaryActions = this.includeAccountRegistryPermissions && this.spacePrefix === import_sdk_core2.ACCOUNT_REGISTRY_SPACE ? cloneAbilitiesMap(this.defaultActions) : this.defaultActions;
17687
+ const spaceAbilities2 = {
17688
+ [primarySpaceId2]: primaryActions,
17689
+ [secretsSpaceId]: {
17690
+ kv: {
17691
+ "vault/secrets/": [
17692
+ import_sdk_core2.KV.GET,
17693
+ import_sdk_core2.KV.PUT,
17694
+ import_sdk_core2.KV.DEL,
17695
+ import_sdk_core2.KV.LIST,
17696
+ import_sdk_core2.KV.METADATA
17697
+ ]
17698
+ }
17699
+ }
17700
+ };
17701
+ if (this.includeAccountRegistryPermissions && this.spacePrefix !== import_sdk_core2.ACCOUNT_REGISTRY_SPACE) {
17702
+ spaceAbilities2[(0, import_sdk_core2.makePkhSpaceId)(address, chainId, import_sdk_core2.ACCOUNT_REGISTRY_SPACE)] = (0, import_sdk_core2.resourceCapabilitiesToAbilitiesMap)(import_sdk_core2.ACCOUNT_MANIFEST_PERMISSIONS);
17703
+ } else if (this.includeAccountRegistryPermissions) {
17704
+ const accountAbilities = (0, import_sdk_core2.resourceCapabilitiesToAbilitiesMap)(
17705
+ import_sdk_core2.ACCOUNT_MANIFEST_PERMISSIONS
17706
+ );
17707
+ for (const [service, paths] of Object.entries(accountAbilities)) {
17708
+ const existingPaths = primaryActions[service] ?? (primaryActions[service] = {});
17709
+ for (const [path, actions] of Object.entries(paths)) {
17710
+ const existingActions = existingPaths[path] ?? (existingPaths[path] = []);
17711
+ for (const action of actions) {
17712
+ if (!existingActions.includes(action)) existingActions.push(action);
17687
17713
  }
17688
17714
  }
17689
- },
17715
+ }
17716
+ }
17717
+ return {
17718
+ abilities: primaryActions,
17719
+ spaceId: primarySpaceId2,
17720
+ spaceAbilities: spaceAbilities2,
17690
17721
  rawAbilities: {
17691
17722
  [defaultNetworkId]: [DECRYPT_ACTION, NETWORK_CREATE_ACTION]
17692
17723
  }
@@ -19149,6 +19180,9 @@ var DEFAULT_HOST = "https://node.tinycloud.xyz";
19149
19180
  var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
19150
19181
  var NETWORK_CREATE_ACTION2 = import_sdk_core7.ENCRYPTION.NETWORK_CREATE;
19151
19182
  var DECRYPT_ACTION2 = import_sdk_core7.ENCRYPTION.DECRYPT;
19183
+ var BOOTSTRAP_COMPLETION_MARKER_KEY = "system/bootstrap/complete";
19184
+ var BOOTSTRAP_COMPLETION_MARKER_VERSION = 1;
19185
+ var ACCEPTED_MARKER_VERSIONS = [BOOTSTRAP_COMPLETION_MARKER_VERSION];
19152
19186
  var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
19153
19187
  function isSecretPayload(value) {
19154
19188
  return typeof value === "object" && value !== null && "value" in value && typeof value.value === "string" && "createdAt" in value && typeof value.createdAt === "string" && "updatedAt" in value && typeof value.updatedAt === "string";
@@ -19556,9 +19590,12 @@ var _TinyCloudNode = class _TinyCloudNode {
19556
19590
  this._bootstrapSkipped = false;
19557
19591
  /**
19558
19592
  * Outcome of the last signIn()'s account-bootstrap attempt. `skipped` is
19559
- * true when bootstrap did not complete (interactive signer, auto-sign
19560
- * denied, or a bootstrap step failed); `reason` carries the cause so apps
19561
- * can surface a "finish account setup" call-to-action. `warnings` is
19593
+ * true when bootstrap did not complete in this invocation (interactive signer,
19594
+ * auto-bootstrap disabled, already provisioned, or a decision/provisioning
19595
+ * step failed). `already-provisioned` means the bootstrap was not run here;
19596
+ * it does not mean a prior provisioning attempt failed to complete.
19597
+ * `reason` carries the cause so apps can surface a "finish account setup"
19598
+ * call-to-action. `warnings` is
19562
19599
  * present when bootstrap completed, but one or more steps recovered from
19563
19600
  * an ambiguous failure (e.g. a KV batch write reconciled via per-space
19564
19601
  * fallback) — clean vs. recovered runs are otherwise byte-identical.
@@ -19741,7 +19778,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19741
19778
  nonce: config.nonce,
19742
19779
  siweConfig: config.siweConfig,
19743
19780
  manifest: useBootstrapSignInRequest ? void 0 : config.manifest,
19744
- capabilityRequest: useBootstrapSignInRequest ? import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : config.capabilityRequest,
19781
+ capabilityRequest: useBootstrapSignInRequest ? config.includeAccountRegistryPermissions === false ? import_sdk_core7.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : config.capabilityRequest,
19745
19782
  includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : config.includeAccountRegistryPermissions
19746
19783
  });
19747
19784
  this.tc = new import_sdk_core7.TinyCloud(this.auth, {
@@ -19984,6 +20021,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19984
20021
  this._bootstrapSkipped = false;
19985
20022
  this._bootstrapStatus = { skipped: false };
19986
20023
  if (this.config.autoBootstrapAccount === false) {
20024
+ this._bootstrapStatus = { skipped: true, reason: "auto-bootstrap-disabled" };
19987
20025
  return false;
19988
20026
  }
19989
20027
  if (!this.auth || !this._address) {
@@ -19998,11 +20036,14 @@ var _TinyCloudNode = class _TinyCloudNode {
19998
20036
  return false;
19999
20037
  }
20000
20038
  const steps = (0, import_sdk_core7.bootstrapSteps)(this._address, this._chainId);
20001
- if (!await this.isFreshBootstrapAccount(steps)) {
20002
- return false;
20003
- }
20004
20039
  try {
20005
- const warnings = await this.runAccountBootstrap(steps);
20040
+ const decision = await this.resolveBootstrapDecision(steps);
20041
+ if (decision.action === "skip") {
20042
+ this._bootstrapStatus = { skipped: true, reason: "already-provisioned" };
20043
+ return false;
20044
+ }
20045
+ const warnings = await this.runAccountBootstrap(steps, { mode: decision.mode });
20046
+ await this.writeBootstrapCompletionMarker(steps);
20006
20047
  if (warnings.length > 0) {
20007
20048
  this._bootstrapStatus = { skipped: false, warnings };
20008
20049
  this.notificationHandler.warning(
@@ -20021,32 +20062,92 @@ var _TinyCloudNode = class _TinyCloudNode {
20021
20062
  }
20022
20063
  return true;
20023
20064
  }
20024
- async isFreshBootstrapAccount(steps) {
20065
+ async resolveBootstrapDecision(steps) {
20025
20066
  const enshrinedSpaceIds = /* @__PURE__ */ new Set();
20026
20067
  for (const step of steps) {
20027
20068
  if (step.kind === "session") {
20028
20069
  enshrinedSpaceIds.add(step.spaceId);
20029
20070
  }
20030
20071
  }
20031
- const skipped = this.auth.lastActivationSkippedSpaceIds;
20072
+ const auth = this.auth;
20073
+ if (!auth) {
20074
+ throw new Error("Account bootstrap requires an active wallet session");
20075
+ }
20076
+ const skipped = auth.lastActivationSkippedSpaceIds;
20032
20077
  if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
20033
- return true;
20078
+ return { action: "run", mode: "fresh" };
20034
20079
  }
20035
20080
  try {
20036
- const indexed = await this.account.index.spaces.list();
20037
- if (indexed.ok && indexed.data.length === 0) {
20038
- return true;
20081
+ const accountSpaceId = this.ownedSpaceId(import_sdk_core7.ACCOUNT_REGISTRY_SPACE);
20082
+ const markerPermission = {
20083
+ service: "tinycloud.kv",
20084
+ space: accountSpaceId,
20085
+ path: BOOTSTRAP_COMPLETION_MARKER_KEY,
20086
+ actions: ["get"]
20087
+ };
20088
+ if (!this.hasRuntimePermissions([markerPermission])) {
20089
+ return { action: "run", mode: "repair" };
20039
20090
  }
20040
- } catch {
20091
+ const marker = await this.readBootstrapCompletionMarker();
20092
+ if (marker.ok) {
20093
+ if (this.isAcceptedBootstrapCompletionMarker(marker.data.data)) {
20094
+ return { action: "skip" };
20095
+ }
20096
+ return { action: "run", mode: "repair" };
20097
+ }
20098
+ if (marker.error.code === import_sdk_core7.ErrorCodes.KV_NOT_FOUND && this.markerReadIsUnhostedSpace(marker.error.meta)) {
20099
+ return { action: "run", mode: "fresh" };
20100
+ }
20101
+ } catch (err) {
20102
+ const reason = err instanceof Error ? err.message : String(err);
20103
+ this.notificationHandler.warning(
20104
+ `Account bootstrap decision failed; attempting one bounded repair: ${reason}`
20105
+ );
20106
+ console.warn(`[TinyCloudNode] account bootstrap decision failed: ${reason}`);
20107
+ return { action: "run", mode: "repair" };
20041
20108
  }
20042
- try {
20043
- const spaces = await this.account.spaces.list();
20044
- return spaces.ok && spaces.data.length === 0;
20045
- } catch {
20046
- return false;
20109
+ return { action: "run", mode: "repair" };
20110
+ }
20111
+ async readBootstrapCompletionMarker() {
20112
+ return this.kvForSpace(this.ownedSpaceId(import_sdk_core7.ACCOUNT_REGISTRY_SPACE)).get(
20113
+ BOOTSTRAP_COMPLETION_MARKER_KEY
20114
+ );
20115
+ }
20116
+ async writeBootstrapCompletionMarker(steps) {
20117
+ if (!this._address) {
20118
+ throw new Error("Bootstrap completion marker requires an active wallet session");
20119
+ }
20120
+ const canonicalStepIds = new Set(
20121
+ (0, import_sdk_core7.bootstrapSteps)(this._address, this._chainId).map((step) => step.id)
20122
+ );
20123
+ const providedStepIds = new Set(steps.map((step) => step.id));
20124
+ if (canonicalStepIds.size !== providedStepIds.size || [...canonicalStepIds].some((stepId) => !providedStepIds.has(stepId))) {
20125
+ throw new Error("Bootstrap completion marker requires the canonical bootstrap step set");
20126
+ }
20127
+ const marker = {
20128
+ v: BOOTSTRAP_COMPLETION_MARKER_VERSION,
20129
+ stepIds: [...canonicalStepIds],
20130
+ completedAt: (/* @__PURE__ */ new Date()).toISOString()
20131
+ };
20132
+ const written = await this.kvForSpace(this.ownedSpaceId(import_sdk_core7.ACCOUNT_REGISTRY_SPACE)).put(
20133
+ BOOTSTRAP_COMPLETION_MARKER_KEY,
20134
+ marker
20135
+ );
20136
+ if (!written.ok) {
20137
+ throw new Error(`Failed to write bootstrap completion marker: ${written.error.message}`);
20047
20138
  }
20048
20139
  }
20049
- async runAccountBootstrap(steps) {
20140
+ isAcceptedBootstrapCompletionMarker(value) {
20141
+ if (typeof value !== "object" || value === null) return false;
20142
+ const entries = Object.entries(value);
20143
+ const markerValue = (name) => entries.find(([key2]) => key2 === name)?.[1];
20144
+ const version23 = markerValue("v");
20145
+ return typeof version23 === "number" && Number.isInteger(version23) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version23);
20146
+ }
20147
+ markerReadIsUnhostedSpace(meta) {
20148
+ return meta?.status === 404;
20149
+ }
20150
+ async runAccountBootstrap(steps, { mode } = { mode: "fresh" }) {
20050
20151
  if (!this.auth || !this._address) {
20051
20152
  throw new Error("Account bootstrap requires an active wallet session");
20052
20153
  }
@@ -20147,9 +20248,8 @@ var _TinyCloudNode = class _TinyCloudNode {
20147
20248
  if (step.kind === "seed-applications") {
20148
20249
  const registered = await this.account.applications.register(
20149
20250
  step.manifests.length > 0 ? [...step.manifests] : import_sdk_core7.TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
20150
- // Bootstrap only runs on an account with no registry records, so the
20151
- // manifest-hash pre-read is definitionally a miss. Skip it; the write
20152
- // it guards is an INSERT OR REPLACE and is safe to repeat.
20251
+ // The write is an INSERT OR REPLACE and is safe to repeat during a
20252
+ // repair, so skip the manifest-hash pre-read.
20153
20253
  { assumeUnregistered: true }
20154
20254
  );
20155
20255
  if (!registered.ok) {
@@ -20157,7 +20257,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20157
20257
  }
20158
20258
  }
20159
20259
  if (step.kind === "encryption-network-create") {
20160
- await this.ensureEncryptionNetwork(step.networkId, { assumeMissing: true });
20260
+ await this.ensureEncryptionNetwork(step.networkId, { assumeMissing: mode === "fresh" });
20161
20261
  }
20162
20262
  if (step.kind === "secret-records-schema") {
20163
20263
  const db = this.sqlForSpace(step.spaceId).db(step.database);
@@ -21206,7 +21306,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21206
21306
  nonce: this.config.nonce,
21207
21307
  siweConfig: this.config.siweConfig,
21208
21308
  manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
21209
- capabilityRequest: useBootstrapSignInRequest ? import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
21309
+ capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ? import_sdk_core7.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
21210
21310
  includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions
21211
21311
  });
21212
21312
  this.tc = new import_sdk_core7.TinyCloud(this.auth, {
@@ -21259,7 +21359,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21259
21359
  nonce: this.config.nonce,
21260
21360
  siweConfig: this.config.siweConfig,
21261
21361
  manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
21262
- capabilityRequest: useBootstrapSignInRequest ? import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
21362
+ capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ? import_sdk_core7.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core7.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
21263
21363
  includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions
21264
21364
  });
21265
21365
  this.tc = new import_sdk_core7.TinyCloud(this.auth, {
@@ -24008,35 +24108,44 @@ var _TinyCloudNode = class _TinyCloudNode {
24008
24108
  if (parentDelegation.disableSubDelegation) {
24009
24109
  throw new Error("Parent delegation does not allow sub-delegation");
24010
24110
  }
24011
- if (!params.path.startsWith(parentDelegation.path)) {
24111
+ const parentResources = parentDelegation.resources ?? [{
24112
+ service: parentDelegation.actions[0]?.split("/", 1)[0]?.replace(/^tinycloud\./, "") ?? "kv",
24113
+ space: parentDelegation.spaceId,
24114
+ path: parentDelegation.path,
24115
+ actions: parentDelegation.actions
24116
+ }];
24117
+ const requestedResources = params.resources ?? [{
24118
+ service: params.actions[0]?.split("/", 1)[0]?.replace(/^tinycloud\./, "") ?? "kv",
24119
+ space: parentDelegation.spaceId,
24120
+ path: params.path,
24121
+ actions: params.actions
24122
+ }];
24123
+ const resourceIsContained = (parent, child) => {
24124
+ const parentEncryption = parent.service === "encryption" || parent.service === "tinycloud.encryption";
24125
+ const childEncryption = child.service === "encryption" || child.service === "tinycloud.encryption";
24126
+ if (parentEncryption || childEncryption) return parentEncryption && childEncryption && parent.path === child.path && child.actions.every((action) => parent.actions.includes(action));
24127
+ const pathContained = parent.path === child.path || parent.path.endsWith("/") && child.path.startsWith(parent.path) || child.path.startsWith(`${parent.path}/`);
24128
+ return pathContained && child.actions.every((action) => parent.actions.includes(action));
24129
+ };
24130
+ if (requestedResources.length === 0 || requestedResources.some((child) => !parentResources.some((parent) => resourceIsContained(parent, child)))) {
24012
24131
  throw new Error(
24013
- `Sub-delegation path "${params.path}" must be within parent path "${parentDelegation.path}"`
24132
+ "Sub-delegation resources exceed the received delegation"
24014
24133
  );
24015
24134
  }
24016
- const parentActions = new Set(parentDelegation.actions);
24017
- for (const action of params.actions) {
24018
- if (!parentActions.has(action)) {
24019
- throw new Error(
24020
- `Sub-delegation action "${action}" is not in parent's actions: ${parentDelegation.actions.join(", ")}`
24021
- );
24022
- }
24023
- }
24024
24135
  const now = /* @__PURE__ */ new Date();
24025
24136
  const expiryMs = params.expiryMs ?? 60 * 60 * 1e3;
24026
24137
  const requestedExpiry = new Date(now.getTime() + expiryMs);
24027
24138
  const actualExpiry = requestedExpiry > parentDelegation.expiry ? parentDelegation.expiry : requestedExpiry;
24028
24139
  const abilities = {};
24029
- const kvActions = params.actions.filter((a) => a.startsWith("tinycloud.kv/"));
24030
- const sqlActions = params.actions.filter((a) => a.startsWith("tinycloud.sql/"));
24031
- const duckdbActions = params.actions.filter((a) => a.startsWith("tinycloud.duckdb/"));
24032
- if (kvActions.length > 0) {
24033
- abilities.kv = { [params.path]: kvActions };
24034
- }
24035
- if (sqlActions.length > 0) {
24036
- abilities.sql = { [params.path]: sqlActions };
24037
- }
24038
- if (duckdbActions.length > 0) {
24039
- abilities.duckdb = { [params.path]: duckdbActions };
24140
+ const rawAbilities = {};
24141
+ for (const resource of requestedResources) {
24142
+ const service = resource.service.replace(/^tinycloud\./, "");
24143
+ if (service === "encryption") {
24144
+ rawAbilities[resource.path] = [...resource.actions];
24145
+ continue;
24146
+ }
24147
+ abilities[service] ?? (abilities[service] = {});
24148
+ abilities[service][resource.path] = [...resource.actions];
24040
24149
  }
24041
24150
  const targetHost = parentDelegation.host ?? this.config.host;
24042
24151
  const prepared = this.wasmBindings.prepareSession({
@@ -24048,7 +24157,8 @@ var _TinyCloudNode = class _TinyCloudNode {
24048
24157
  expirationTime: actualExpiry.toISOString(),
24049
24158
  spaceId: parentDelegation.spaceId,
24050
24159
  delegateUri: params.delegateDID,
24051
- parents: [parentDelegation.cid]
24160
+ parents: [parentDelegation.cid],
24161
+ ...Object.keys(rawAbilities).length > 0 ? { rawAbilities } : {}
24052
24162
  });
24053
24163
  const signature2 = await this.signer.signMessage(prepared.siwe);
24054
24164
  const subDelegationSession = this.wasmBindings.completeSessionSetup({
@@ -24066,14 +24176,20 @@ var _TinyCloudNode = class _TinyCloudNode {
24066
24176
  cid: subDelegationSession.delegationCid,
24067
24177
  delegationHeader: subDelegationSession.delegationHeader,
24068
24178
  spaceId: parentDelegation.spaceId,
24069
- path: params.path,
24070
- actions: params.actions,
24179
+ path: requestedResources[0].path,
24180
+ actions: requestedResources[0].actions,
24071
24181
  disableSubDelegation: params.disableSubDelegation ?? false,
24072
24182
  expiry: actualExpiry,
24073
24183
  delegateDID: params.delegateDID,
24074
24184
  ownerAddress: parentDelegation.ownerAddress,
24075
24185
  chainId: parentDelegation.chainId,
24076
- host: targetHost
24186
+ host: targetHost,
24187
+ resources: requestedResources.map((resource) => ({
24188
+ service: resource.service.replace(/^tinycloud\./, ""),
24189
+ space: resource.service.replace(/^tinycloud\./, "") === "encryption" ? "encryption" : resource.space ?? parentDelegation.spaceId,
24190
+ path: resource.path,
24191
+ actions: [...resource.actions]
24192
+ }))
24077
24193
  };
24078
24194
  }
24079
24195
  };
@@ -24352,6 +24468,14 @@ function signedAuthorityFromCompactUcan(authorization) {
24352
24468
  if (typeof payload.aud !== "string" || payload.aud.length === 0) {
24353
24469
  throw new Error("Validated runtime delegation is missing a signed audience.");
24354
24470
  }
24471
+ if (typeof payload.iss !== "string" || payload.iss.length === 0) {
24472
+ throw new Error("Validated runtime delegation is missing a signed issuer.");
24473
+ }
24474
+ if (!Array.isArray(payload.prf) || payload.prf.some(
24475
+ (proof) => typeof proof !== "string" || proof.length === 0
24476
+ )) {
24477
+ throw new Error("Validated runtime delegation has malformed signed proofs.");
24478
+ }
24355
24479
  if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
24356
24480
  throw new Error("Validated runtime delegation is missing a signed expiry.");
24357
24481
  }
@@ -24362,6 +24486,11 @@ function signedAuthorityFromCompactUcan(authorization) {
24362
24486
  if (payload.att === null || typeof payload.att !== "object" || Array.isArray(payload.att)) {
24363
24487
  throw new Error("Validated runtime delegation is missing a signed attenuation.");
24364
24488
  }
24489
+ const fact = Array.isArray(payload.fct) && payload.fct.length > 0 && payload.fct[0] !== null && typeof payload.fct[0] === "object" && !Array.isArray(payload.fct[0]) ? payload.fct[0] : void 0;
24490
+ const remainingRedelegationDepth = fact?.remainingRedelegationDepth;
24491
+ if (remainingRedelegationDepth !== void 0 && (!Number.isInteger(remainingRedelegationDepth) || remainingRedelegationDepth < 0 || remainingRedelegationDepth > 8)) {
24492
+ throw new Error("Validated runtime delegation has invalid signed redelegation depth.");
24493
+ }
24365
24494
  const permissions = [];
24366
24495
  for (const [resource, abilities] of Object.entries(payload.att)) {
24367
24496
  if (abilities === null || typeof abilities !== "object" || Array.isArray(abilities)) {
@@ -24412,8 +24541,11 @@ function signedAuthorityFromCompactUcan(authorization) {
24412
24541
  ...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
24413
24542
  }));
24414
24543
  return {
24544
+ issuer: payload.iss,
24415
24545
  audience: payload.aud,
24416
24546
  expiry,
24547
+ proofs: [...payload.prf],
24548
+ ...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth },
24417
24549
  permissions: canonicalPermissions,
24418
24550
  resources: canonicalResources
24419
24551
  };
@@ -24504,6 +24636,13 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
24504
24636
  delegationHeader: { Authorization: authorization },
24505
24637
  ownerAddress: delegation.ownerAddress,
24506
24638
  chainId: delegation.chainId,
24639
+ delegatorDID: signed2.issuer,
24640
+ ...signed2.proofs.length === 1 ? { parentCid: signed2.proofs[0] } : {},
24641
+ ...signed2.remainingRedelegationDepth === void 0 ? {} : {
24642
+ allowSubDelegation: signed2.remainingRedelegationDepth > 0,
24643
+ disableSubDelegation: signed2.remainingRedelegationDepth === 0
24644
+ },
24645
+ authHeader: authorization,
24507
24646
  spaceId: signedSpace ?? delegation.spaceId,
24508
24647
  path: primary.path,
24509
24648
  actions: [...primary.actions],
@@ -24597,10 +24736,13 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
24597
24736
  var import_sdk_core23 = require("@tinycloud/sdk-core");
24598
24737
  // Annotate the CommonJS export names for ESM import in node:
24599
24738
  0 && (module.exports = {
24739
+ ACCEPTED_MARKER_VERSIONS,
24600
24740
  ACCOUNT_REGISTRY_PATH,
24601
24741
  ACCOUNT_REGISTRY_SPACE,
24602
24742
  AccountService,
24603
24743
  AutoApproveSpaceCreationHandler,
24744
+ BOOTSTRAP_COMPLETION_MARKER_KEY,
24745
+ BOOTSTRAP_COMPLETION_MARKER_VERSION,
24604
24746
  CapabilityKeyRegistry,
24605
24747
  CapabilityKeyRegistryErrorCodes,
24606
24748
  CaveatedDelegationUnsupportedError,