@tinycloud/sdk-core 2.2.0-beta.7 → 2.2.0

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
@@ -37,34 +37,51 @@ __export(index_exports, {
37
37
  CapabilityKeyRegistryErrorCodes: () => CapabilityKeyRegistryErrorCodes,
38
38
  ClientSessionSchema: () => ClientSessionSchema,
39
39
  CloudLocationResolutionError: () => CloudLocationResolutionError,
40
+ DECRYPT_ACTION: () => import_sdk_services5.DECRYPT_ACTION,
41
+ DECRYPT_FACT_TYPE: () => import_sdk_services5.DECRYPT_FACT_TYPE,
42
+ DECRYPT_RESULT_TYPE: () => import_sdk_services5.DECRYPT_RESULT_TYPE,
40
43
  DEFAULT_DEFAULTS: () => DEFAULT_DEFAULTS,
44
+ DEFAULT_ENCRYPTION_ALG: () => import_sdk_services5.DEFAULT_ENCRYPTION_ALG,
41
45
  DEFAULT_EXPIRY: () => DEFAULT_EXPIRY,
46
+ DEFAULT_KEY_VERSION: () => import_sdk_services5.DEFAULT_KEY_VERSION,
42
47
  DEFAULT_MANIFEST_SPACE: () => DEFAULT_MANIFEST_SPACE,
43
48
  DEFAULT_MANIFEST_VERSION: () => DEFAULT_MANIFEST_VERSION,
49
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
44
50
  DEFAULT_TINYCLOUD_FALLBACK_HOST: () => DEFAULT_TINYCLOUD_FALLBACK_HOST,
45
51
  DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL: () => DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
46
- DataVaultService: () => import_sdk_services4.DataVaultService,
47
- DatabaseHandle: () => import_sdk_services4.DatabaseHandle,
52
+ DataVaultService: () => import_sdk_services5.DataVaultService,
53
+ DatabaseHandle: () => import_sdk_services5.DatabaseHandle,
48
54
  DelegationErrorCodes: () => DelegationErrorCodes,
49
55
  DelegationManager: () => DelegationManager,
50
- DuckDbAction: () => import_sdk_services4.DuckDbAction,
51
- DuckDbDatabaseHandle: () => import_sdk_services4.DuckDbDatabaseHandle,
52
- DuckDbService: () => import_sdk_services4.DuckDbService,
56
+ DuckDbAction: () => import_sdk_services5.DuckDbAction,
57
+ DuckDbDatabaseHandle: () => import_sdk_services5.DuckDbDatabaseHandle,
58
+ DuckDbService: () => import_sdk_services5.DuckDbService,
59
+ ENCRYPTION_MANIFEST_SPACE: () => ENCRYPTION_MANIFEST_SPACE,
60
+ ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_services5.ENCRYPTION_NETWORK_URN_PREFIX,
61
+ ENCRYPTION_PERMISSION_SERVICE: () => ENCRYPTION_PERMISSION_SERVICE,
62
+ ENCRYPTION_SERVICE: () => import_sdk_services5.ENCRYPTION_SERVICE,
63
+ ENCRYPTION_SERVICE_SHORT: () => import_sdk_services5.ENCRYPTION_SERVICE_SHORT,
64
+ ENVELOPE_VERSION: () => import_sdk_services5.ENVELOPE_VERSION,
65
+ EXPIRY: () => EXPIRY,
66
+ EncryptionService: () => import_sdk_services5.EncryptionService,
53
67
  EnsDataSchema: () => EnsDataSchema,
54
- ErrorCodes: () => import_sdk_services4.ErrorCodes,
55
- HooksService: () => import_sdk_services4.HooksService,
56
- KVService: () => import_sdk_services4.KVService,
68
+ ErrorCodes: () => import_sdk_services5.ErrorCodes,
69
+ HooksService: () => import_sdk_services5.HooksService,
70
+ KVService: () => import_sdk_services5.KVService,
57
71
  LocationRecordValidationError: () => LocationRecordValidationError,
58
72
  ManifestValidationError: () => ManifestValidationError,
73
+ NETWORK_NAME_PATTERN: () => import_sdk_services5.NETWORK_NAME_PATTERN,
74
+ NetworkIdError: () => import_sdk_services5.NetworkIdError,
59
75
  PermissionNotInManifestError: () => PermissionNotInManifestError,
60
- PrefixedKVService: () => import_sdk_services4.PrefixedKVService,
76
+ PrefixedKVService: () => import_sdk_services5.PrefixedKVService,
61
77
  ProtocolMismatchError: () => ProtocolMismatchError,
78
+ SECRET_NAME_RE: () => import_sdk_services5.SECRET_NAME_RE,
62
79
  SERVICE_LONG_TO_SHORT: () => SERVICE_LONG_TO_SHORT,
63
80
  SERVICE_SHORT_TO_LONG: () => SERVICE_SHORT_TO_LONG,
64
- SQLAction: () => import_sdk_services4.SQLAction,
65
- SQLService: () => import_sdk_services4.SQLService,
66
- SecretsService: () => import_sdk_services4.SecretsService,
67
- ServiceContext: () => import_sdk_services4.ServiceContext,
81
+ SQLAction: () => import_sdk_services5.SQLAction,
82
+ SQLService: () => import_sdk_services5.SQLService,
83
+ SecretsService: () => import_sdk_services5.SecretsService,
84
+ ServiceContext: () => import_sdk_services5.ServiceContext,
68
85
  SessionExpiredError: () => SessionExpiredError,
69
86
  SharingService: () => SharingService,
70
87
  SilentNotificationHandler: () => SilentNotificationHandler,
@@ -75,51 +92,86 @@ __export(index_exports, {
75
92
  SpaceService: () => SpaceService,
76
93
  TinyCloud: () => TinyCloud,
77
94
  UnsupportedFeatureError: () => UnsupportedFeatureError,
78
- VaultHeaders: () => import_sdk_services4.VaultHeaders,
79
- VaultPublicSpaceKVActions: () => import_sdk_services4.VaultPublicSpaceKVActions,
95
+ VAULT_PERMISSION_SERVICE: () => VAULT_PERMISSION_SERVICE,
96
+ VaultHeaders: () => import_sdk_services5.VaultHeaders,
97
+ VaultPublicSpaceKVActions: () => import_sdk_services5.VaultPublicSpaceKVActions,
80
98
  VersionCheckError: () => VersionCheckError,
81
99
  activateSessionWithHost: () => activateSessionWithHost,
82
100
  applyPrefix: () => applyPrefix,
101
+ buildCanonicalDecryptRequest: () => import_sdk_services5.buildCanonicalDecryptRequest,
102
+ buildDecryptAttenuation: () => import_sdk_services5.buildDecryptAttenuation,
103
+ buildDecryptFacts: () => import_sdk_services5.buildDecryptFacts,
104
+ buildDecryptInvocation: () => import_sdk_services5.buildDecryptInvocation,
105
+ buildNetworkId: () => import_sdk_services5.buildNetworkId,
83
106
  buildSpaceUri: () => buildSpaceUri,
107
+ canonicalHashHex: () => import_sdk_services5.canonicalHashHex,
84
108
  canonicalLocationPayload: () => canonicalLocationPayload,
109
+ canonicalSignedResponse: () => import_sdk_services5.canonicalSignedResponse,
110
+ canonicalizeEncryptionJson: () => import_sdk_services5.canonicalizeEncryptionJson,
111
+ canonicalizeSecretScope: () => import_sdk_services5.canonicalizeSecretScope,
112
+ checkDecryptInvocationInput: () => import_sdk_services5.checkDecryptInvocationInput,
85
113
  checkNodeInfo: () => checkNodeInfo,
86
114
  composeManifestRequest: () => composeManifestRequest,
87
115
  createCapabilityKeyRegistry: () => createCapabilityKeyRegistry,
88
116
  createSharingService: () => createSharingService,
89
117
  createSpaceService: () => createSpaceService,
90
- createVaultCrypto: () => import_sdk_services4.createVaultCrypto,
91
- defaultRetryPolicy: () => import_sdk_services4.defaultRetryPolicy,
118
+ createVaultCrypto: () => import_sdk_services5.createVaultCrypto,
119
+ decryptEnvelopeWithKey: () => import_sdk_services5.decryptEnvelopeWithKey,
120
+ defaultRetryPolicy: () => import_sdk_services5.defaultRetryPolicy,
92
121
  defaultSignStrategy: () => defaultSignStrategy,
93
122
  defaultSpaceCreationHandler: () => defaultSpaceCreationHandler,
94
- err: () => import_sdk_services4.err,
123
+ deriveSignedReceiverKey: () => import_sdk_services5.deriveSignedReceiverKey,
124
+ discoverNetwork: () => import_sdk_services5.discoverNetwork,
125
+ encryptToNetwork: () => import_sdk_services5.encryptToNetwork,
126
+ encryptionBase64Decode: () => import_sdk_services5.base64Decode,
127
+ encryptionBase64Encode: () => import_sdk_services5.base64Encode,
128
+ encryptionError: () => import_sdk_services5.encryptionError,
129
+ encryptionUtf8Decode: () => import_sdk_services5.utf8Decode,
130
+ encryptionUtf8Encode: () => import_sdk_services5.utf8Encode,
131
+ ensureNetworkUsableForDecrypt: () => import_sdk_services5.ensureNetworkUsableForDecrypt,
132
+ err: () => import_sdk_services5.err,
95
133
  expandActionShortNames: () => expandActionShortNames,
134
+ expandPermissionEntries: () => expandPermissionEntries,
135
+ expandPermissionEntry: () => expandPermissionEntry,
96
136
  fetchLocationRecord: () => fetchLocationRecord,
97
137
  fetchPeerId: () => fetchPeerId,
138
+ generateRandomReceiverKey: () => import_sdk_services5.generateRandomReceiverKey,
139
+ hexDecode: () => import_sdk_services5.hexDecode,
140
+ hexEncode: () => import_sdk_services5.hexEncode,
98
141
  httpUrlToMultiaddr: () => httpUrlToMultiaddr,
99
142
  isCapabilitySubset: () => isCapabilitySubset,
143
+ isNetworkId: () => import_sdk_services5.isNetworkId,
100
144
  loadManifest: () => loadManifest,
101
145
  locationPayloadForRecord: () => locationPayloadForRecord,
102
146
  makePublicSpaceId: () => makePublicSpaceId,
103
147
  manifestAbilitiesUnion: () => manifestAbilitiesUnion,
104
148
  multiaddrToHttpUrl: () => multiaddrToHttpUrl,
149
+ networkDiscoveryKey: () => import_sdk_services5.networkDiscoveryKey,
105
150
  normalizeDefaults: () => normalizeDefaults,
106
- ok: () => import_sdk_services4.ok,
151
+ ok: () => import_sdk_services5.ok,
152
+ openWrappedKey: () => import_sdk_services5.openWrappedKey,
107
153
  parseExpiry: () => parseExpiry,
154
+ parseNetworkId: () => import_sdk_services5.parseNetworkId,
108
155
  parseRecapCapabilities: () => parseRecapCapabilities,
109
156
  parseSpaceUri: () => parseSpaceUri,
110
157
  resolveCloudLocation: () => resolveCloudLocation,
111
158
  resolveManifest: () => resolveManifest,
159
+ resolveSecretListPrefix: () => import_sdk_services5.resolveSecretListPrefix,
160
+ resolveSecretPath: () => import_sdk_services5.resolveSecretPath,
112
161
  resolveTinyCloudHosts: () => resolveTinyCloudHosts,
113
162
  resourceCapabilitiesToAbilitiesMap: () => resourceCapabilitiesToAbilitiesMap,
114
163
  resourceCapabilitiesToSpaceAbilitiesMap: () => resourceCapabilitiesToSpaceAbilitiesMap,
115
- serviceError: () => import_sdk_services4.serviceError,
164
+ serviceError: () => import_sdk_services5.serviceError,
116
165
  signLocationRecord: () => signLocationRecord,
117
166
  submitHostDelegation: () => submitHostDelegation,
118
167
  validateClientSession: () => validateClientSession,
168
+ validateEnvelope: () => import_sdk_services5.validateEnvelope,
119
169
  validateLocationRecord: () => validateLocationRecord,
120
170
  validateLocationRecordPayload: () => validateLocationRecordPayload,
121
171
  validateManifest: () => validateManifest,
122
172
  validatePersistedSessionData: () => validatePersistedSessionData,
173
+ verifyDecryptResponse: () => import_sdk_services5.verifyDecryptResponse,
174
+ verifyDidKeyEd25519Signature: () => verifyDidKeyEd25519Signature,
123
175
  verifyLocationRecord: () => verifyLocationRecord
124
176
  });
125
177
  module.exports = __toCommonJS(index_exports);
@@ -844,6 +896,23 @@ function validateServerSpaceInfoResponse(data) {
844
896
  return { ok: true, data: result.data };
845
897
  }
846
898
 
899
+ // src/expiry.ts
900
+ var EPHEMERAL_MS = 60 * 60 * 1e3;
901
+ var SIGNED_READ_URL_MS = 5 * 60 * 1e3;
902
+ var SESSION_MS = 7 * 24 * 60 * 60 * 1e3;
903
+ var SHARE_MS = 7 * 24 * 60 * 60 * 1e3;
904
+ var APP_MS = 30 * 24 * 60 * 60 * 1e3;
905
+ var MAX_MS = 10 * 365 * 24 * 60 * 60 * 1e3;
906
+ var EXPIRY = {
907
+ EPHEMERAL_MS,
908
+ SIGNED_READ_URL_MS,
909
+ SESSION_MS,
910
+ SHARE_MS,
911
+ APP_MS,
912
+ MAX_MS
913
+ };
914
+ var DEFAULT_SIGNED_READ_URL_EXPIRY_MS = EXPIRY.SIGNED_READ_URL_MS;
915
+
847
916
  // src/spaces/SpaceService.ts
848
917
  var SERVICE_NAME = "space";
849
918
  var SpaceErrorCodes = {
@@ -920,7 +989,7 @@ function transformServerDelegations(validatedData, defaultSpaceId) {
920
989
  spaceId,
921
990
  path,
922
991
  actions,
923
- expiry: info.expiry ? new Date(info.expiry) : new Date(Date.now() + 24 * 60 * 60 * 1e3),
992
+ expiry: info.expiry ? new Date(info.expiry) : new Date(Date.now() + EXPIRY.SHARE_MS),
924
993
  isRevoked: false,
925
994
  createdAt: info.issued_at ? new Date(info.issued_at) : void 0,
926
995
  parentCid: firstStringParent
@@ -1780,6 +1849,22 @@ var TinyCloud = class _TinyCloud {
1780
1849
  }
1781
1850
  return service;
1782
1851
  }
1852
+ /**
1853
+ * Get the Encryption service.
1854
+ * @throws Error if services are not initialized or encryption service is not registered
1855
+ */
1856
+ get encryption() {
1857
+ if (!this._servicesInitialized) {
1858
+ throw new Error(
1859
+ "Services not initialized. Call initializeServices() first, or use TinyCloudWeb/TinyCloudNode which handles this automatically."
1860
+ );
1861
+ }
1862
+ const service = this._services.get("encryption");
1863
+ if (!service) {
1864
+ throw new Error("Encryption service is not registered.");
1865
+ }
1866
+ return service;
1867
+ }
1783
1868
  /**
1784
1869
  * Notify services of session change.
1785
1870
  * Called internally after sign-in and sign-out.
@@ -2115,7 +2200,7 @@ var TinyCloud = class _TinyCloud {
2115
2200
  };
2116
2201
 
2117
2202
  // src/index.ts
2118
- var import_sdk_services4 = require("@tinycloud/sdk-services");
2203
+ var import_sdk_services5 = require("@tinycloud/sdk-services");
2119
2204
 
2120
2205
  // src/space.ts
2121
2206
  async function fetchPeerId(host, spaceId) {
@@ -2304,7 +2389,7 @@ var DelegationManager = class {
2304
2389
  spaceId: this.session.spaceId,
2305
2390
  path: params.path,
2306
2391
  actions: params.actions,
2307
- expiry: params.expiry ?? new Date(Date.now() + 24 * 60 * 60 * 1e3),
2392
+ expiry: params.expiry ?? new Date(Date.now() + EXPIRY.SHARE_MS),
2308
2393
  isRevoked: false,
2309
2394
  allowSubDelegation: !(params.disableSubDelegation ?? false),
2310
2395
  createdAt: /* @__PURE__ */ new Date()
@@ -2783,6 +2868,7 @@ function validateEncodedShareData(data) {
2783
2868
 
2784
2869
  // src/manifest.ts
2785
2870
  var import_ms = __toESM(require("ms"), 1);
2871
+ var import_sdk_services3 = require("@tinycloud/sdk-services");
2786
2872
  var ManifestValidationError = class extends Error {
2787
2873
  constructor(message) {
2788
2874
  super(`Manifest validation failed: ${message}`);
@@ -2796,14 +2882,17 @@ var DEFAULT_MANIFEST_SPACE = "applications";
2796
2882
  var ACCOUNT_REGISTRY_SPACE = "account";
2797
2883
  var ACCOUNT_REGISTRY_PATH = "applications/";
2798
2884
  var SECRETS_SPACE = "secrets";
2799
- var SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
2885
+ var VAULT_PERMISSION_SERVICE = "tinycloud.vault";
2800
2886
  var SERVICE_SHORT_TO_LONG = Object.freeze({
2801
2887
  kv: "tinycloud.kv",
2802
2888
  sql: "tinycloud.sql",
2803
2889
  duckdb: "tinycloud.duckdb",
2804
2890
  capabilities: "tinycloud.capabilities",
2805
- hooks: "tinycloud.hooks"
2891
+ hooks: "tinycloud.hooks",
2892
+ encryption: "tinycloud.encryption"
2806
2893
  });
2894
+ var ENCRYPTION_PERMISSION_SERVICE = "tinycloud.encryption";
2895
+ var ENCRYPTION_MANIFEST_SPACE = "encryption";
2807
2896
  var SERVICE_LONG_TO_SHORT = Object.freeze(
2808
2897
  Object.fromEntries(
2809
2898
  Object.entries(SERVICE_SHORT_TO_LONG).map(([s, l]) => [l, s])
@@ -2879,6 +2968,72 @@ function expandActionShortNames(service, actions) {
2879
2968
  return `${service}/${a}`;
2880
2969
  });
2881
2970
  }
2971
+ function expandPermissionEntry(entry) {
2972
+ if (entry.service === ENCRYPTION_PERMISSION_SERVICE) {
2973
+ return expandEncryptionPermissionEntry(entry);
2974
+ }
2975
+ if (entry.service !== VAULT_PERMISSION_SERVICE) {
2976
+ return [
2977
+ {
2978
+ ...entry,
2979
+ actions: expandActionShortNames(entry.service, entry.actions)
2980
+ }
2981
+ ];
2982
+ }
2983
+ return expandVaultPermissionEntry(entry);
2984
+ }
2985
+ function expandEncryptionPermissionEntry(entry) {
2986
+ if (typeof entry.path !== "string" || !entry.path.startsWith("urn:tinycloud:encryption:")) {
2987
+ throw new ManifestValidationError(
2988
+ `tinycloud.encryption entries require path to be a networkId URN (got ${JSON.stringify(entry.path)})`
2989
+ );
2990
+ }
2991
+ const normalizedActions = [];
2992
+ for (const action of entry.actions) {
2993
+ if (action === "decrypt" || action === "tinycloud.encryption/decrypt") {
2994
+ normalizedActions.push("tinycloud.encryption/decrypt");
2995
+ continue;
2996
+ }
2997
+ if (action === "network.create" || action === "tinycloud.encryption/network.create") {
2998
+ normalizedActions.push("tinycloud.encryption/network.create");
2999
+ continue;
3000
+ }
3001
+ if (action === "network.revoke" || action === "tinycloud.encryption/network.revoke") {
3002
+ normalizedActions.push("tinycloud.encryption/network.revoke");
3003
+ continue;
3004
+ }
3005
+ if (action.includes("/")) {
3006
+ throw new ManifestValidationError(
3007
+ `unknown encryption action ${JSON.stringify(action)}; expected decrypt, network.create, or network.revoke`
3008
+ );
3009
+ }
3010
+ throw new ManifestValidationError(
3011
+ `unknown encryption action ${JSON.stringify(action)}; expected decrypt, network.create, or network.revoke`
3012
+ );
3013
+ }
3014
+ const dedupedActions = [];
3015
+ const seen = /* @__PURE__ */ new Set();
3016
+ for (const a of normalizedActions) {
3017
+ if (!seen.has(a)) {
3018
+ dedupedActions.push(a);
3019
+ seen.add(a);
3020
+ }
3021
+ }
3022
+ return [
3023
+ {
3024
+ service: ENCRYPTION_PERMISSION_SERVICE,
3025
+ space: ENCRYPTION_MANIFEST_SPACE,
3026
+ path: entry.path,
3027
+ actions: dedupedActions,
3028
+ skipPrefix: true,
3029
+ ...entry.expiry !== void 0 ? { expiry: entry.expiry } : {},
3030
+ ...entry.description !== void 0 ? { description: entry.description } : {}
3031
+ }
3032
+ ];
3033
+ }
3034
+ function expandPermissionEntries(entries) {
3035
+ return entries.flatMap(expandPermissionEntry);
3036
+ }
2882
3037
  function applyPrefix(prefix, path, skipPrefix) {
2883
3038
  if (skipPrefix) {
2884
3039
  return path;
@@ -2960,9 +3115,19 @@ function validateManifestSecrets(secrets) {
2960
3115
  throw new ManifestValidationError("manifest.secrets must be an object");
2961
3116
  }
2962
3117
  for (const [name, spec] of Object.entries(secrets)) {
2963
- if (!SECRET_NAME_RE.test(name)) {
3118
+ if (!import_sdk_services3.SECRET_NAME_RE.test(name)) {
3119
+ throw new ManifestValidationError(
3120
+ `manifest.secrets.${name} must match ${import_sdk_services3.SECRET_NAME_RE.source}`
3121
+ );
3122
+ }
3123
+ try {
3124
+ (0, import_sdk_services3.resolveSecretPath)(
3125
+ secretNameFromSpec(name, spec),
3126
+ { scope: secretScopeFromSpec(spec) }
3127
+ );
3128
+ } catch (error) {
2964
3129
  throw new ManifestValidationError(
2965
- `manifest.secrets.${name} must match ${SECRET_NAME_RE.source}`
3130
+ `manifest.secrets.${name}: ${error instanceof Error ? error.message : String(error)}`
2966
3131
  );
2967
3132
  }
2968
3133
  const actions = secretActionsFromSpec(name, spec);
@@ -3006,6 +3171,16 @@ function validatePermissionEntry(p, path) {
3006
3171
  `${path}.actions must be a non-empty array`
3007
3172
  );
3008
3173
  }
3174
+ for (const action of entry.actions) {
3175
+ if (typeof action !== "string" || action.length === 0) {
3176
+ throw new ManifestValidationError(
3177
+ `${path}.actions must contain non-empty strings`
3178
+ );
3179
+ }
3180
+ if (entry.service === VAULT_PERMISSION_SERVICE) {
3181
+ vaultActionExpansion(action);
3182
+ }
3183
+ }
3009
3184
  if (entry.expiry !== void 0) {
3010
3185
  parseExpiry(entry.expiry);
3011
3186
  }
@@ -3055,7 +3230,7 @@ function resolveManifest(input) {
3055
3230
  ...secretEntries
3056
3231
  ];
3057
3232
  const resources = withCapabilitiesReadForSpaces(
3058
- allEntries.map((entry) => resolveEntry(entry, prefix, expiryMs, space))
3233
+ allEntries.flatMap((entry) => resolveEntry(entry, prefix, expiryMs, space))
3059
3234
  );
3060
3235
  const additionalDelegates = manifest.did === void 0 ? [] : [
3061
3236
  {
@@ -3111,6 +3286,18 @@ function normalizeSecretActions(actions) {
3111
3286
  }
3112
3287
  return out;
3113
3288
  }
3289
+ function secretNameFromSpec(fallbackName, spec) {
3290
+ if (spec !== null && typeof spec === "object" && !Array.isArray(spec)) {
3291
+ return spec.name ?? fallbackName;
3292
+ }
3293
+ return fallbackName;
3294
+ }
3295
+ function secretScopeFromSpec(spec) {
3296
+ if (spec !== null && typeof spec === "object" && !Array.isArray(spec)) {
3297
+ return spec.scope;
3298
+ }
3299
+ return void 0;
3300
+ }
3114
3301
  function secretActionsFromSpec(name, spec) {
3115
3302
  if (spec === true) {
3116
3303
  return ["read"];
@@ -3146,40 +3333,105 @@ function secretEntriesForManifest(secrets) {
3146
3333
  const entries = [];
3147
3334
  for (const [name, spec] of Object.entries(secrets)) {
3148
3335
  const actions = secretActionsFromSpec(name, spec);
3336
+ const secretPath = (0, import_sdk_services3.resolveSecretPath)(
3337
+ secretNameFromSpec(name, spec),
3338
+ { scope: secretScopeFromSpec(spec) }
3339
+ );
3149
3340
  const extra = spec !== true && typeof spec === "object" && !Array.isArray(spec) ? spec : {};
3150
- for (const base of ["keys", "vault"]) {
3151
- entries.push({
3152
- service: "tinycloud.kv",
3153
- space: SECRETS_SPACE,
3154
- path: `${base}/secrets/${name}`,
3155
- actions: normalizeSecretActions(actions),
3156
- skipPrefix: true,
3157
- ...extra.expiry !== void 0 ? { expiry: extra.expiry } : {},
3158
- ...extra.description !== void 0 ? { description: extra.description } : {}
3159
- });
3160
- }
3341
+ entries.push({
3342
+ service: VAULT_PERMISSION_SERVICE,
3343
+ space: SECRETS_SPACE,
3344
+ path: secretPath.vaultKey,
3345
+ actions: normalizeSecretActions(actions),
3346
+ skipPrefix: true,
3347
+ ...extra.expiry !== void 0 ? { expiry: extra.expiry } : {},
3348
+ ...extra.description !== void 0 ? { description: extra.description } : {}
3349
+ });
3161
3350
  }
3162
3351
  return entries;
3163
3352
  }
3164
3353
  function resolveEntry(entry, prefix, _inheritedExpiryMs, inheritedSpace) {
3165
- const resolvedPath = applyPrefix(
3166
- prefix,
3167
- entry.path,
3168
- entry.skipPrefix === true
3169
- );
3170
- const resolvedActions = expandActionShortNames(entry.service, entry.actions);
3354
+ const skipPrefixForEntry = entry.skipPrefix === true || entry.service === ENCRYPTION_PERMISSION_SERVICE;
3355
+ const resolvedPath = applyPrefix(prefix, entry.path, skipPrefixForEntry);
3171
3356
  const entryExpiryMs = entry.expiry !== void 0 ? parseExpiry(entry.expiry) : void 0;
3172
- return {
3173
- service: entry.service,
3357
+ return expandPermissionEntry({
3358
+ ...entry,
3174
3359
  space: entry.space ?? inheritedSpace,
3175
3360
  path: resolvedPath,
3176
- actions: resolvedActions,
3361
+ skipPrefix: true
3362
+ }).map((expanded) => ({
3363
+ service: expanded.service,
3364
+ space: expanded.space ?? inheritedSpace,
3365
+ path: expanded.path,
3366
+ actions: expanded.actions,
3177
3367
  // Only populate `expiryMs` when the entry had its own expiry override.
3178
3368
  // When absent, callers use the parent (delegation or manifest) expiry
3179
3369
  // which is carried on ResolvedDelegate.expiryMs / ResolvedCapabilities.expiryMs.
3180
3370
  ...entryExpiryMs !== void 0 ? { expiryMs: entryExpiryMs } : {},
3181
3371
  ...entry.description !== void 0 ? { description: entry.description } : {}
3182
- };
3372
+ }));
3373
+ }
3374
+ function expandVaultPermissionEntry(entry) {
3375
+ const byBase = /* @__PURE__ */ new Map();
3376
+ for (const action of entry.actions) {
3377
+ const expansion = vaultActionExpansion(action);
3378
+ for (const base of expansion.bases) {
3379
+ const actions = byBase.get(base) ?? [];
3380
+ if (!actions.includes(expansion.action)) {
3381
+ actions.push(expansion.action);
3382
+ }
3383
+ byBase.set(base, actions);
3384
+ }
3385
+ }
3386
+ return [...byBase.entries()].map(([base, actions]) => ({
3387
+ ...entry,
3388
+ service: "tinycloud.kv",
3389
+ path: vaultKVPath(base, entry.path),
3390
+ actions,
3391
+ skipPrefix: true
3392
+ }));
3393
+ }
3394
+ function vaultActionExpansion(action) {
3395
+ const normalized = normalizeVaultAction(action);
3396
+ if (normalized === "read" || normalized === "get") {
3397
+ return { bases: ["vault"], action: "tinycloud.kv/get" };
3398
+ }
3399
+ if (normalized === "write" || normalized === "put") {
3400
+ return { bases: ["vault"], action: "tinycloud.kv/put" };
3401
+ }
3402
+ if (normalized === "delete" || normalized === "del") {
3403
+ return { bases: ["vault"], action: "tinycloud.kv/del" };
3404
+ }
3405
+ if (normalized === "list") {
3406
+ return { bases: ["vault"], action: "tinycloud.kv/list" };
3407
+ }
3408
+ if (normalized === "head") {
3409
+ return { bases: ["vault"], action: "tinycloud.kv/get" };
3410
+ }
3411
+ if (normalized === "metadata") {
3412
+ return { bases: ["vault"], action: "tinycloud.kv/metadata" };
3413
+ }
3414
+ throw new ManifestValidationError(
3415
+ `unknown vault action ${JSON.stringify(action)}; expected read, write, delete, get, put, del, list, head, or metadata`
3416
+ );
3417
+ }
3418
+ function normalizeVaultAction(action) {
3419
+ if (action.startsWith(`${VAULT_PERMISSION_SERVICE}/`)) {
3420
+ return action.slice(`${VAULT_PERMISSION_SERVICE}/`.length);
3421
+ }
3422
+ if (action.startsWith("tinycloud.kv/")) {
3423
+ return action.slice("tinycloud.kv/".length);
3424
+ }
3425
+ if (action.includes("/")) {
3426
+ throw new ManifestValidationError(
3427
+ `unknown vault action ${JSON.stringify(action)}; expected a tinycloud.vault or tinycloud.kv action`
3428
+ );
3429
+ }
3430
+ return action;
3431
+ }
3432
+ function vaultKVPath(base, path) {
3433
+ const normalized = path.startsWith("/") ? path.slice(1) : path;
3434
+ return `${base}/${normalized}`;
3183
3435
  }
3184
3436
  function cloneResourceCapability(entry) {
3185
3437
  return {
@@ -3236,7 +3488,9 @@ function withCapabilitiesReadForSpaces(resources) {
3236
3488
  if (resources.length === 0) {
3237
3489
  return [];
3238
3490
  }
3239
- const spaces = new Set(resources.map((resource) => resource.space));
3491
+ const spaces = new Set(
3492
+ resources.filter((resource) => resource.service !== ENCRYPTION_PERMISSION_SERVICE).map((resource) => resource.space)
3493
+ );
3240
3494
  return dedupeResources([
3241
3495
  ...resources,
3242
3496
  ...[...spaces].map(capabilitiesReadPermission)
@@ -3368,7 +3622,7 @@ function inferShortServiceFromActionUrns(actions) {
3368
3622
  return short;
3369
3623
  }
3370
3624
  var DEFAULT_READ_ACTIONS = ["tinycloud.kv/get", "tinycloud.kv/metadata"];
3371
- var DEFAULT_EXPIRY_MS = 24 * 60 * 60 * 1e3;
3625
+ var DEFAULT_EXPIRY_MS = EXPIRY.SHARE_MS;
3372
3626
  var BASE64_PREFIX = "tc1:";
3373
3627
  function createError2(code, message, cause, meta) {
3374
3628
  return {
@@ -4010,7 +4264,7 @@ function createSharingService(config) {
4010
4264
  }
4011
4265
 
4012
4266
  // src/authorization/CapabilityKeyRegistry.ts
4013
- var import_sdk_services3 = require("@tinycloud/sdk-services");
4267
+ var import_sdk_services4 = require("@tinycloud/sdk-services");
4014
4268
  var SERVICE_NAME2 = "capability-key-registry";
4015
4269
  var CapabilityKeyRegistryErrorCodes = {
4016
4270
  /** Key not found in registry */
@@ -4228,8 +4482,8 @@ var CapabilityKeyRegistry = class {
4228
4482
  revokeDelegation(cid) {
4229
4483
  const stored = this.store.byCid.get(cid);
4230
4484
  if (!stored) {
4231
- return (0, import_sdk_services3.err)(
4232
- (0, import_sdk_services3.serviceError)(
4485
+ return (0, import_sdk_services4.err)(
4486
+ (0, import_sdk_services4.serviceError)(
4233
4487
  CapabilityKeyRegistryErrorCodes.KEY_NOT_FOUND,
4234
4488
  `Delegation not found: ${cid}`,
4235
4489
  SERVICE_NAME2
@@ -4251,7 +4505,7 @@ var CapabilityKeyRegistry = class {
4251
4505
  }
4252
4506
  }
4253
4507
  }
4254
- return (0, import_sdk_services3.ok)(void 0);
4508
+ return (0, import_sdk_services4.ok)(void 0);
4255
4509
  }
4256
4510
  // ===========================================================================
4257
4511
  // Search
@@ -4497,6 +4751,7 @@ async function checkNodeInfo(host, sdkProtocol, fetchFn = globalThis.fetch.bind(
4497
4751
  }
4498
4752
  return {
4499
4753
  features: data.features ?? [],
4754
+ nodeId: data.nodeId,
4500
4755
  quotaUrl: data.quota_url
4501
4756
  };
4502
4757
  }
@@ -4833,6 +5088,10 @@ function verifyDidKeySignature(did, payload, signature) {
4833
5088
  publicKey
4834
5089
  );
4835
5090
  }
5091
+ function verifyDidKeyEd25519Signature(did, payload, signature) {
5092
+ const publicKey = ed25519PublicKeyFromDidKey(did);
5093
+ return import_ed25519.ed25519.verify(signature, payload, publicKey);
5094
+ }
4836
5095
  function ed25519PublicKeyFromDidKey(did) {
4837
5096
  const identifier = did.slice("did:key:".length);
4838
5097
  if (!identifier.startsWith("z")) {
@@ -4841,12 +5100,15 @@ function ed25519PublicKeyFromDidKey(did) {
4841
5100
  );
4842
5101
  }
4843
5102
  const bytes = import_basics.bases.base58btc.decode(identifier);
4844
- if (bytes.length !== 34 || bytes[0] !== 237 || bytes[1] !== 1) {
4845
- throw new LocationRecordValidationError(
4846
- "did:key must be an Ed25519 public key"
4847
- );
5103
+ if (bytes.length === 34 && bytes[0] === 237 && bytes[1] === 1) {
5104
+ return bytes.slice(2);
5105
+ }
5106
+ if (bytes.length === 33 && bytes[0] === 237) {
5107
+ return bytes.slice(1);
4848
5108
  }
4849
- return bytes.slice(2);
5109
+ throw new LocationRecordValidationError(
5110
+ "did:key must be an Ed25519 public key"
5111
+ );
4850
5112
  }
4851
5113
  function base64UrlEncode2(bytes) {
4852
5114
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
@@ -5011,10 +5273,16 @@ function parseRecapCapabilities(parseWasm, siwe) {
5011
5273
  CapabilityKeyRegistryErrorCodes,
5012
5274
  ClientSessionSchema,
5013
5275
  CloudLocationResolutionError,
5276
+ DECRYPT_ACTION,
5277
+ DECRYPT_FACT_TYPE,
5278
+ DECRYPT_RESULT_TYPE,
5014
5279
  DEFAULT_DEFAULTS,
5280
+ DEFAULT_ENCRYPTION_ALG,
5015
5281
  DEFAULT_EXPIRY,
5282
+ DEFAULT_KEY_VERSION,
5016
5283
  DEFAULT_MANIFEST_SPACE,
5017
5284
  DEFAULT_MANIFEST_VERSION,
5285
+ DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
5018
5286
  DEFAULT_TINYCLOUD_FALLBACK_HOST,
5019
5287
  DEFAULT_TINYCLOUD_LOCATION_REGISTRY_URL,
5020
5288
  DataVaultService,
@@ -5024,15 +5292,26 @@ function parseRecapCapabilities(parseWasm, siwe) {
5024
5292
  DuckDbAction,
5025
5293
  DuckDbDatabaseHandle,
5026
5294
  DuckDbService,
5295
+ ENCRYPTION_MANIFEST_SPACE,
5296
+ ENCRYPTION_NETWORK_URN_PREFIX,
5297
+ ENCRYPTION_PERMISSION_SERVICE,
5298
+ ENCRYPTION_SERVICE,
5299
+ ENCRYPTION_SERVICE_SHORT,
5300
+ ENVELOPE_VERSION,
5301
+ EXPIRY,
5302
+ EncryptionService,
5027
5303
  EnsDataSchema,
5028
5304
  ErrorCodes,
5029
5305
  HooksService,
5030
5306
  KVService,
5031
5307
  LocationRecordValidationError,
5032
5308
  ManifestValidationError,
5309
+ NETWORK_NAME_PATTERN,
5310
+ NetworkIdError,
5033
5311
  PermissionNotInManifestError,
5034
5312
  PrefixedKVService,
5035
5313
  ProtocolMismatchError,
5314
+ SECRET_NAME_RE,
5036
5315
  SERVICE_LONG_TO_SHORT,
5037
5316
  SERVICE_SHORT_TO_LONG,
5038
5317
  SQLAction,
@@ -5049,40 +5328,72 @@ function parseRecapCapabilities(parseWasm, siwe) {
5049
5328
  SpaceService,
5050
5329
  TinyCloud,
5051
5330
  UnsupportedFeatureError,
5331
+ VAULT_PERMISSION_SERVICE,
5052
5332
  VaultHeaders,
5053
5333
  VaultPublicSpaceKVActions,
5054
5334
  VersionCheckError,
5055
5335
  activateSessionWithHost,
5056
5336
  applyPrefix,
5337
+ buildCanonicalDecryptRequest,
5338
+ buildDecryptAttenuation,
5339
+ buildDecryptFacts,
5340
+ buildDecryptInvocation,
5341
+ buildNetworkId,
5057
5342
  buildSpaceUri,
5343
+ canonicalHashHex,
5058
5344
  canonicalLocationPayload,
5345
+ canonicalSignedResponse,
5346
+ canonicalizeEncryptionJson,
5347
+ canonicalizeSecretScope,
5348
+ checkDecryptInvocationInput,
5059
5349
  checkNodeInfo,
5060
5350
  composeManifestRequest,
5061
5351
  createCapabilityKeyRegistry,
5062
5352
  createSharingService,
5063
5353
  createSpaceService,
5064
5354
  createVaultCrypto,
5355
+ decryptEnvelopeWithKey,
5065
5356
  defaultRetryPolicy,
5066
5357
  defaultSignStrategy,
5067
5358
  defaultSpaceCreationHandler,
5359
+ deriveSignedReceiverKey,
5360
+ discoverNetwork,
5361
+ encryptToNetwork,
5362
+ encryptionBase64Decode,
5363
+ encryptionBase64Encode,
5364
+ encryptionError,
5365
+ encryptionUtf8Decode,
5366
+ encryptionUtf8Encode,
5367
+ ensureNetworkUsableForDecrypt,
5068
5368
  err,
5069
5369
  expandActionShortNames,
5370
+ expandPermissionEntries,
5371
+ expandPermissionEntry,
5070
5372
  fetchLocationRecord,
5071
5373
  fetchPeerId,
5374
+ generateRandomReceiverKey,
5375
+ hexDecode,
5376
+ hexEncode,
5072
5377
  httpUrlToMultiaddr,
5073
5378
  isCapabilitySubset,
5379
+ isNetworkId,
5074
5380
  loadManifest,
5075
5381
  locationPayloadForRecord,
5076
5382
  makePublicSpaceId,
5077
5383
  manifestAbilitiesUnion,
5078
5384
  multiaddrToHttpUrl,
5385
+ networkDiscoveryKey,
5079
5386
  normalizeDefaults,
5080
5387
  ok,
5388
+ openWrappedKey,
5081
5389
  parseExpiry,
5390
+ parseNetworkId,
5082
5391
  parseRecapCapabilities,
5083
5392
  parseSpaceUri,
5084
5393
  resolveCloudLocation,
5085
5394
  resolveManifest,
5395
+ resolveSecretListPrefix,
5396
+ resolveSecretPath,
5086
5397
  resolveTinyCloudHosts,
5087
5398
  resourceCapabilitiesToAbilitiesMap,
5088
5399
  resourceCapabilitiesToSpaceAbilitiesMap,
@@ -5090,10 +5401,13 @@ function parseRecapCapabilities(parseWasm, siwe) {
5090
5401
  signLocationRecord,
5091
5402
  submitHostDelegation,
5092
5403
  validateClientSession,
5404
+ validateEnvelope,
5093
5405
  validateLocationRecord,
5094
5406
  validateLocationRecordPayload,
5095
5407
  validateManifest,
5096
5408
  validatePersistedSessionData,
5409
+ verifyDecryptResponse,
5410
+ verifyDidKeyEd25519Signature,
5097
5411
  verifyLocationRecord
5098
5412
  });
5099
5413
  //# sourceMappingURL=index.cjs.map