@tinycloud/node-sdk 3.8.0-beta.3 → 3.8.0-beta.4

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.
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-CVO41O12.cjs';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-CxRHpusk.cjs';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-B6VOBrCb.js';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-BKFo3t4u.js';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
package/dist/index.cjs CHANGED
@@ -18824,13 +18824,42 @@ function getNodeReplicationLoaders() {
18824
18824
 
18825
18825
  // src/TinyCloudNode.ts
18826
18826
  var import_sdk_core10 = require("@tinycloud/sdk-core");
18827
- var import_sdk_services3 = require("@tinycloud/sdk-services");
18827
+ var import_sdk_services4 = require("@tinycloud/sdk-services");
18828
18828
  var import_requestLog2 = require("@tinycloud/sdk-services/telemetry/requestLog");
18829
+ var import_resource2 = require("@tinycloud/sdk-services/encryption/resource");
18829
18830
 
18830
18831
  // src/authorization/NodeUserAuthorization.ts
18831
18832
  var import_node_crypto = require("crypto");
18832
18833
  var import_siwe = require("siwe");
18833
18834
  var import_sdk_core5 = require("@tinycloud/sdk-core");
18835
+ var import_resource = require("@tinycloud/sdk-services/encryption/resource");
18836
+ var import_sdk_services3 = require("@tinycloud/sdk-services");
18837
+
18838
+ // src/authorization/appKeyHostBinding.ts
18839
+ var DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
18840
+ var IPV4 = /^\d+\.\d+\.\d+\.\d+$/;
18841
+ var APP_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
18842
+ function appKeyHostBinding(domain, appId) {
18843
+ if (!APP_ID.test(appId)) return false;
18844
+ if (domain.endsWith(":")) return false;
18845
+ let url;
18846
+ try {
18847
+ url = new URL(`https://${domain}`);
18848
+ } catch {
18849
+ return false;
18850
+ }
18851
+ if (url.protocol !== "https:" || url.port !== "" || url.username !== "" || url.password !== "") return false;
18852
+ if (url.pathname !== "/" || url.search !== "" || url.hash !== "") return false;
18853
+ const host = url.hostname;
18854
+ if (host.startsWith("[") || host.endsWith(".") || IPV4.test(host)) return false;
18855
+ const labels = host.split(".");
18856
+ if (labels.length < 2 || labels[labels.length - 1] === "localhost") return false;
18857
+ if (!labels.every((label) => DOMAIN_LABEL.test(label))) return false;
18858
+ const reversed = labels.reverse().join(".");
18859
+ return appId === reversed || appId.startsWith(`${reversed}.`);
18860
+ }
18861
+
18862
+ // src/authorization/NodeUserAuthorization.ts
18834
18863
  init_authority_sign_in();
18835
18864
 
18836
18865
  // src/authorization/caveatRefusal.ts
@@ -19342,6 +19371,23 @@ var NodeUserAuthorization = class {
19342
19371
  );
19343
19372
  return this._capabilityRequest;
19344
19373
  }
