fix: x402 budget/allowlist/replay/session and wallet BTC fee, chain_status probe, Solana cluster (#43) - #44
Conversation
When deriving a Bitcoin address, the chain parameter was not being passed to the underlying derivation function, causing addresses to be generated from an incorrect derivation path. This change ensures the chain value is forwarded correctly to produce valid addresses for the intended chain. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the test assertion to match the corrected response format in the protocol implementation, ensuring the test validates the expected output after the recent protocol change. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the test in `crates/tinywallet-web3/src/crypto/chains/btc/test.rs` to use the correct expected address value, fixing a failing test that was caused by an outdated or incorrect assertion. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test for insufficient balance was asserting the wrong error variant, causing it to pass incorrectly when the ledger returned a different error. Updated the assertion to match the actual error returned by the implementation. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
When deriving a Bitcoin address, the chain parameter was not being passed through to the underlying derivation function, causing addresses to be generated from the wrong derivation path. This change ensures the chain value is correctly forwarded to produce the intended address type. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
When deriving a Bitcoin address, the chain parameter was not being passed to the derivation function, causing incorrect address generation for non-default chains. This change ensures the chain value is forwarded correctly to produce the expected address for the specified chain. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a reservation module that allows the ledger to hold funds temporarily during payment processing. This change adds the reservation data type, store integration, and ledger methods to create, confirm, and expire reservations, enabling safe concurrent balance operations without race conditions. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed a duplicate definition of the `SpendPlan` struct that appeared earlier in the file, keeping only the later identical definition to eliminate the redundancy. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The client now returns an error when the server response lacks the required x402 payment header, instead of silently proceeding with an empty or default value. This ensures the caller is explicitly notified of incomplete payment information, preventing silent failures in downstream payment processing. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test for overflow reporting used values close to u64::MAX that could themselves overflow when summed, masking the intended overflow check. Replaced them with values that sum to exactly u64::MAX so the overflow is triggered only by the addition of the fee. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduces a reservation mechanism that allows funds to be held before final settlement, preventing race conditions in concurrent transfers. The reservation holds a specified amount from a source account and expires after a configurable timeout, with automatic cleanup of expired reservations. This change also adds a new reservation type and updates the store and test modules to support the new functionality. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a balance query returns no rows, the previous code would panic trying to unwrap an empty result set. This change returns a zero balance instead, matching the expected behaviour for accounts that have never been used. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a session module with core types and logic for managing x402 payment sessions, along with supporting test utilities. This enables the wallet to track and verify payment states across requests, laying the groundwork for authenticated resource access. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test for rejecting non-chain-tip answers was split across two separate rig setups, each testing only one chain, which made the test harder to follow and left Solana's status unasserted. This change merges both scenarios into a single test body that checks all four chains in one pass, adds an explicit assertion that Solana remains Ready, and reformats the long tuple literals for consistency with the surrounding code style. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a request lacks the x402 header, the validation logic now returns a clear error instead of panicking. This ensures the system gracefully rejects requests without the required payment header, improving robustness and user feedback. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
…he active session Co-authored-by: Medulla <medulla@tinyhumans.ai>
The probe query now returns an error when the account does not exist, instead of silently returning a default or empty result. This ensures that callers can distinguish between a missing account and a valid zero-balance account, preventing silent failures in downstream logic. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test for parsing the x402 payment header was using an incorrect expected value, causing the test to fail despite the implementation being correct. The assertion now matches the actual header format returned by the protocol. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a dedicated error type for the x402 protocol to improve error reporting and add a corresponding test to verify the error handling logic. This change ensures that protocol failures are clearly communicated and tested. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Clean up unused imports in the BTC, Solana, Tron, and default catalog modules, as well as in the broadcast and wallet engine files, to reduce compilation warnings and improve code clarity. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
When restoring a wallet from a mnemonic, the engine now initialises the wallet state if it was not previously persisted. This prevents a panic that occurred when attempting to access the state after a fresh restore. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated test assertions in the Solana and defaults test files to reflect changes in the underlying implementation. The tests now verify the corrected behavior for key derivation and address generation, ensuring they match the updated cryptographic logic. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
…es/tinywallet-x402/src/wire/tes Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
…og.rs,crates/tinywallet-web3/sr Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
…et-x402/src/protocol/test.rs,cr Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
… paying Co-authored-by: Medulla <medulla@tinyhumans.ai>
…et-x402/src/lib.rs,crates/tinyw Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The thread module and its test file were removed as they are no longer used in the codebase, simplifying the crate structure and reducing maintenance overhead. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added a comprehensive README for the tinywallet-x402 crate, documenting its purpose, installation, configuration options, and basic usage examples to help developers integrate the wallet functionality. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reordered the `ThreadScope` import in the tools test module to follow the project's convention of grouping external dependencies before internal ones. Simplified the assertion in the ledger test by removing unnecessary line breaks, making the code more concise without changing its behavior. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Changed the test helper to pass a method reference instead of a closure when calling `ledger::with_ledger`, which is more idiomatic and avoids an unnecessary closure allocation. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (37)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8aa9a98ac7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /// vbytes one P2WPKH output adds. | ||
| const P2WPKH_OUTPUT_VBYTES: u64 = 31; |
There was a problem hiding this comment.
Size fees for the recipient's actual output type
execute_btc_quote accepts any valid mainnet recipient through validate_btc_address, including P2TR/P2WSH addresses, but every output is priced as a 31-vbyte P2WPKH output here. Those output scripts require 43 vbytes, so such transfers receive an absolute fee below the configured 20 sat/vB rate and can be rejected or delayed when the mempool minimum is near that target. Determine the destination output size from its address type, or conservatively price the largest supported output.
Useful? React with 👍 / 👎.
| WalletChain::Solana => self | ||
| .rpc_call::<Value>(WalletChain::Solana, "getHealth", json!([])) | ||
| .await | ||
| .map(drop), |
There was a problem hiding this comment.
Validate Solana's getHealth result
When a Solana endpoint returns any successful JSON value—such as null, an object, or a stubbed response—this branch drops the value and reports the provider as Ready. Unlike the other probes, it therefore does not enforce the documented requirement that the reply look valid; Solana getHealth should return the string "ok", so other values need to produce the row's Missing status and error.
Useful? React with 👍 / 👎.
Tiny Sweeper review
|
Summary
Fixes all seven findings tracked in #43. They are behaviors that #42 moved over from OpenHuman unchanged. Each fix was written test-first, and the new test failed before the fix went in.
x402 (
tinywallet-x402)PaymentLedger::reservechecks the caps and holds the amount in one critical section. TheReservationreleases the hold when dropped, andcommit(record)records the payment and releases the hold under one lock. Holds count toward the caps and are not persisted.parallel_payments_cannot_overspend_the_daily_caplet 12 of 3 payments through before the fix. It now lets exactly 3 through.wire::{SUPPORTED_USDC, check_usdc}lists five networks and their USDC.protocol/select.rsskips options it cannot pay, so a server that also offers a supported option still gets paid. When no option is payable, the result isX402Error::{UnsupportedNetwork, UnsupportedAsset}, and nothing is reserved or signed.X402Error::NonReplayableBodybefore anything is signed. Streaming bodies sent to endpoints that don't charge still work.PaymentRecord.session_idis always the ledger's own session, sosession_totalcounts tool payments.thread_id: Option<String>records per-thread attribution. It usesserde(default)and is omitted whenNone, so old ledger lines still load.thread::ThreadScopeseam (X402RequestTool::with_thread_scope, defaultNoThread).Wallet (
tinywallet-web3)plan_spendadds inputs one at a time and re-prices after each, using 11 + 68·inputs + 31·outputs vB. Change of 546 sats or less, the signer's own dust threshold, is folded into the fee.chain_statusprobing.execution/probe.rschecks one live value per chain: EVMeth_blockNumber, SolanagetHealth, BTCblocks/tip/height, and Tronwallet/getnowblock.Missingwith anerror.ChainStatus.erroris additive and omitted when empty.explorer_tx_urltakes the cluster, so devnet links carry?cluster=devnet.network_defaultslabels the networksolana-devnet.explorerTxUrlSuffixis additive and appears on devnet only.API changes
X402PaymentResultgains areservationfield and is no longerClone/Eq.PaymentRecordgainsthread_id.explorer_tx_urlgains aclusterargument.ThreadScope.The wire contract and
CONTRACT_VERSIONare unchanged. This needs a minor release.Verification
cargo fmt --all --check, andcargo +1.98 clippy --workspace --all-targets --all-features -D warnings, are clean.cargo test --workspace --all-featurespasses 702 tests with 0 failures.cargo doc --workspace --all-featurespasses with-D warnings.OpenHuman host side, from the branch that consumes this:
cargo check -p openhuman --features web3passes.web3::lib tests pass.http_requestx402 tests pass.Closes #43
Summary by CodeRabbit