@tinycloud/node-sdk 3.1.0-beta.11 → 3.1.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
@@ -19735,15 +19735,21 @@ var _TinyCloudNode = class _TinyCloudNode {
19735
19735
  if (!this.wasmBindings.invokeAny) {
19736
19736
  throw new Error("WASM binding does not support invokeAny");
19737
19737
  }
19738
- const operations = entries.flatMap((entry) => {
19738
+ const routedEntries = entries;
19739
+ const operations = routedEntries.flatMap((entry) => {
19739
19740
  const operation = this.operationFromInvokeAnyEntry(entry);
19740
19741
  return operation ? [operation] : [];
19741
19742
  });
19742
- const grant = this.findGrantForOperations(operations);
19743
- const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
19744
- const caveatPreservingEntries = grant ? entries.map((entry) => {
19743
+ const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
19744
+ const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
19745
+ if (authorityCid !== void 0 && !explicitGrant) {
19746
+ throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
19747
+ }
19748
+ const grant = explicitGrant ?? this.findGrantForOperations(operations);
19749
+ const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
19750
+ const caveatPreservingEntries = routedEntries.map(({ revokeAuthorityCid: _cid, ...entry }) => {
19745
19751
  const requested = this.operationFromInvokeAnyEntry(entry);
19746
- const granted = requested && grant.operations.find(
19752
+ const granted = grant && requested && grant.operations.find(
19747
19753
  (candidate) => this.operationCovers(candidate, requested)
19748
19754
  );
19749
19755
  if (!granted?.caveats?.length) {
@@ -19753,7 +19759,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19753
19759
  throw new Error("Invocation caveats do not match signed ReCap authority.");
19754
19760
  }
19755
19761
  return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
19756
- }) : entries;
19762
+ });
19757
19763
  return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
19758
19764
  };
19759
19765
  this.explicitHost = config.host;
@@ -21099,6 +21105,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21099
21105
  stagedSessionExpiry,
21100
21106
  stagedRecap
21101
21107
  );
21108
+ const stagedAccountSpaceId = stagedAddress ? this.wasmBindings.makeSpaceId(stagedAddress, stagedChainId, import_sdk_core7.ACCOUNT_REGISTRY_SPACE) : void 0;
21102
21109
  const stagedGraph = this.stageRestoredServiceGraph({
21103
21110
  host: stagedHost,
21104
21111
  manager: stagedManager,
@@ -21107,6 +21114,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21107
21114
  nodeDid: stagedNodeDid,
21108
21115
  address: stagedAddress,
21109
21116
  chainId: stagedChainId,
21117
+ accountSpaceId: stagedAccountSpaceId,
21110
21118
  tinyCloudSession: stagedTcSession,
21111
21119
  sessionExpiry: stagedSessionExpiry,
21112
21120
  recap: stagedRecap
@@ -21272,6 +21280,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21272
21280
  }
21273
21281
  const delegationManager = new import_sdk_core7.DelegationManager({
21274
21282
  hosts: [input.host],
21283
+ accountSpaceId: input.accountSpaceId,
21275
21284
  session: input.serviceSession,
21276
21285
  invoke: graph.invoke,
21277
21286
  invokeAny: graph.invokeAny,
@@ -22976,6 +22985,14 @@ var _TinyCloudNode = class _TinyCloudNode {
22976
22985
  delegation.delegationHeader
22977
22986
  );
22978
22987
  if (!activateResult.success) {
22988
+ if (this.operationsFromDelegation(delegation).some(
22989
+ (operation) => operation.resource?.startsWith("urn:cid:") === true && operation.service === "delegation" && operation.action === "tinycloud.delegation/revoke"
22990
+ ) && activateResult.status === 401 && /Cannot find parent delegation/i.test(activateResult.error ?? "")) {
22991
+ throw Object.assign(
22992
+ new Error("The host cannot activate a root raw-CID revoke authority without a parent delegation."),
22993
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: activateResult }
22994
+ );
22995
+ }
22979
22996
  throw Object.assign(
22980
22997
  new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
22981
22998
  { cause: activateResult }
@@ -23023,10 +23040,10 @@ var _TinyCloudNode = class _TinyCloudNode {
23023
23040
  }
23024
23041
  this.assertDelegationCaveatsPreservable(expanded);
23025
23042
  const rawEntries = expanded.filter(
23026
- (entry) => this.isEncryptionPermissionEntry(entry)
23043
+ (entry) => this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry)
23027
23044
  );
23028
23045
  const spaceEntries = expanded.filter(
23029
- (entry) => !this.isEncryptionPermissionEntry(entry)
23046
+ (entry) => !this.isEncryptionPermissionEntry(entry) && !this.isRawRevocationPermissionEntry(entry)
23030
23047
  );
23031
23048
  const bySpace = /* @__PURE__ */ new Map();
23032
23049
  for (const entry of spaceEntries) {
@@ -23053,17 +23070,29 @@ var _TinyCloudNode = class _TinyCloudNode {
23053
23070
  }
23054
23071
  const delegatedEntries = [...entries, ...rawForDelegation];
23055
23072
  const abilities = this.permissionsToAbilities(entries);
23056
- const prepared = this.wasmBindings.prepareSession({
23057
- abilities,
23058
- ...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
23059
- address: this.wasmBindings.ensureEip55(session.address),
23060
- chainId: session.chainId,
23061
- domain: this.siweDomain,
23062
- issuedAt: now.toISOString(),
23063
- expirationTime: expiresAt.toISOString(),
23064
- spaceId,
23065
- jwk: session.jwk
23066
- });
23073
+ const prepared = (() => {
23074
+ try {
23075
+ return this.wasmBindings.prepareSession({
23076
+ abilities,
23077
+ ...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
23078
+ address: this.wasmBindings.ensureEip55(session.address),
23079
+ chainId: session.chainId,
23080
+ domain: this.siweDomain,
23081
+ issuedAt: now.toISOString(),
23082
+ expirationTime: expiresAt.toISOString(),
23083
+ spaceId,
23084
+ jwk: session.jwk
23085
+ });
23086
+ } catch (error) {
23087
+ if (rawForDelegation.some((entry) => this.isRawRevocationPermissionEntry(entry)) && /invalid ReCap resource URI/i.test(error instanceof Error ? error.message : String(error))) {
23088
+ throw Object.assign(
23089
+ new Error("This WASM build cannot encode raw urn:cid ReCap resources."),
23090
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: error }
23091
+ );
23092
+ }
23093
+ throw error;
23094
+ }
23095
+ })();
23067
23096
  const signature2 = await this.signer.signMessage(prepared.siwe);
23068
23097
  const delegatedSession = this.wasmBindings.completeSessionSetup({
23069
23098
  ...prepared,
@@ -23074,6 +23103,12 @@ var _TinyCloudNode = class _TinyCloudNode {
23074
23103
  delegatedSession.delegationHeader
23075
23104
  );
23076
23105
  if (!activateResult.success) {
23106
+ if (rawForDelegation.some((entry) => this.isRawRevocationPermissionEntry(entry)) && activateResult.status === 401 && /Cannot find parent delegation/i.test(activateResult.error ?? "")) {
23107
+ throw Object.assign(
23108
+ new Error("The host cannot activate a root raw-CID revoke authority without a parent delegation."),
23109
+ { code: "RAW_RECAP_RESOURCE_UNSUPPORTED", cause: activateResult }
23110
+ );
23111
+ }
23077
23112
  throw Object.assign(
23078
23113
  new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
23079
23114
  { cause: activateResult }
@@ -23775,6 +23810,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23775
23810
  permissionsToAbilities(entries) {
23776
23811
  const abilities = {};
23777
23812
  for (const entry of entries) {
23813
+ if (this.isRawRevocationPermissionEntry(entry)) continue;
23778
23814
  const service = this.shortServiceName(entry.service);
23779
23815
  abilities[service] ?? (abilities[service] = {});
23780
23816
  const existing = abilities[service][entry.path] ?? [];
@@ -23792,9 +23828,16 @@ var _TinyCloudNode = class _TinyCloudNode {
23792
23828
  isEncryptionPermissionEntry(entry) {
23793
23829
  return entry.service === import_sdk_core7.ENCRYPTION_PERMISSION_SERVICE && this.isEncryptionNetworkOperation("encryption", entry.path, entry.space);
23794
23830
  }
23831
+ isRawRevocationPermissionEntry(entry) {
23832
+ return entry.service === "tinycloud.delegation" && entry.path === "" && entry.space?.startsWith("urn:cid:") === true && entry.actions.includes("tinycloud.delegation/revoke");
23833
+ }
23795
23834
  permissionsToRawAbilities(entries) {
23796
23835
  const rawAbilities = {};
23797
23836
  for (const entry of entries) {
23837
+ if (this.isRawRevocationPermissionEntry(entry)) {
23838
+ rawAbilities[entry.space] = [...new Set(entry.actions)];
23839
+ continue;
23840
+ }
23798
23841
  if (!this.isEncryptionPermissionEntry(entry)) {
23799
23842
  continue;
23800
23843
  }
@@ -23814,7 +23857,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23814
23857
  return entries.flatMap((entry) => {
23815
23858
  const service = this.shortServiceName(entry.service);
23816
23859
  return entry.actions.map((action) => ({
23817
- ...this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
23860
+ ...this.isRawRevocationPermissionEntry(entry) ? { resource: entry.space } : this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
23818
23861
  service,
23819
23862
  path: entry.path,
23820
23863
  action,
@@ -23824,11 +23867,13 @@ var _TinyCloudNode = class _TinyCloudNode {
23824
23867
  }
23825
23868
  /** Raw network authority cannot be covered by a nested encryption space. */
23826
23869
  signedCapabilitySubset(requested, granted) {
23827
- const rawGranted = granted.filter((entry) => this.isEncryptionPermissionEntry(entry)).map((entry) => ({ ...entry, space: "encryption" }));
23828
- const spaceGranted = granted.filter((entry) => !this.isEncryptionPermissionEntry(entry));
23870
+ const rawGranted = granted.filter((entry) => this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry)).map((entry) => this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry);
23871
+ const spaceGranted = granted.filter(
23872
+ (entry) => !this.isEncryptionPermissionEntry(entry) && !this.isRawRevocationPermissionEntry(entry)
23873
+ );
23829
23874
  const missing = requested.filter((entry) => {
23830
- const raw = this.isEncryptionPermissionEntry(entry);
23831
- const comparable = raw ? { ...entry, space: "encryption" } : entry;
23875
+ const raw = this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry);
23876
+ const comparable = raw && this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry;
23832
23877
  return !(0, import_sdk_core7.isCapabilitySubset)([comparable], raw ? rawGranted : spaceGranted).subset;
23833
23878
  });
23834
23879
  return { subset: missing.length === 0, missing };
@@ -23843,10 +23888,11 @@ var _TinyCloudNode = class _TinyCloudNode {
23843
23888
  }
23844
23889
  permissionEntriesToOperations(entries, session) {
23845
23890
  return entries.flatMap((entry) => {
23846
- const spaceId = this.resolvePermissionSpace(entry.space, session);
23891
+ const rawRevocation = this.isRawRevocationPermissionEntry(entry);
23892
+ const spaceId = rawRevocation ? void 0 : this.resolvePermissionSpace(entry.space, session);
23847
23893
  const service = this.shortServiceName(entry.service);
23848
23894
  return entry.actions.map((action) => ({
23849
- ...this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
23895
+ ...rawRevocation ? { resource: entry.space } : this.isEncryptionNetworkOperation(service, entry.path, entry.space) ? { resource: entry.path } : { spaceId },
23850
23896
  service,
23851
23897
  path: entry.path,
23852
23898
  action,
@@ -23925,7 +23971,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23925
23971
  delegatedResourcesForEntries(entries, spaceId) {
23926
23972
  return entries.map((entry) => ({
23927
23973
  service: this.shortServiceName(entry.service),
23928
- space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
23974
+ space: this.isRawRevocationPermissionEntry(entry) ? entry.space : this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
23929
23975
  path: entry.path,
23930
23976
  actions: [...entry.actions],
23931
23977
  ...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
@@ -23935,8 +23981,9 @@ var _TinyCloudNode = class _TinyCloudNode {
23935
23981
  const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
23936
23982
  return resources.flatMap((resource) => {
23937
23983
  const service = this.invocationServiceName(resource.service);
23984
+ const rawRevocation = service === "delegation" && resource.space.startsWith("urn:cid:") && resource.path === "";
23938
23985
  return resource.actions.map((action) => ({
23939
- ...this.isEncryptionNetworkOperation(service, resource.path, resource.space) ? { resource: resource.path } : { spaceId: resource.space },
23986
+ ...rawRevocation ? { resource: resource.space } : this.isEncryptionNetworkOperation(service, resource.path, resource.space) ? { resource: resource.path } : { spaceId: resource.space },
23940
23987
  service,
23941
23988
  path: resource.path,
23942
23989
  action,
@@ -23982,7 +24029,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23982
24029
  * @internal
23983
24030
  */
23984
24031
  buildActivationAbilities(delegation) {
23985
- var _a, _b, _c;
24032
+ var _a, _b, _c, _d;
23986
24033
  const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
23987
24034
  const abilities = {};
23988
24035
  const rawAbilities = {};
@@ -24002,13 +24049,18 @@ var _TinyCloudNode = class _TinyCloudNode {
24002
24049
  addActions(rawAbilities[resource.path], resource.actions);
24003
24050
  continue;
24004
24051
  }
24052
+ if (service === "delegation" && resource.space.startsWith("urn:cid:") && resource.path === "") {
24053
+ rawAbilities[_b = resource.space] ?? (rawAbilities[_b] = []);
24054
+ addActions(rawAbilities[resource.space], resource.actions);
24055
+ continue;
24056
+ }
24005
24057
  if (resource.space !== delegation.spaceId) {
24006
24058
  throw new Error(
24007
24059
  `useDelegation: resource targets space '${resource.space}' but the delegation activates space '${delegation.spaceId}'. Multi-space delegations cannot be activated in a single useDelegation call.`
24008
24060
  );
24009
24061
  }
24010
24062
  abilities[service] ?? (abilities[service] = {});
24011
- (_b = abilities[service])[_c = resource.path] ?? (_b[_c] = []);
24063
+ (_c = abilities[service])[_d = resource.path] ?? (_c[_d] = []);
24012
24064
  addActions(abilities[service][resource.path], resource.actions);
24013
24065
  }
24014
24066
  return { abilities, rawAbilities };