loadHubIdentity function

Future<HubIdentity> loadHubIdentity(
  1. String path
)

Loads the hub identity persisted at path, creating it (mode 0600, atomic temp+rename) on first use. File format — the SAME lines the CLI's fa_hub_client key files use — so a host may share one identity across surfaces when it wants to: ed25519:<seed b64>, x25519:<priv b64>, x25519pub:<pub b64>. The pub line is informational; keys are always re-derived from the private scalars, so a torn legacy write can never pair a mismatched pub.

Implementation

Future<HubIdentity> loadHubIdentity(String path) async {
  final file = File(path);
  if (await file.exists()) {
    final fields = <String, String>{};
    for (final line in await file.readAsString().then((c) => c.split('\n'))) {
      final idx = line.indexOf(':');
      if (idx > 0) fields[line.substring(0, idx)] = line.substring(idx + 1);
    }
    final edSeed = fields['ed25519'];
    final xPriv = fields['x25519'];
    if (edSeed != null && xPriv != null) {
      try {
        return await HubIdentity.fromSeeds(
          ed25519Seed: base64Decode(edSeed),
          x25519Private: base64Decode(xPriv),
        );
      } on Object {
        // A torn or corrupt file falls through to regeneration: a fresh
        // address beats an unusable fabric; save overwrites the file.
      }
    }
  }
  final identity = await HubIdentity.fromSeeds(
    ed25519Seed: _randomBytes(32),
    x25519Private: _randomBytes(32),
  );
  final signingSeed = await identity.signingKeyPair.extractPrivateKeyBytes();
  final dhPriv = await identity.dhKeyPair.extractPrivateKeyBytes();
  await File(path).parent.create(recursive: true);
  // Atomic create via temp + rename: a crashed direct write could tear the
  // file mid-line and break every later load.
  final tmp = File('$path.tmp');
  await tmp.writeAsString(
    'ed25519:${base64Encode(signingSeed)}\n'
    'x25519:${base64Encode(dhPriv)}\n'
    'x25519pub:${identity.dhPubkeyB64}\n',
    flush: true,
  );
  await tmp.rename(path);
  if (!await _chmod600(path)) {
    stderr.writeln(
      '[hub] warning: identity file $path was NOT locked to mode 0600 — '
      'the private keys may be readable by other local users',
    );
  }
  return identity;
}