feat(client): add keypair generation
This commit is contained in:
@@ -9,11 +9,12 @@ import {
|
||||
} from "../../../Yonexus.Protocol/src/index.js";
|
||||
import type { YonexusClientConfig } from "./config.js";
|
||||
import {
|
||||
createInitialClientState,
|
||||
ensureClientKeyPair,
|
||||
hasClientKeyPair,
|
||||
hasClientSecret,
|
||||
type YonexusClientState,
|
||||
type YonexusClientStateStore
|
||||
createInitialClientState,
|
||||
YonexusClientState,
|
||||
YonexusClientStateStore
|
||||
} from "./state.js";
|
||||
import type { ClientConnectionState, ClientTransport } from "./transport.js";
|
||||
|
||||
@@ -66,7 +67,12 @@ export class YonexusClientRuntime {
|
||||
}
|
||||
|
||||
this.phase = "starting";
|
||||
this.clientState = await this.options.stateStore.load(this.options.config.identifier);
|
||||
|
||||
// Load existing state and ensure key pair exists
|
||||
let state = await this.options.stateStore.load(this.options.config.identifier);
|
||||
const keyResult = await ensureClientKeyPair(state, this.options.stateStore);
|
||||
this.clientState = keyResult.state;
|
||||
|
||||
await this.options.transport.connect();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
||||
import { dirname } from "node:path";
|
||||
import { generateKeyPair, type KeyPair } from "../crypto/keypair.js";
|
||||
|
||||
export const CLIENT_STATE_VERSION = 1;
|
||||
|
||||
@@ -132,6 +133,31 @@ export function hasClientKeyPair(state: YonexusClientState): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the client state has a valid key pair.
|
||||
* If no key pair exists, generates a new Ed25519 key pair.
|
||||
* Returns the (possibly updated) state and whether a new key was generated.
|
||||
*/
|
||||
export async function ensureClientKeyPair(
|
||||
state: YonexusClientState,
|
||||
stateStore: YonexusClientStateStore
|
||||
): Promise<{ state: YonexusClientState; generated: boolean }> {
|
||||
if (hasClientKeyPair(state)) {
|
||||
return { state, generated: false };
|
||||
}
|
||||
|
||||
const keyPair = await generateKeyPair();
|
||||
const updatedState: YonexusClientState = {
|
||||
...state,
|
||||
privateKey: keyPair.privateKey,
|
||||
publicKey: keyPair.publicKey,
|
||||
updatedAt: Math.floor(Date.now() / 1000)
|
||||
};
|
||||
|
||||
await stateStore.save(updatedState);
|
||||
return { state: updatedState, generated: true };
|
||||
}
|
||||
|
||||
function assertClientStateShape(
|
||||
value: unknown,
|
||||
filePath: string
|
||||
|
||||
Reference in New Issue
Block a user