Repository navigation
v0.7.1
Everything in this release is in notary/ and in CI. The lethe package is
unchanged from 0.7.0 — git diff v0.7.0..v0.7.1 -- lethe/ is empty — so there
is nothing to gain by upgrading lethe-delete itself. Upgrade if you run the
notary: as declared, it could not take a payment on a clean install.
Fixed
lethe-notarydeclaredx402>=2but the payment path needsx402[evm]
andx402[httpx]. A clean install started the service and could not take a
payment. Measured on a clean venv: barex402raisesImportErrorfrom
x402.mechanisms.evm.exact.register("EVM mechanism requires ethereum
packages"), andx402[evm]withouthttpxfails preflight with "No module
named 'httpx'". Invisible locally, whereeth_account,eth_utilsand
httpxall arrive transitively. Missingeth_utilsadditionally disabled
the EIP-55 checksum onLETHE_NOTARY_PAY_TOin silence — confirmed by
feeding it an address with one wrong character, which it accepted.lethe-notary[dev]declaredhttpx2, which is a real distribution that
ships a module namedhttpx2. Starlette'sTestClientimportshttpx. The
tests passed only becausehttpxarrived transitively; a clean install of the
extra could not importTestClientat all.notary/tools/pay.pyoverwrote the previous receipt. A fixed
receipt.jsonmeant buying a second certificate destroyed the first
receipt — the artifact the tool's own output calls "the evidence". Measured:
two purchases left one file. Receipts are now named after the certificate's
payload hash, and a differing receipt at that path is refused rather than
replaced. Re-running the same certificate rewrites an identical file, so the
idempotency check stays a two-command exercise.pay.pycrashed with a bareKeyErroron a 402 carrying no
PAYMENT-REQUIREDheader — a stripped header or a URL that is not a
notary. It now says which, and exits 2.PaymentGate.chargereturnedtuple[bool, object | None], and an
objectin the return position meant a type checker could see nothing about
its callers — including the three route handlers whose bodiesmypywas
therefore skipping entirely. It now returns either the response to send or
the settlement record, so the two outcomes are distinguishable by type.
Checking those bodies immediately surfaced six unnarrowed values in
/witness, whereall(isinstance(v, str) for v in ...)validates at runtime
but narrows nothing.
Added
notary/is now covered by CI:ruff,mypy, its own test run, and a
no-extras install job that imports the whole paid path and quotes a price.
It was checked by hand for three releases, which is another way of saying
nobody was checking. Dependabot now watchesnotary/pyproject.tomltoo.- The notary says whether it is charging real money.
network_kind()
classifies a CAIP-2 id astestnet,mainnetorunknown— never guessing,
because assuming either way is unsafe in a different direction. The startup
banner and/.well-known/notaryboth report it, so an operator one
environment variable away from mainnet, and an agent deciding whether to pay,
can both tell. notary/tools/pay.py— the buyer side of the x402 flow. It exists to be
run twice: the second run of the same certificate must report
charged: falseand settle nothing, which is the idempotency guarantee the
payment design rests on.- The skipped-test guard in CI now covers the notary's suite as well, and fails
on a missing report rather than passing over a run that never happened. - Two tests for the settlement reference the notary hands back — the payer's
only independent proof the money moved. v0.7.0 fixed the bug that discarded
it, but the fix was guarded only bylive-marked tests that CI never runs:
dropping the payment block from either the normal response or the
witness-write-failure response left the whole offline suite green.