You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 8e10ebc
Browse filesBrowse the repository at this point in the historyBrowse files
Record what the crawler paywall earns, and show it publicly (#37)
* Write down what the crawler paywall does, and put it on a public board
The gateway has been answering 402 and selling day passes for weeks and none
of it was recorded: a sale existed only for as long as the response took to
send. So 'what did the paywall earn' and 'which agent is the customer' had no
answer. Two tables now hold it. A sale is money (crawl_sales, unique on the
payment ref so a settlement delivered twice books once). A refusal is demand
(crawl_demand, counted per agent per day rather than stored per request, so
thousands a day stay small enough to keep forever).
Both writes are fire and forget. Bookkeeping must not fail a payment the
buyer already made, or turn a 402 into a 500.
The board shows the two sides apart: agents paying ranked by money, agents
not paying ranked by volume. The same agent can sit on both, and the numbers
are never pooled, because 'paid us $1' and 'asked 5,000 times for free' are
not the same fact. No commission rate anywhere, since nobody earns here.
/leaderboard is in openPaths with and without the trailing slash: the gateway
prefix-matches only entries ending in a slash, so the bare path would open the
index and still charge for every board on it.
Verified against a throwaway Postgres: all 34 migrations apply, a duplicate
ref books once, five refusals make one row of five, a live 402 from ClaudeBot
increments crawl_demand, and GPTBot reads the board at 200 while / stays 402.
A DATE column bound as a JS Date 500s the whole board, so the day is sent as
a day.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0144uEVbZK3jdaQkwcLYTXPE
* Return the sale promise, so the write lands before the receipt
The gateway awaits onSale before sending the buyer's receipt (its JSDoc said
otherwise; profullstack/x402-gateway#5 fixes the comment and tests the
behaviour). Dropping the promise made the write fire and forget, which is
fine while a long-lived server keeps running and silently loses the sale
anywhere the runtime can stop once the response is sent.
Returning it makes the sale land first. A rejection is still swallowed by the
gateway, so a database failure never costs a buyer the pass it paid for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0144uEVbZK3jdaQkwcLYTXPE
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments