1234567891011121314import { Capacitor, registerPlugin } from "@capacitor/core";15import { generateKeyPair } from "@stablelib/x25519";1617interface SyncKeyPlugin {18 19202122 loadKeypair(): Promise<{ privateKeyHex: string; publicKeyHex: string }>;23 24 saveKeypair(keys: { privateKeyHex: string; publicKeyHex: string }): Promise<void>;25}2627const SyncKey = registerPlugin<SyncKeyPlugin>("SyncKey");2829let cached: { privateKey: Uint8Array; publicKey: Uint8Array } | null = null;3031function bytesToHex(bytes: Uint8Array): string {32 return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");33}3435function hexToBytes(hex: string): Uint8Array {36 const out = new Uint8Array(hex.length / 2);37 for (let i = 0; i < hex.length; i += 2) {38 out[i / 2] = parseInt(hex.slice(i, i + 2), 16);39 }40 return out;41}4243export async function getAndroidSyncIdentity(): Promise<{44 privateKey: Uint8Array;45 publicKey: Uint8Array;46}> {47 if (cached) return cached;48 if (!Capacitor.isNativePlatform()) {49 throw new Error("Android sync identity requested on non-native platform");50 }5152 const stored = await SyncKey.loadKeypair();53 if (stored.privateKeyHex && stored.publicKeyHex) {54 cached = {55 privateKey: hexToBytes(stored.privateKeyHex),56 publicKey: hexToBytes(stored.publicKeyHex),57 };58 return cached;59 }6061 const pair = generateKeyPair();62 const privateKeyHex = bytesToHex(pair.secretKey);63 const publicKeyHex = bytesToHex(pair.publicKey);64 await SyncKey.saveKeypair({ privateKeyHex, publicKeyHex });65 cached = { privateKey: pair.secretKey, publicKey: pair.publicKey };66 return cached;67}686970export function __resetForTests(): void {71 cached = null;72}