Repository navigation
0.7.0 (5/7): payer balance, wallet --network, two serve modes - #8
Merged
Merged
Conversation
A payer that cannot fund the payment got its refusal reported as the target's: on Solana devnet X402-06 failed with "got 402 (invalid_exact_svm_transaction_simulation_failed)", a reason real defects give too, so it cannot be told apart afterwards. On Stellar the SDK client's own simulation stopped the build first, reported as a harness error with only the token's code (Error(Contract, #13)). X402-06 now reads the payer's balance of the advertised asset once the option to pay is known and before anything is signed. When the chain reports less than the price, X402-06 is ERROR (setup), naming the payer key to fund, nothing is signed or sent, and the negative checks are skipped. When the balance cannot be read, the run pays as before, so a failed read never becomes a verdict. Read before signing, so a target that settles and then refuses still shows as one. Each adapter reads it its own way: EVM through ERC-20 balanceOf; Solana as the sum of the payer's token accounts for the mint, never less than what the client can spend; Stellar by simulating the token's balance, and, since a Stellar Asset Contract reports a missing trustline as an error, by looking the trustline up when the token is that asset's SAC (recognised by its own contract id, the issuer excepted). Live, with fresh unfunded payers: ERROR (setup) on Stellar, Base Sepolia and Solana devnet; with the funded payers every x402 fixture passes 10/10. 227 core tests; 7 mutants killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Solana devnet CHECKS.md's X402-06 row and "The payment checks cannot pay" say that the payer's balance is read before signing, that a balance below the price gives ERROR (setup) with nothing sent, and that an unreadable one pays as before. The CHANGELOG records it as a change. The evidence: fresh unfunded payers on Stellar, Base Sepolia and Solana devnet get ERROR (setup) naming the key to fund, where Solana used to fail X402-06 and Stellar to stop on the token's bare error code; funded payers pass 10/10 on every fixture. It also records one Permit2 run that drew 402 without a reason and moved no funds, not reproduced in the five runs after it. The Solana devnet payer's USDC comes from faucet.circle.com, as the configuration guide, CHECKS.md and the Solana evidence now say. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
generatePayerKey() returns a new random key in the form the adapter's payerKeyEnv takes: a Stellar secret, an EVM private key, or the base58 of a Solana keypair's 64 bytes, the form wallets export. So a key handed out by `wasit wallet` is never one the payment checks would refuse at preflight; a test reads every generated key back through its adapter, and checks a Solana key's address against the one kit derives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…net payers `wasit wallet create --role x402` made Stellar keys only, so a builder paying on Base Sepolia or Solana devnet had to find another way to make the key the payment checks read. `--network eip155:84532` and `--network solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` now generate it, printing the EVM_PRIVATE_KEY or SVM_PRIVATE_KEY line and the address to fund at faucet.circle.com; that is the only step, since the payer needs no ETH or SOL. `status --network` shows the configured payer's USDC balance of the SDK's default asset and exits 2 when it could not be read; `fund --network` prints the faucet step. `--fund` stays Stellar only (Friendbot). `--network` takes the testnets `wasit serve` poses on, nothing else, and the MPP roles stay on Stellar. The serve network profiles gain a name, a faucet label and the native token, which the messages use. The dashboard's environment panel lists EVM_PRIVATE_KEY and SVM_PRIVATE_KEY. Stellar behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
X402-02's detail for a challenge in the v1 body form gave Stellar's `exact` scheme as the reason a header is required, and the payment checks' skip reason said Wasit pays through the exact scheme "on Stellar". Both predate the other chains: a v1 challenge from a Base Sepolia paywall was told about Stellar. They now say x402 v2 signals payment in PAYMENT-REQUIRED and that the payment checks pay through v2 only, keeping the Stellar fact as Stellar's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two modes about the challenge itself, for testing how an agent reads one. `v1-challenge` sends only the x402 v1 form: the PaymentRequirementsResponse in the 402 body, with v1's field names (maxAmountRequired, resource, description, mimeType) and the network's v1 name (base-sepolia, solana-devnet), and no PAYMENT-REQUIRED header, as a paywall on the old SDK does. It refuses Stellar, which v1 names no network for. `malformed-header` sends a PAYMENT-REQUIRED header that is base64 of the challenge's JSON cut short. Both answer a payment with 402 and log which header it came in and what that says about the agent. Wasit's read checks see exactly that: the v1 challenge is complete as v1 (X402-04 "All required v1 fields present") and fails X402-02 and X402-05; the malformed header fails X402-03. With the official x402 SDK client as the agent, it paid the v1 challenge as v1 in X-PAYMENT on Base Sepolia and Solana devnet, and refused the malformed one without paying. The evidence file also records `wasit wallet --network` as run. The tests that every challenge is a well-formed v2 one now cover the four modes it is true of. 75 CLI tests; 6 mutants killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 5 of 7 of 0.7.0, which is on npm since 2026-10-08. The PRs follow the release branch's commit order and are merged with merge commits, so every commit keeps its hash.
What changes
X402-06reads the payer's balance before signing: a payer below the price gets no verdict (ERROR (setup)) and nothing is sent.wasit wallet --networkfor the Base Sepolia and Solana devnet payers.wasit servemodesv1-challengeandmalformed-header.Commits
21f7bdcfeat(core): no verdict when the payer cannot cover the priceadc7781docs: the payer balance read before X402-06, and Circle's faucet for Solana devnet3b45048feat(core): each payment adapter generates its own payer keys4c3ca55feat(cli): wasit wallet --network for the Base Sepolia and Solana devnet payers3d9c11cfix(core): x402 v1 challenge messages no longer read as Stellar-onlyd82555afeat(cli): wasit serve v1-challenge and malformed-header modesVerification
Unit tests and the clean install run in CI. The payer-balance and wallet runs are in
docs/evidence/2026-10-05-payer-balance-check-run.mdand2026-10-05-wallet-network-and-serve-modes-run.md(folded into the per-date file in PR 7/7).🤖 Generated with Claude Code