mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-01 20:33:50 +00:00
Add the AgentBBS M5 "AgentAd marketplace" spec and a working reference
implementation built on the existing @logicsrc/schemas AgentAd contracts.
- docs/agentad-marketplace.md: two-sided exchange PRD (buy/sell sides,
match -> auction -> pace -> serve -> meter -> settle, CoinPay settlement,
AgentBBS as reference publisher, milestones M5.0-M5.5).
- packages/agentad (@logicsrc/agentad): reference exchange
- builders that emit schema-valid, always-disclosed ad/campaign/placement docs
- HMAC-signed, single-use impression/click tracking tokens
- AgentAdExchange: targeting/format/category matching, second-price auction,
budget pacing + daily caps, frequency capping, token-driven metering
- pluggable settlement (InMemorySettlement) that can't overspend escrow
- runtime validation against the canonical agentad-*.schema.json
- 22 vitest cases (builders, tokens, full serve/meter/settle lifecycle).
- Wire package into root build; link the PRD from README + docs/agentad.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { mintToken, verifyToken, type TokenPayload } from "./tokens.js";
|
|
|
|
const base: TokenPayload = {
|
|
k: "impression",
|
|
rid: "req-1",
|
|
pid: "plc-1",
|
|
aid: "ad-1",
|
|
cid: "cmp-1",
|
|
model: "cpc",
|
|
charge: 0.5,
|
|
cur: "USD",
|
|
exp: 2_000_000_000_000,
|
|
n: "abc123"
|
|
};
|
|
|
|
describe("AgentAd tracking tokens", () => {
|
|
it("round-trips a signed payload", () => {
|
|
const token = mintToken("s3cret", base);
|
|
const result = verifyToken("s3cret", token, 1_000);
|
|
expect(result.ok).toBe(true);
|
|
expect(result.payload).toEqual(base);
|
|
});
|
|
|
|
it("rejects a token signed with a different secret", () => {
|
|
const token = mintToken("s3cret", base);
|
|
const result = verifyToken("other", token, 1_000);
|
|
expect(result.ok).toBe(false);
|
|
expect(result.reason).toBe("bad_signature");
|
|
});
|
|
|
|
it("rejects a tampered body", () => {
|
|
const token = mintToken("s3cret", base);
|
|
const [, sig] = token.split(".");
|
|
const forged = `${Buffer.from(JSON.stringify({ ...base, charge: 9999 })).toString("base64url")}.${sig}`;
|
|
expect(verifyToken("s3cret", forged).ok).toBe(false);
|
|
});
|
|
|
|
it("rejects expired tokens", () => {
|
|
const token = mintToken("s3cret", { ...base, exp: 500 });
|
|
const result = verifyToken("s3cret", token, 1_000);
|
|
expect(result.ok).toBe(false);
|
|
expect(result.reason).toBe("expired");
|
|
});
|
|
|
|
it("flags malformed tokens", () => {
|
|
expect(verifyToken("s3cret", "not-a-token").reason).toBe("malformed");
|
|
});
|
|
});
|