19374
+ async refreshNamedKeyFeatureForSignIn(address, chainId) {
19375
+ const request = this.getCapabilityRequest();
19376
+ const siweDomain = this.siweConfig?.domain ?? this.domain;
19377
+ const hasNamedKeys = request?.manifests.some((manifest) => manifest.keys?.length && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id));
19378
+ if (hasNamedKeys) {
19379
+ await this.resolveTinyCloudHostsForSignIn(address, chainId);
19380
+ await this.refreshNodeInfo();
19381
+ }
19382
+ }
19383
+ /** Manifest key paths that this sign-in cannot grant. */
19384
+ get unavailableKeyPaths() {
19385
+ const request = this.getCapabilityRequest();
19386
+ const siweDomain = this.siweConfig?.domain ?? this.domain;
19387
+ return (request?.manifests ?? []).flatMap(
19388
+ (manifest) => this._nodeFeatures.includes("encryption-named-keys-v1") && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id) ? [] : (manifest.keys ?? []).map((entry) => "path" in entry ? entry.path : entry.prefix)
19389
+ );
19390
+ }
19345
19391
  resolveSpaceName(space, address, chainId) {
19346
19392
  if (space.startsWith("tinycloud:")) {
19347
19393
  return space;
@@ -19533,15 +19579,31 @@ var NodeUserAuthorization = class {
19533
19579
  }
19534
19580
  const rawAbilities = {};
19535
19581
  const currentDid = (0, import_sdk_core5.pkhDid)(address, chainId);
19582
+ if (this._nodeFeatures.includes("encryption-named-keys-v1")) {
19583
+ const siweDomain = this.siweConfig?.domain ?? this.domain;
19584
+ for (const manifest of request.manifests) {
19585
+ if (!appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id)) continue;
19586
+ for (const declaration of manifest.keys ?? []) {
19587
+ const path = "path" in declaration ? declaration.path : declaration.prefix;
19588
+ const resource = `urn:tinycloud:encryption:${currentDid}:default/${path}`;
19589
+ for (const ability of declaration.abilities) {
19590
+ addRawAbility(rawAbilities, resource, `tinycloud.encryption/${ability}`);
19591
+ }
19592
+ }
19593
+ }
19594
+ }
19536
19595
  const spaceResources = request.resources.filter((entry) => {
19537
19596
  if (entry.service !== import_sdk_core5.ENCRYPTION_PERMISSION_SERVICE) {
19538
19597
  return true;
19539
19598
  }
19599
+ const parsed = entry.path.includes("/") ? (0, import_resource.parseEncryptionResource)(entry.path) : { ...(0, import_sdk_services3.parseNetworkId)(entry.path), kind: "network" };
19600
+ if (parsed.kind !== "network") {
19601
+ throw new import_sdk_core5.ManifestValidationError("named keys go in manifest.keys");
19602
+ }
19540
19603
  for (const action of entry.actions) {
19541
19604
  addRawAbility(rawAbilities, entry.path, action);
19542
19605
  }
19543
- if (entry.actions.includes(DECRYPT_ACTION)) {
19544
- const parsed = (0, import_sdk_core5.parseNetworkId)(entry.path);
19606
+ if (entry.actions.includes(DECRYPT_ACTION) && parsed.kind === "network") {
19545
19607
  if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
19546
19608
  addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
19547
19609
  }
@@ -19937,6 +19999,8 @@ var NodeUserAuthorization = class {
19937
19999
  this._chainId = chainId;
19938
20000
  await this.resolveTinyCloudHostsForSignIn(address, chainId);
19939
20001
  this.assertSignInCurrent(generation);
20002
+ await this.refreshNamedKeyFeatureForSignIn(address, chainId);
20003
+ this.assertSignInCurrent(generation);
19940
20004
  const keyId = `session-${Date.now()}`;
19941
20005
  this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
19942
20006
  this.activeSessionKeyId = keyId;
@@ -20083,6 +20147,7 @@ var NodeUserAuthorization = class {
20083
20147
  refuseCaveated(this.getCapabilityRequest()?.manifests);
20084
20148
  const address = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
20085
20149
  const chainId = await this.signer.getChainId();
20150
+ await this.refreshNamedKeyFeatureForSignIn(address, chainId);
20086
20151
  const keyId = `session-${Date.now()}`;
20087
20152
  this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
20088
20153
  this.activeSessionKeyId = keyId;
@@ -21667,6 +21732,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21667
21732
  return void 0;
21668
21733
  }
21669
21734
  };
21735
+ this._keysUnavailable = [];
21670
21736
  this._baseVaults = /* @__PURE__ */ new Map();
21671
21737
  this._baseSecrets = /* @__PURE__ */ new Map();
21672
21738
  this._secrets = /* @__PURE__ */ new Map();
@@ -22494,6 +22560,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22494
22560
  this._hooks = void 0;
22495
22561
  this._vault = void 0;
22496
22562
  this._encryption = void 0;
22563
+ this._namedKeyClient = void 0;
22564
+ this._keysUnavailable = [];
22497
22565
  this._baseVaults.clear();
22498
22566
  this._baseSecrets.clear();
22499
22567
  this._secrets.clear();
@@ -22616,6 +22684,8 @@ var _TinyCloudNode = class _TinyCloudNode {
22616
22684
  this._hooks = void 0;
22617
22685
  this._vault = void 0;
22618
22686
  this._encryption = void 0;
22687
+ this._namedKeyClient = void 0;
22688
+ this._keysUnavailable = [];
22619
22689
  this._baseVaults.clear();
22620
22690
  this._baseSecrets.clear();
22621
22691
  this._secrets.clear();
@@ -22668,6 +22738,26 @@ var _TinyCloudNode = class _TinyCloudNode {
22668
22738
  this.assertSessionEpoch(epoch, "Sign-in");
22669
22739
  await this.ensureRequestedEncryptionNetworks();
22670
22740
  this.assertSessionEpoch(epoch, "Sign-in");
22741
+ this._keysUnavailable = this.auth?.unavailableKeyPaths ?? [];
22742
+ if (this._keysUnavailable.length > 0) {
22743
+ this.notificationHandler.warning(`Named keys unavailable: ${this._keysUnavailable.join(", ")}`);
22744
+ }
22745
+ if (this.nodeFeatures.includes("encryption-named-keys-v1")) {
22746
+ for (const manifest of this.auth?.capabilityRequest?.manifests ?? []) {
22747
+ for (const declaration of manifest.keys ?? []) {
22748
+ if ("path" in declaration && declaration.abilities.includes("key.create") && !this._keysUnavailable.includes(declaration.path)) {
22749
+ try {
22750
+ await this.keys.ensureKey(declaration.path);
22751
+ } catch (error) {
22752
+ this._keysUnavailable.push(declaration.path);
22753
+ const code = error && typeof error === "object" && "code" in error && typeof error.code === "string" && /^[A-Z_]+$/.test(error.code) ? error.code : "UNKNOWN";
22754
+ this.notificationHandler.warning(`Named key unavailable: ${declaration.path} (${code})`);
22755
+ }
22756
+ this.assertSessionEpoch(epoch, "Sign-in");
22757
+ }
22758
+ }
22759
+ }
22760
+ }
22671
22761
  if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
22672
22762
  await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(import_sdk_core10.SECRETS_SPACE));
22673
22763
  }
@@ -23244,7 +23334,7 @@ var _TinyCloudNode = class _TinyCloudNode {
23244
23334
  if (!this.currentSessionCoversAccountRegistry()) {
23245
23335
  if (!_TinyCloudNode.accountRegistrySkipLogged) {
23246
23336
  _TinyCloudNode.accountRegistrySkipLogged = true;
23247
- import_sdk_services3.tinyCloudDebugLogger.log("registry.skip");
23337
+ import_sdk_services4.tinyCloudDebugLogger.log("registry.skip");
23248
23338
  }
23249
23339
  return;
23250
23340
  }
@@ -23455,7 +23545,8 @@ var _TinyCloudNode = class _TinyCloudNode {
23455
23545
  const networkIds = /* @__PURE__ */ new Set();
23456
23546
  for (const resource of request.resources) {
23457
23547
  if (resource.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
23458
- networkIds.add(resource.path);
23548
+ const parsed = resource.path.includes("/") ? (0, import_resource2.parseEncryptionResource)(resource.path) : { ...(0, import_sdk_core10.parseNetworkId)(resource.path), kind: "network" };
23549
+ if (parsed.kind === "network") networkIds.add(resource.path);
23459
23550
  }
23460
23551
  }
23461
23552
  return [...networkIds];
@@ -24005,6 +24096,8 @@ var _TinyCloudNode = class _TinyCloudNode {
24005
24096
  this._hooks = stagedGraph.hooks;
24006
24097
  this._vault = stagedGraph.vault;
24007
24098
  this._encryption = stagedGraph.encryption;
24099
+ this._namedKeyClient = void 0;
24100
+ this._keysUnavailable = [];
24008
24101
  this._capabilityRegistry = stagedGraph.capabilityRegistry;
24009
24102
  this._keyProvider = stagedGraph.keyProvider;
24010
24103
  this._sharingService = stagedGraph.sharingService;
@@ -24914,7 +25007,7 @@ var _TinyCloudNode = class _TinyCloudNode {
24914
25007
  );
24915
25008
  graph.assertActive();
24916
25009
  if (!response.ok) {
24917
- const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services3.parsePermissionHint)({
25010
+ const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services4.parsePermissionHint)({
24918
25011
  service: "tinycloud.encryption",
24919
25012
  path: networkId,
24920
25013
  actions: ["tinycloud.encryption/decrypt"]
@@ -25601,6 +25694,40 @@ var _TinyCloudNode = class _TinyCloudNode {
25601
25694
  get encryption() {
25602
25695
  return this.getEncryptionService();
25603
25696
  }
25697
+ /** Named keys bound to the current session. */
25698
+ get keys() {
25699
+ return new Proxy({}, {
25700
+ get: (_target, property) => {
25701
+ if (property === "refreshNodeInfo") {
25702
+ return () => {
25703
+ void this._namedKeyClient?.then((client) => client.refreshNodeInfo());
25704
+ };
25705
+ }
25706
+ if (typeof property !== "string" || ![
25707
+ "getPublicKey",
25708
+ "describeKey",
25709
+ "createKey",
25710
+ "blockKey",
25711
+ "unblockKey",
25712
+ "ensureKey",
25713
+ "encrypt",
25714
+ "decrypt",
25715
+ "decryptMany"
25716
+ ].includes(property)) return void 0;
25717
+ return (...args) => {
25718
+ this._namedKeyClient ?? (this._namedKeyClient = import("./encryption-keys.cjs").then(({ createNamedKeyClient }) => createNamedKeyClient(this)));
25719
+ return this._namedKeyClient.then((client) => {
25720
+ const method = client[property];
25721
+ return method.apply(client, args);
25722
+ });
25723
+ };
25724
+ }
25725
+ });
25726
+ }
25727
+ /** Manifest key paths unavailable during the latest `signIn()` attempt. */
25728
+ get keysUnavailable() {
25729
+ return this._keysUnavailable;
25730
+ }
25604
25731
  async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
25605
25732
  const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
25606
25733
  return this.fetchEncryptionNetworkAt(
@@ -25728,7 +25855,7 @@ var _TinyCloudNode = class _TinyCloudNode {
25728
25855
  );
25729
25856
  if (result.status !== "ok") {
25730
25857
  if (result.status === "permission_required") {
25731
- const hint = (0, import_sdk_services3.parsePermissionHint)(result.hint);
25858
+ const hint = (0, import_sdk_services4.parsePermissionHint)(result.hint);
25732
25859
  if (hint === void 0) return { status: "read_failed" };
25733
25860
  return {
25734
25861
  status: "permission_required",
@@ -28073,7 +28200,7 @@ var import_node_fs = require("fs");
28073
28200
  var import_promises = require("fs/promises");
28074
28201
  var import_node_path = require("path");
28075
28202
  var import_sdk_core14 = require("@tinycloud/sdk-core");
28076
- var import_sdk_services4 = require("@tinycloud/sdk-services");
28203
+ var import_sdk_services5 = require("@tinycloud/sdk-services");
28077
28204
  var import_contractConstants = require("@tinycloud/sdk-services/kv/replication/contractConstants");
28078
28205
  init_authority();
28079
28206
  var REPLICA_LOGOUT_PENDING_FILE = "replica-logout-pending.json";
@@ -28635,7 +28762,7 @@ function sha256Base32(material) {
28635
28762
  return out.slice(0, 26);
28636
28763
  }
28637
28764
  function partitionDirOf(root, identity) {
28638
- return (0, import_node_path.join)(root, sha256Base32((0, import_sdk_services4.replicationIdentityKey)(identity)));
28765
+ return (0, import_node_path.join)(root, sha256Base32((0, import_sdk_services5.replicationIdentityKey)(identity)));
28639
28766
  }
28640
28767
  function replicaHashOf(prefix, deviceDid) {
28641
28768
  return sha256Base32(`${prefix}
@@ -28709,8 +28836,8 @@ function deviceRecordOf(value) {
28709
28836
  }
28710
28837
  function sameIdentity(a, b) {
28711
28838
  try {
28712
- const left = (0, import_sdk_services4.canonicalReplicationIdentity)(a);
28713
- const right = (0, import_sdk_services4.canonicalReplicationIdentity)(b);
28839
+ const left = (0, import_sdk_services5.canonicalReplicationIdentity)(a);
28840
+ const right = (0, import_sdk_services5.canonicalReplicationIdentity)(b);
28714
28841
  return left.host === right.host && left.space === right.space && left.principal === right.principal;
28715
28842
  } catch {
28716
28843
  return false;
@@ -28726,7 +28853,7 @@ async function ensurePartitionIdentity(dir, identity, dirSync) {
28726
28853
  const file = (0, import_node_path.join)(dir, "identity.json");
28727
28854
  const existing = await readJsonFile(file);
28728
28855
  if (existing === void 0) {
28729
- await writeJsonAtomic(file, { v: 1, ...(0, import_sdk_services4.canonicalReplicationIdentity)(identity) }, dirSync);
28856
+ await writeJsonAtomic(file, { v: 1, ...(0, import_sdk_services5.canonicalReplicationIdentity)(identity) }, dirSync);
28730
28857
  return;
28731
28858
  }
28732
28859
  const record = identityRecordOf(existing);
@@ -28825,7 +28952,7 @@ withGate_fn = async function(section) {
28825
28952
  if (snapshot === void 0) throw gated("gate_unavailable");
28826
28953
  const [principalHash, identityKeyHash] = await Promise.all([
28827
28954
  gate.principalHashOf(snapshot.salt, this.identity.principal),
28828
- gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(this.identity))
28955
+ gate.identityHashOf(snapshot.salt, (0, import_sdk_services5.replicationIdentityKey)(this.identity))
28829
28956
  ]);
28830
28957
  const access = {
28831
28958
  stamp: __privateGet(this, _stamp),
@@ -29325,7 +29452,7 @@ function createSqliteReplicaStorage(options) {
29325
29452
  if (snapshot === void 0) throw gated("gate_unavailable");
29326
29453
  const [principalHash, identityKeyHash] = await Promise.all([
29327
29454
  gate.principalHashOf(snapshot.salt, principal),
29328
- identity === void 0 ? Promise.resolve(void 0) : gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(identity))
29455
+ identity === void 0 ? Promise.resolve(void 0) : gate.identityHashOf(snapshot.salt, (0, import_sdk_services5.replicationIdentityKey)(identity))
29329
29456
  ]);
29330
29457
  return profileSection(async () => {
29331
29458
  assertLogoutClear(options.logoutPendingFile);
@@ -29348,7 +29475,7 @@ function createSqliteReplicaStorage(options) {
29348
29475
  if (snapshot === void 0) throw gated("gate_unavailable");
29349
29476
  const [principalHash, identityKeyHash] = await Promise.all([
29350
29477
  gate.principalHashOf(snapshot.salt, spec.identity.principal),
29351
- gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(spec.identity))
29478
+ gate.identityHashOf(snapshot.salt, (0, import_sdk_services5.replicationIdentityKey)(spec.identity))
29352
29479
  ]);
29353
29480
  const access = {
29354
29481
  stamp: spec.stamp,
@@ -29432,7 +29559,7 @@ function createSqliteReplicaStorage(options) {
29432
29559
  const identity = identityRecordOf(await readJsonFile((0, import_node_path.join)(idDir, "identity.json")));
29433
29560
  if (identity === void 0) throw new ReplicaStorageError("STORAGE_ERROR", `Missing identity at ${idDir}.`);
29434
29561
  if (await gate.principalHashOf(salt, identity.principal) !== principalHash) continue;
29435
- const identityKeyHash = await gate.identityHashOf(salt, (0, import_sdk_services4.replicationIdentityKey)(identity));
29562
+ const identityKeyHash = await gate.identityHashOf(salt, (0, import_sdk_services5.replicationIdentityKey)(identity));
29436
29563
  const recordedAt = Date.now();
29437
29564
  if (await pathExists((0, import_node_path.join)(idDir, "pending.json")) || await pathExists((0, import_node_path.join)(idDir, "device.jwk"))) {
29438
29565
  intents.push({ id: `pending:${identityKeyHash}`, kind: "pending", identityKeyHash, principalHash, recordedAt });
@@ -30110,7 +30237,7 @@ function createSqliteReplicaStorage(options) {
30110
30237
  for (const dir of await identityDirs()) {
30111
30238
  const identity = identityRecordOf(await readJsonFile((0, import_node_path.join)(dir, "identity.json")));
30112
30239
  if (identity === void 0) throw new ReplicaStorageError("STORAGE_ERROR", `Missing identity at ${dir}.`);
30113
- const hash3 = await gate.identityHashOf(state.salt, (0, import_sdk_services4.replicationIdentityKey)(identity));
30240
+ const hash3 = await gate.identityHashOf(state.salt, (0, import_sdk_services5.replicationIdentityKey)(identity));
30114
30241
  if (intent.kind === "pending" ? hash3 === intent.identityKeyHash : intent.partitionId.startsWith(`${hash3}:`)) {
30115
30242
  idDir = dir;
30116
30243
  break;
@@ -30256,7 +30383,7 @@ function createSqliteReplicaStorage(options) {
30256
30383
  const gate = await fileGate();
30257
30384
  const snapshot = await gate.readGateSnapshot(profileDir);
30258
30385
  if (snapshot === void 0) throw gated("gate_unavailable");
30259
- const identityKeyHash = await gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(spec.identity));
30386
+ const identityKeyHash = await gate.identityHashOf(snapshot.salt, (0, import_sdk_services5.replicationIdentityKey)(spec.identity));
30260
30387
  const resolvePolicy = async (at, recordFirst) => {
30261
30388
  const policy = spec.grantPolicy;
30262
30389
  if (!Number.isSafeInteger(policy.grantTtlMs) || policy.grantTtlMs <= 0 || policy.grantTtlMs > import_contractConstants.MAX_GRANT_TTL_MS) {
@@ -30278,7 +30405,7 @@ function createSqliteReplicaStorage(options) {
30278
30405
  let partitionId;
30279
30406
  const storeGuard = (section) => guarded(spec.identity.principal, spec.stamp, spec.identity, partitionId, section);
30280
30407
  return guarded(spec.identity.principal, spec.stamp, spec.identity, void 0, async () => {
30281
- if ((0, import_sdk_services4.requiresSecretsOptIn)(spec.space, spec.prefix) && spec.allowSecrets !== true) {
30408
+ if ((0, import_sdk_services5.requiresSecretsOptIn)(spec.space, spec.prefix) && spec.allowSecrets !== true) {
30282
30409
  throw new replica.ReplicaError(
30283
30410
  replica.ReplicaErrorCode.SECRETS_OPT_IN_REQUIRED,
30284
30411
  `Replicating ${spec.space}/kv/${spec.prefix} copies secret material to disk; pass allowSecrets to opt in.`
@@ -30524,7 +30651,7 @@ function createSqliteReplicaStorage(options) {
30524
30651
  const gate = await fileGate();
30525
30652
  const currentGate = await gate.readGateSnapshot(profileDir);
30526
30653
  if (currentGate !== void 0 && currentGate.principalHash !== null && currentGate.principalHash === await gate.principalHashOf(currentGate.salt, target.identity.principal)) {
30527
- const identityKeyHash = await gate.identityHashOf(currentGate.salt, (0, import_sdk_services4.replicationIdentityKey)(target.identity));
30654
+ const identityKeyHash = await gate.identityHashOf(currentGate.salt, (0, import_sdk_services5.replicationIdentityKey)(target.identity));
30528
30655
  await retainGrantInstalls(gate, currentGate, identityKeyHash, store);
30529
30656
  }
30530
30657
  if (state.revoked === null) {