Files
aitbc/packages/js/aitbc-sdk/src/receipts.test.ts
oib 825f157749 Update Python version requirements and fix compatibility issues
- Bump minimum Python version from 3.11 to 3.13 across all apps
- Add Python 3.11-3.13 test matrix to CLI workflow
- Document Python 3.11+ requirement in .env.example
- Fix Starlette Broadcast removal with in-process fallback implementation
- Add _InProcessBroadcast class for tests when Starlette Broadcast is unavailable
- Refactor API key validators to read live settings instead of cached values
- Update database models with explicit
2026-02-24 18:41:08 +01:00

78 lines
2.1 KiB
TypeScript

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);
});
});