Skip to content

refactor(request): drop the workarounds machine-fetch 0.3.2 now covers - #293

Merged
brendanjryan merged 4 commits into
brendan/machine-fetch-integrationfrom
brendan/drop-machine-fetch-workarounds
Oct 21, 2026
Merged

brendanjryan merged 4 commits into
brendan/machine-fetch-integrationfrom
brendan/drop-machine-fetch-workarounds

Conversation

@brendanjryan

Copy link
Copy Markdown
Contributor

Stacked on #290 (base brendan/machine-fetch-integration). Retarget to main once #290 merges.

machine-fetch 0.3.2 ships the cross-chain fixes this integration first made in the CLI (tempoxyz/machine-fetch#88–#92). This PR removes the CLI's copies. Each one went only after a test showed machine-fetch covers the same case. One commit per workaround, so each rebases on its own if #290 changes.

Removed

Workaround Now covered by Shown by
crossChainDeadlineSeconds = 300 and the deadlineSeconds override in src/request/evm-charge.ts tempoxyz/machine-fetch#88: a cross-chain funder defaults to 300 s when policy sets no deadline test/cross-chain-deadline.test.ts runs a payment through machine-fetch with no policy deadline and checks the bridge's quote gets 300 s. The --dry-run preview now uses the funder's own defaultDeadlineSeconds.
confirmedDelivery, DeliveryFloor, destinationBalanceAt, the target/floor plumbing through fundingRoutes/crossChainFunders, and the DeliveredStatus alias tempoxyz/machine-fetch#89 (polls the destination balance until the deadline, retrying failed reads) and tempoxyz/machine-fetch#90 (recover confirms a spent delivery from destinationTxs) test/cross-chain-delivery.test.ts runs each case the wrapper handled through machine-fetch with the CLI's readers. Base read lag: in the lagging-RPC e2e test (test/e2e/lagging-rpc.ts), logging each balance read showed 0, 0, 0, 100000 after the bridge reported completion. machine-fetch's polling alone covers it, so the block-floor read is gone.
Recording the source block (blockNumber, fromBlock) in new Stargate quotes, and the OFTSent search for new operations tempoxyz/machine-fetch#91: saveReference The route signs its send, saves the signed transaction's hash, then broadcasts. The kill mid-bridge e2e test checks that the saved hash is the send's own.

Kept, and why

  • destinationDelivery (src/shared/chains.ts): it is now the funder's delivered reader and returns only the amount. machine-fetch needs a reader from the app because the CLI's Relay and Stargate routes are its own, so neither brings one.
  • The OFTSent search (findSent): it runs only for operations saved before this change, which have fromBlock and no validBefore in their quote data. The never-recorded-hash e2e test now rewrites a saved operation to that shape.
  • dexSwapSpend, canSpend, beforeSwap (src/wallet/access-key.ts, src/request/funding.ts, src/payment/tempo-funding.ts, src/commands/swap.ts): tempoxyz/machine-fetch#92's spendLimit applies only to machine-fetch's built-in auto-swap, which the CLI turns off (autoSwap: false). The CLI's own DEX funder and wallet swap still need the 2× budget and the tempo wallet keys update hint. Nothing here duplicates fix(request): strip credentials on cross-origin redirects #92, so nothing is removed.
  • Asking the route first in funding recover and in reconciliation before a new funding: machine-fetch's recover throws on refunded and pending operations instead of reporting them. So the CLI still reads route.status, and calls the funder's recover (new operationStatus) only to confirm a completion on chain. A completion not yet visible stays pending, as before.

Behavior to review

  • Stargate sends now expire. A send is signed with Tempo's validBefore set to the quote's expiry. A saved send with no receipt counts as refunded once Tempo's latest block is at least 60 s past validBefore; the margin covers an RPC whose receipts lag its head. machine-fetch's docs ask routes to handle a reference that was saved but never broadcast. The dropped reader (getBlock plus receipt-not-found) is covered through the route's unit tests. No e2e test makes the local chain drop a signed send.
  • funding recover waits longer. Confirming a completion now polls for up to 15 s (reconciliation: 10 s) before saying pending. Before, it read once.

Verification

machine-fetch 0.3.2 gives a cross-chain funder its own 300-second default deadline when policy
sets none (tempoxyz/machine-fetch#88), so the CLI no longer overrides `deadlineSeconds` for a
bridged payment. The dry-run preview quotes with the funder's own default.

A test runs a payment through machine-fetch with a policy that sets no deadline and checks the
bridge's quote gets 300 seconds.
machine-fetch 0.3.2 polls the destination balance until the deadline after a route completes
(tempoxyz/machine-fetch#89) and, in `recover`, confirms a delivery a payment already spent from
the route's `destinationTxs` (tempoxyz/machine-fetch#90). That covers what the CLI wrapped every
route in, so this drops:

- `confirmedDelivery`, which turned `completed` into `pending` until the delivery was visible.
- `DeliveryFloor` and `destinationBalanceAt`, which kept machine-fetch's single balance read off
  a lagging node by reading no earlier than the block that showed the delivery.
- The `target` plumbing, and the `DeliveredStatus` alias of `CrossChain.Status`.

The funders get the CLI's destination readers instead: `balance` reads the payer's USDC at
"latest", and `destinationDelivery`, now returning only the amount, is the `delivered` reader.
`funding recover` and the reconciliation before a new funding still ask the route first, so
refunded and pending operations read as before, then confirm a completion with the funder's
`recover`; one not yet visible stays pending.

Base's read lag (mainnet.base.org serves receipts before "latest" state) is still covered: in the
lagging-RPC e2e test, logging each read showed the first three balance reads after completion
returned 0 and the fourth the delivery, so machine-fetch's polling alone is enough. Unit tests run
each case the wrapper handled through machine-fetch with the CLI's readers.
machine-fetch 0.3.2 hands a route `saveReference` to save its reference before broadcasting
(tempoxyz/machine-fetch#91). The Stargate route now signs its send, saves the signed
transaction's hash, and only then broadcasts it, so a run killed in between still leaves the
hash for recovery. A save that fails stops the send, and a broadcast whose hash differs from the
one saved is rejected.

A saved send may never land, so the route signs it valid only until the quote expires (Tempo's
`validBefore`) and reports one with no receipt as refunded once Tempo is a minute past that.

New quotes no longer record the source block, so the `OFTSent` log search only runs for
operations saved before this, which recorded the hash after broadcasting. The e2e test for a
never-recorded hash now rewrites the saved operation to that earlier shape, and the kill
mid-bridge test checks that the hash saved is the send's own.
@brendanjryan
brendanjryan merged commit a96e327 into brendan/machine-fetch-integration Oct 21, 2026
16 of 22 checks passed
@brendanjryan

Copy link
Copy Markdown
Contributor Author

Folded into #290 (fast-forwarded onto its branch) so the wallet ships as one PR. The extra changelog entry was dropped, since the replaced copies never reached main.

@brendanjryan
brendanjryan deleted the brendan/drop-machine-fetch-workarounds branch October 21, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant