feat: add Ultrasound MEV bundle sender - #220
Merged
Merged
Conversation
Adds BundleSenderTypeUltrasound (value 29), the three mainnet endpoints, the builder ID, and SetUltrasoundFields. Ultrasound accepts four of the five extra Bombora bundle fields; it does not document replacementSeqNumber. A separate setter keeps that key off the wire when a caller reuses one SendBundleV2Request across builders. replacementUuid needs no work, because SetUUID already writes that key. Co-Authored-By: Claude <noreply@anthropic.com>
vaigay
approved these changes
Aug 21, 2026
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.
Summary
BundleSenderTypeUltrasound, appended as enum value 29 so that no existing value is renumbered, plusEndpointUltrasoundEU/US/JPandBuilderUltrasoundID.Client. Ultrasound accepts a plaineth_sendBundle, so it needs no builder-specific client file.SetUltrasoundFields, gated on the sender type inSendBundleV2. It copies the four extra bundle fields that Ultrasound documents (droppingTxHashes,refundPercent,refundRecipient,refundTxHashes) and validates the same two limits as Bombora, reusingErrInvalidRefundPercentandErrInvalidLenRefundTxHashes.replacementSeqNumber, so a shared gate would put that key on the wire whenever a caller reuses oneSendBundleV2Requestacross builders.replacementUuidneeds no new code, becauseSetUUIDalready writes it under that key. The wire struct needs no new fields for the same reason.ReplacementSeqNumberstays Bombora only.Test plan
go build ./...passes.go test -race ./pkg/mev/...passes.golangci-lint run --config=.golangci.yml ./pkg/mev/...stays at the pre-existing baseline of 7 issues (1gosec, 6modernize), none in the new code..claude/MEV_Integration.md: the bundle carries the four documented keys and noreplacementSeqNumber, a refund percent of 100 fails, and two refund tx hashes fail.https://builder-rpc-eu.ultrasound.moneyto confirm that the builder accepts the payload. No live-endpoint check ran.Out of scope
ultrasound_getBundleTraceis not wired.getGetBundleStatsMethodreturnsflashbots_getBundleStatsV2for every sender type, and the trace response shape (indexedUpToBlock,data.status,builderPayment) does not fitGetBundleStatsResponse. Wiring it needs new response types.X-Api-Keyheader is not plumbed. It only raises the rate limit. Adding it needs a new client option plus a header change insendRawBundleand its sibling methods, which every builder shares.allowBuilderNetRefundsandbuilderNetRefundAddresscarry noomitempty, so every bundle sends them, Ultrasound included, even though Ultrasound documents neither key. This is pre-existing shared behaviour that also affects Bombora.CancelBundlealready sendseth_cancelBundlewithreplacementUuid, which matches the Ultrasound document. It is builder-agnostic and unchanged, and it is unverified against the live endpoint.Stack
feat/eth-mev-bombora) — merge it first.🤖 Generated with Claude Code