- Change file mode from 644 to 755 for all project files - Add chain_id parameter to get_balance RPC endpoint with default "ait-devnet" - Rename Miner.extra_meta_data to extra_metadata for consistency
78 lines
2.1 KiB
TypeScript
Executable File
78 lines
2.1 KiB
TypeScript
Executable File
import { describe, expect, it } from "vitest";
|
|
import { generateKeyPairSync, sign } from "crypto";
|
|
import { ReceiptService } from "./receipts";
|
|
import type { ReceiptSummary } from "./types";
|
|
|
|
class ThrowingClient {
|
|
async request() {
|
|
throw new Error("offline");
|
|
}
|
|
}
|
|
|
|
describe("ReceiptService signature verification", () => {
|
|
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
const publicKeyPem = publicKey.export({ type: "spki", format: "pem" }).toString();
|
|
|
|
const baseReceipt: ReceiptSummary = {
|
|
receiptId: "r1",
|
|
jobId: "job-123",
|
|
miner: "miner-1",
|
|
coordinator: "coord-1",
|
|
issuedAt: new Date().toISOString(),
|
|
status: "completed",
|
|
payload: {
|
|
job_id: "job-123",
|
|
provider: "miner-1",
|
|
client: "client-1",
|
|
},
|
|
};
|
|
|
|
const signPayload = (payload: Record<string, unknown>): string => {
|
|
const message = Buffer.from(JSON.stringify(payload));
|
|
return sign(null, message, privateKey).toString("base64");
|
|
};
|
|
|
|
it("validates with provided PEM keys", async () => {
|
|
const sig = signPayload(baseReceipt.payload!);
|
|
const receipt: ReceiptSummary = {
|
|
...baseReceipt,
|
|
payload: {
|
|
...baseReceipt.payload,
|
|
minerSignature: sig,
|
|
coordinatorSignature: sig,
|
|
},
|
|
};
|
|
|
|
const svc = new ReceiptService({
|
|
client: new ThrowingClient() as any,
|
|
minerPublicKeyPem: publicKeyPem,
|
|
coordinatorPublicKeyPem: publicKeyPem,
|
|
signatureAlgorithm: "ed25519",
|
|
});
|
|
|
|
const result = await svc.validateReceipt(receipt);
|
|
expect(result.valid).toBe(true);
|
|
});
|
|
|
|
it("fails with bad signature", async () => {
|
|
const receipt: ReceiptSummary = {
|
|
...baseReceipt,
|
|
payload: {
|
|
...baseReceipt.payload,
|
|
minerSignature: "bad",
|
|
coordinatorSignature: "bad",
|
|
},
|
|
};
|
|
|
|
const svc = new ReceiptService({
|
|
client: new ThrowingClient() as any,
|
|
minerPublicKeyPem: publicKeyPem,
|
|
coordinatorPublicKeyPem: publicKeyPem,
|
|
signatureAlgorithm: "ed25519",
|
|
});
|
|
|
|
const result = await svc.validateReceipt(receipt);
|
|
expect(result.valid).toBe(false);
|
|
});
|
|
});
|