kog-fee-verify / tree / test/verify.test.ts ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
import { test } from "node:test";
import assert from "node:assert/strict";
import { verifyKogFee } from "../src/index.js";
import { load, PYUSD, USDG, X402, MEMO, USDG_TX } from "./fixtures.js";

const quote = (amount: string, expires_at: number | string = X402.blockTime + 60) => ({ amount, expires_at });

test("A1 right fee: a recorded Token 2022 x402 payment of the quoted amount to the payee is accepted", () => {
  const tx = load(X402.name);
  const r = verifyKogFee({ tx, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD, seen: new Set() });
  assert.deepEqual(r, { ok: true, reason: "ok", signature: tx.transaction.signatures[0], received: X402.amount });
  // paying more than the quote is fine; the payee may also be given as its token account
  assert.equal(verifyKogFee({ tx, quote: quote("39999999"), payee: X402.payee, mint: PYUSD }).ok, true);
  assert.equal(verifyKogFee({ tx, quote: quote(X402.amount), payee: X402.payeeAta, mint: PYUSD }).ok, true);
  // a second real transfer (with a memo instruction) also passes
  const m = load(MEMO.name);
  assert.equal(verifyKogFee({ tx: m, quote: { amount: MEMO.amount, expires_at: MEMO.blockTime }, payee: MEMO.payee, mint: PYUSD }).reason, "ok");
});

test("A2 short fee: a payment below the quote is refused with short_fee and the amount received", () => {
  const tx = load(X402.name);
  const r = verifyKogFee({ tx, quote: quote("40000001"), payee: X402.payee, mint: PYUSD, seen: [] });
  assert.equal(r.ok, false);
  assert.equal(r.reason, "short_fee");
  assert.equal(r.received, X402.amount);
});

test("A3 wrong mint: a real Token 2022 transfer in another mint is refused", () => {
  const tx = load(USDG_TX.name);
  const r = verifyKogFee({ tx, quote: { amount: "1", expires_at: USDG_TX.blockTime + 60 }, payee: USDG_TX.payee, mint: PYUSD });
  assert.deepEqual([r.ok, r.reason], [false, "wrong_mint"]);
  // the same transaction is fine for its own mint
  assert.equal(verifyKogFee({ tx, quote: { amount: USDG_TX.amount, expires_at: USDG_TX.blockTime }, payee: USDG_TX.payee, mint: USDG }).ok, true);
});

test("A4 wrong payee: the right mint paid to someone else is refused, including the payer itself", () => {
  const tx = load(X402.name);
  for (const payee of [MEMO.payee, X402.payer]) {
    const r = verifyKogFee({ tx, quote: quote("1"), payee, mint: PYUSD });
    assert.deepEqual([r.ok, r.reason], [false, "wrong_payee"], payee);
  }
});

test("A5 expired quote: a payment landed after the quote expiry is refused", () => {
  const tx = load(X402.name);
  assert.equal(verifyKogFee({ tx, quote: quote(X402.amount, X402.blockTime - 1), payee: X402.payee, mint: PYUSD }).reason, "expired");
  assert.equal(verifyKogFee({ tx, quote: quote(X402.amount, X402.blockTime), payee: X402.payee, mint: PYUSD }).reason, "ok");
  const iso = new Date((X402.blockTime - 30) * 1000).toISOString();
  assert.equal(verifyKogFee({ tx, quote: quote(X402.amount, iso), payee: X402.payee, mint: PYUSD }).reason, "expired");
  // with no blockTime the caller's now is used, and with neither the input is refused
  const noTime = { ...tx, blockTime: null };
  assert.equal(verifyKogFee({ tx: noTime, quote: quote(X402.amount, 100), payee: X402.payee, mint: PYUSD, now: 101 }).reason, "expired");
  assert.equal(verifyKogFee({ tx: noTime, quote: quote(X402.amount, 100), payee: X402.payee, mint: PYUSD }).reason, "bad_input");
});

