Skip to content

Commit d7f5c50

Browse files
committed
(refactor) (openai/gpt-5.5, reviewed T, tested T) make vfnode identity a class
1 parent 7d06f77 commit d7f5c50

4 files changed

Lines changed: 46 additions & 26 deletions

File tree

packages/vfnode/src/Identity.ts

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,47 @@
11
import { randomUUID } from "node:crypto";
22
import type { Address, Hex } from "viem";
33
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
4+
import { err, ok, type Result } from "./result.js";
45

56
export type NodeId = string & { readonly __brand: "nodeId" };
67

7-
export type Identity = {
8-
readonly nodeId: NodeId;
9-
readonly publicAddress: Address;
10-
readonly privateKey: Hex;
11-
};
8+
export class Identity {
9+
readonly #nodeId: NodeId;
10+
readonly #publicAddress: Address;
11+
readonly #privateKey: Hex;
1212

13-
export function createNodeId(): NodeId {
14-
return randomUUID() as NodeId;
15-
}
13+
private constructor(nodeId: NodeId, publicAddress: Address, privateKey: Hex) {
14+
this.#nodeId = nodeId;
15+
this.#publicAddress = publicAddress;
16+
this.#privateKey = privateKey;
17+
}
18+
19+
static create(nodeId: NodeId): Result<Identity, "failed_to_create_identity"> {
20+
try {
21+
const privateKey = generatePrivateKey();
22+
const account = privateKeyToAccount(privateKey);
23+
24+
return ok(new Identity(nodeId, account.address, privateKey));
25+
} catch {
26+
return err("failed_to_create_identity");
27+
}
28+
}
29+
30+
get nodeId(): NodeId {
31+
return this.#nodeId;
32+
}
1633

17-
export function createIdentity(): Identity {
18-
const privateKey = generatePrivateKey();
19-
const account = privateKeyToAccount(privateKey);
34+
get publicAddress(): Address {
35+
return this.#publicAddress;
36+
}
2037

21-
return {
22-
nodeId: createNodeId(),
23-
publicAddress: account.address,
24-
privateKey,
25-
};
38+
async signMessage(message: string): Promise<Hex> {
39+
const account = privateKeyToAccount(this.#privateKey);
40+
41+
return account.signMessage({ message });
42+
}
43+
}
44+
45+
export function createNodeId(): NodeId {
46+
return randomUUID() as NodeId;
2647
}

packages/vfnode/src/SignedBay.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { TextDecoder, TextEncoder } from "node:util";
22
import { isAddressEqual, recoverMessageAddress, toHex, type Address, type Hex } from "viem";
3-
import { privateKeyToAccount } from "viem/accounts";
43
import type { Bay, BayEndpoint, BayErrorListener, BayPacketListener } from "./Bay.js";
54
import type { Identity, NodeId } from "./Identity.js";
65

@@ -33,11 +32,6 @@ export class SignedBay {
3332
#sequence = 0;
3433

3534
constructor(options: SignedBayOptions) {
36-
const account = privateKeyToAccount(options.identity.privateKey);
37-
if (!isAddressEqual(account.address, options.identity.publicAddress)) {
38-
throw new Error("Identity publicAddress does not match privateKey");
39-
}
40-
4135
this.#bay = options.bay;
4236
this.#identity = options.identity;
4337
this.#now = options.now ?? Date.now;
@@ -75,8 +69,7 @@ export class SignedBay {
7569
timestamp: this.#now(),
7670
payload: toHex(data),
7771
};
78-
const account = privateKeyToAccount(this.#identity.privateKey);
79-
const signature = await account.signMessage({ message: signedBayMessage(packet) });
72+
const signature = await this.#identity.signMessage(signedBayMessage(packet));
8073

8174
this.#sequence += 1;
8275

packages/vfnode/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export type {
88
BayRemote,
99
BaySocketType,
1010
} from "./Bay.js";
11-
export { createIdentity, createNodeId } from "./Identity.js";
12-
export type { Identity, NodeId } from "./Identity.js";
11+
export { Identity, createNodeId } from "./Identity.js";
12+
export type { NodeId } from "./Identity.js";
1313
export {
1414
SignedBay,
1515
decodeSignedBayPacket,

packages/vfnode/src/result.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type Result<T, E = Error> =
2+
| { readonly ok: true; readonly value: T }
3+
| { readonly ok: false; readonly error: E };
4+
5+
export const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });
6+
export const err = <E>(error: E): Result<never, E> => ({ ok: false, error });

0 commit comments

Comments
 (0)