Umotu Explorer
Home/docs/builder

PBS-lite Builder Guide

This doc explains how to participate in Umotu’s PBS-lite market using services/builder-relay. Every bid is backed by on-chain escrow; the relay enforces commitments, signs receipts for proposers, and slashes non-delivering builders automatically.

Builder Relays

Umotu operates 4 independent builder relays across different regions. Each relay maintains separate state, so builders must register with each relay they want to use. You can register with one relay (closest to you) or all four for maximum reach.

RegionRelay URLLocation
Europehttps://builder-relay1.testnet.umotu.comEU
North Americahttps://builder-relay2.testnet.umotu.comUS
South Americahttps://builder-relay3.testnet.umotu.comSouth America
Asiahttps://builder-relay4.testnet.umotu.comAsia

Each relay is associated with a specific validator. Builders compete for block space on each validator independently. Registering with multiple relays increases your chances of winning blocks.

Quick Start

  1. Choose which relay(s) to use based on your geographic location or register with all four.
  2. Fund a builder wallet (EOA) and register it with BuilderEscrow.
  3. Register with each relay via POST /register to obtain relay tokens.
  4. Lock escrow for a target height, then submit bids to /bids on your chosen relay(s).
  5. Watch /assign responses; when you win, deliver the bundle + PaymentTx #1.
  6. Monitor /slash events to make sure failed competitors are penalized.
Sample builder env (.env)
RPC_URL=http://localhost:8080/rpc
ESCROW_ADDRESS=0xBuilderEscrow
BUILDER_ADDRESS=0xYourBuilder
BUILDER_PRIV_KEY=0xYourKey
# Choose one or use all four relays
BUILDER_RELAY_URL=https://builder-relay1.testnet.umotu.com
# BUILDER_RELAY_URL=https://builder-relay2.testnet.umotu.com
# BUILDER_RELAY_URL=https://builder-relay3.testnet.umotu.com
# BUILDER_RELAY_URL=https://builder-relay4.testnet.umotu.com
BUILDER_TOKEN=your-token-for-relay1
INTENT_SIGNATURE_KEY=0xOptionalKey

Note: If you want to submit bids to multiple relays, you'll need to manage separate tokens for each relay and send requests to each relay endpoint.

1. Register & Authenticate

Each builder needs a relay token for each relay they want to use. If self-registration is enabled (ENABLE_SELF_REGISTRATION=true), sign the message below and register with each relay separately.

BUILDER=0xYourBuilderAddress
NONCE=$(date +%s)
MESSAGE="UMOTU_RELAY_REGISTER:builder:${BUILDER}:${BUILDER}:${NONCE}"
SIG=$(cast wallet sign --private-key $BUILDER_PRIV_KEY "$MESSAGE")

# Register with relay 1 (EU)
curl -X POST https://builder-relay1.testnet.umotu.com/register \
  -H "Content-Type: application/json" \
  -d "{\"role\":\"builder\",\"address\":\"$BUILDER\",\"nonce\":\"$NONCE\",\"signature\":\"$SIG\"}"

# Register with relay 2 (US) - generate new nonce
NONCE=$(date +%s)
MESSAGE="UMOTU_RELAY_REGISTER:builder:${BUILDER}:${BUILDER}:${NONCE}"
SIG=$(cast wallet sign --private-key $BUILDER_PRIV_KEY "$MESSAGE")
curl -X POST https://builder-relay2.testnet.umotu.com/register \
  -H "Content-Type: application/json" \
  -d "{\"role\":\"builder\",\"address\":\"$BUILDER\",\"nonce\":\"$NONCE\",\"signature\":\"$SIG\"}"

# Repeat for relay 3 and 4 if desired...

Each relay returns { token }. Store each token securely and include the appropriate token as Authorization: Bearer <token>when making requests to that specific relay. Tokens are relay-specific and cannot be used across different relays.

2. Lock Escrow

Before submitting a bid, lock collateral on BuilderEscrow. Each lock is keyed by keccak256(builder, height, bundleCommitment).

# Example: lock Bid for height 12345 with 2.5 UMT payment and 10% escrow
cast send $ESCROW_ADDRESS "lockBid(uint64,bytes32,uint256,uint64)" \
  12345 \
  0xBUNDLE_COMMITMENT \
  2500000000000000000 \
  $(($(date +%s)+30)) \
  --value 250000000000000000
  • payAmount: total builder payment (wei) that the proposer receives.
  • expiresAt: UNIX seconds; keep it a bit ahead of the projected slot.
  • Escrow: send at least requiredEscrowAmount(builder, payAmount) (relay enforces this on submit).

3. Submit Bids

curl -X POST $BUILDER_RELAY_URL/bids \
  -H "Authorization: Bearer $BUILDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "builderId": "'$BUILDER'",
    "height": 12345,
    "bundleCommitment": "0xBUNDLE_COMMITMENT",
    "payAmount": "2500000000000000000",
    "expiresAt": 1712345678
  }'

Relay checks on-chain escrow, keeps only the top MAX_BIDS_PER_HEIGHT (default 64), and returns { ok: true, bidId }.

  • Use GET /intents to discover mandatory inclusion intents; incorporate them into your bundle.
  • Submit multiple bids (different bundles) per height if desired—just ensure each bid has a unique commitment.

4. Monitor & Assign

Proposers call GET /bids?height=N to see the top bids. When you win, they hit POST /assign and the relay returns a signed receipt.

# Proposer view (for reference)
curl -H "Authorization: Bearer $PROPOSER_TOKEN" "$BUILDER_RELAY_URL/bids?height=12345"

# Receipt lookup (builder or proposer token)
curl -H "Authorization: Bearer $BUILDER_TOKEN" "$BUILDER_RELAY_URL/receipts?bidId=<id>"

If you need to verify what you won, fetch the receipt and confirm the signature; Delivery must match the commitment exactly.

5. Deliver Winning Block

  1. Send the full bundle (matching bundleCommitment) to the proposer via your preferred channel.
  2. Broadcast PaymentTx #1 from the builder wallet with value = payAmount and metadata (height, builder, bundle) in calldata so the ABCI app can verify it.
  3. Include any required intents + top-fee transactions; phones will audit compliance using the receipt’s intentRoot.

If you fail to deliver before expiresAt, the relay (or proposer) will call /slash and you lose escrow proportional to the violation.

6. Slash & Disputes

curl -X POST $BUILDER_RELAY_URL/slash \
  -H "Authorization: Bearer $PROPOSER_OR_BUILDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "height": 12345,
    "builder": "0xBuilder",
    "bundleCommitment": "0xBUNDLE_COMMITMENT",
    "evidence": "0xdeadbeef"
  }'

The relay calls BuilderEscrow.slashOnBehalf. Provide any evidence (logs, receipts) as a hex blob. Successful slash pays the proposer + sentinel pool automatically.

REST API Reference

EndpointAuthDescription
POST /registerNone (signed message)Issue builder/proposer tokens.
POST /bidsBuilder tokenSubmit a sealed bid backed by escrow.
GET /bids?height=NProposer tokenList top bids for a height.
POST /assignProposer tokenAssign a bid, receive signed receipt.
GET /receipts?bidId=…Builder or proposer tokenFetch stored receipt.
POST /intentsSigned payloadPublish inclusion intents (no auth token).
GET /intentsPublicList active intents + Merkle root.
POST /slashProposer tokenSlash failed builders via escrow.
GET /healthzPublicRelay stats + liveness check.