test("A6 replay: a signature already used for a fee is refused, whatever form seen takes", () => {
  const tx = load(X402.name);
  const sig = tx.transaction.signatures[0];
  for (const seen of [new Set([sig]), [sig], new Map([[sig, true]]), { has: (s: string) => s === sig }]) {
    const r = verifyKogFee({ tx, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD, seen });
    assert.deepEqual([r.ok, r.reason, r.signature], [false, "replay", sig]);
  }
});

test("A7 a failed transaction, a bad quote or malformed input never pass", () => {
  const tx = load(X402.name);
  const failed = structuredClone(tx);
  failed.meta.err = { InstructionError: [2, { Custom: 1 }] };
  assert.equal(verifyKogFee({ tx: failed, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD }).reason, "tx_failed");
  assert.equal(verifyKogFee({ tx, quote: quote("0"), payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
  assert.equal(verifyKogFee({ tx, quote: quote("1.5"), payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
  assert.equal(verifyKogFee({ tx, quote: { amount: X402.amount, expires_at: "soon" }, payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
  assert.equal(verifyKogFee({ tx, quote: { ...quote(X402.amount), mint: USDG }, payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
  assert.equal(verifyKogFee({ tx: {}, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD }).reason, "bad_input");
  assert.equal(verifyKogFee({ tx, quote: quote(X402.amount), payee: "", mint: PYUSD }).reason, "bad_input");
  assert.equal(verifyKogFee(null as any).reason, "bad_input");
});

test("A7 a balance rise without a transfer instruction to the payee (for example a swap) is not a fee", () => {
  const tx = structuredClone(load(X402.name));
  tx.transaction.message.instructions = tx.transaction.message.instructions.filter((i: any) => i.parsed?.type !== "transferChecked");
  assert.equal(verifyKogFee({ tx, quote: quote("1"), payee: X402.payee, mint: PYUSD }).reason, "wrong_mint");
});

test("A7 the verifier is pure: same input, same answer, and the transaction is not changed", () => {
  const tx = load(X402.name);
  const before = JSON.stringify(tx);
  const a = verifyKogFee({ tx, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD });
  const b = verifyKogFee({ tx, quote: quote(X402.amount), payee: X402.payee, mint: PYUSD });
  assert.deepEqual(a, b);
  assert.equal(JSON.stringify(tx), before);
});

test("A7 a quote bound to another payee or mint is refused as bad_quote", () => {
  const tx = load(X402.name);
  const base = { amount: X402.amount, expires_at: X402.blockTime + 60 };
  assert.equal(verifyKogFee({ tx, quote: { ...base, payee: X402.payee, mint: PYUSD }, payee: X402.payee, mint: PYUSD }).ok, true);
  assert.equal(verifyKogFee({ tx, quote: { ...base, payee: MEMO.payee }, payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
  assert.equal(verifyKogFee({ tx, quote: { ...base, mint: USDG }, payee: X402.payee, mint: PYUSD }).reason, "bad_quote");
});

test("A2 short fee: a payee token account closed in the same transaction counts against what was received", () => {
  const tx = load(X402.name);
  const keys = tx.transaction.message.accountKeys;
  const idx = keys.length;
  keys.push(typeof keys[0] === "string" ? "ClosedPayeeAta11111111111111111111111111111" : { ...keys[0], pubkey: "ClosedPayeeAta11111111111111111111111111111", signer: false, writable: true });
  tx.meta.preTokenBalances.push({ accountIndex: idx, mint: PYUSD, owner: X402.payee, uiTokenAmount: { amount: "1000", decimals: 6 } });
  const r = verifyKogFee({ tx, quote: { amount: X402.amount, expires_at: X402.blockTime + 60 }, payee: X402.payee, mint: PYUSD });
  assert.deepEqual([r.ok, r.reason, r.received], [false, "short_fee", String(BigInt(X402.amount) - 1000n)]);
});

agentgate-source: code mirror on Cloudflare Pages. All repos