Sepolia to Miden Testnet E2E Evidence

Updated 2026-05-16 on main. Evidence captured 2026-05-15 against live Sepolia native ETH and public Miden testnet.

PASS: both Sepolia native ETH directions reached SUCCESS

This page focuses only on the live Sepolia run. It documents the mock NEAR Intents 1Click flow through /v0/tokens, /v0/quote, /v0/deposit/submit, and /v0/status, with Etherscan and Miden explorer links for the chain transactions that prove settlement.

Run Environment

Bridge API http://localhost:8080
EVM Network Sepolia, chain id 11155111
Miden Network Public testnet via https://rpc.testnet.miden.io
Runtime profile BRIDGE_PROFILE=sepolia, nearIntentsMock=true, demoEnabled=false, uiEnabled=true
Sepolia RPC https://gateway.tenderly.co/public/sepolia
Amount per flow 1000000000000 wei native Sepolia ETH
Solver EVM address 0x7a593c0c800c171E877238029C198FA3b7bF6c4c
Test user EVM address 0x5167777c02CFf68f65ed77058A92909b2d6C307c
Health checks /healthz = 200 ok, /readyz = 200 ready

End-to-End Flow

Component interaction model

flowchart TB
    subgraph UserSide["Builder / user side"]
      User["Builder app or user wallet"]
      Recipient["Recipient Miden wallet"]
    end

    subgraph BridgeRuntime["Mock 1Click Bridge service"]
      API["Bridge API: tokens, quote, submit, status"]
      Lifecycle["Lifecycle engine: status transitions and recovery"]
      Poller["Bridge poller: public note scanner"]
    end

    subgraph SolverAuthority["Solver authority in this mock"]
      MidenSolver["Miden solver account (also outbound bridge account)"]
      SepoliaSolver["Sepolia solver EOA"]
    end

    subgraph DurableState["Durable state"]
      Postgres["Postgres quote state and tx artifacts"]
    end

    subgraph SettlementNetworks["Settlement networks"]
      Sepolia["Sepolia native ETH"]
      Miden["Miden public testnet"]
    end

    User -->|"quote, submit deposit tx, poll status"| API
    API --> Postgres
    Postgres --> API
    API -->|"verify submitted deposit tx"| Sepolia
    API --> Lifecycle

    Lifecycle --> Postgres
    Postgres --> Lifecycle
    Lifecycle -->|"inbound payout request"| MidenSolver

    Poller -->|"scan public BridgeOutV1 notes"| Miden
    Poller --> Postgres
    Postgres --> Poller
    Poller -->|"validated outbound settlement"| MidenSolver

    MidenSolver -->|"public P2ID mint"| Miden
    MidenSolver -->|"consume BridgeOutV1 note"| Miden
    MidenSolver -->|"release instruction"| SepoliaSolver
    SepoliaSolver -->|"release ETH tx"| Sepolia

    User -->|"Sepolia deposit"| Sepolia
    User -->|"create BridgeOutV1 note"| Miden
    Recipient -->|"claim public P2ID note"| Miden

The solver is a separate role, not a separate process in this mock. The bridge container owns the solver authority: the deterministic Miden solver account, which also acts as the stable outbound bridge account, and the Sepolia solver EOA used to release ETH. A production deployment can split that role out, but the public 1Click API shape does not change.

Sepolia native ETH both directions

flowchart LR
    subgraph Inbound["Inbound: Sepolia to Miden"]
      I1["/v0/quote"] --> I2["User sends Sepolia ETH"]
      I2 --> I3["/v0/deposit/submit"]
      I3 --> I4["Bridge API verifies tx"]
      I4 --> I5["Solver role signs public P2ID mint"]
      I5 --> I6["Recipient claims on Miden"]
    end

    subgraph Outbound["Outbound: Miden to Sepolia"]
      O1["/v0/quote"] --> O2["User creates public BridgeOutV1 note"]
      O2 --> O3["Bridge poller validates note"]
      O3 --> O4["Solver/bridge Miden account consumes note"]
      O4 --> O5["Solver EOA releases Sepolia ETH"]
      O5 --> O6["/v0/status SUCCESS"]
    end
Inbound final status SUCCESS
Inbound lifecycle PENDING_DEPOSIT -> KNOWN_DEPOSIT_TX -> PENDING_DEPOSIT -> PROCESSING -> SUCCESS
Outbound final status SUCCESS
Outbound lifecycle PENDING_DEPOSIT -> KNOWN_DEPOSIT_TX -> PENDING_DEPOSIT -> PROCESSING -> SUCCESS

Inbound: Sepolia ETH To Miden Payout

The user asks the Bridge API for a Sepolia-to-Miden quote, sends native ETH to the returned Sepolia deposit address, then submits the deposit tx hash. The Bridge API verifies the Sepolia transaction and submits a solver-signed public P2ID mint on Miden testnet. The recipient then claims the public note.

1

Quote created

POST /v0/quote eth-sepolia:eth -> miden-testnet:eth

2

User sent Sepolia deposit

The funded test user sent 1000000000000 wei to the quote deposit address.

3

Bridge API accepted the submitted tx hash

POST /v0/deposit/submit moved the quote into the confirmed-deposit lifecycle.

4

Bridge API minted the Miden public P2ID note

The configured Miden solver account submitted the public payout note directly to the recipient account.

5

Recipient claimed the Miden payout

Bridge SUCCESS means the public P2ID note is committed and consumable. The recipient claim transaction consumed it and updated the wallet balance.

Outbound: Miden Public Note To Sepolia ETH

The outbound actor is the user's Miden source account, not the solver. The runner first funded that user account through the same Sepolia inbound path so it had spendable Miden assets for the live test. Then it requested a Miden-to-Sepolia quote, created a public programmable BridgeOutV1 note from the user account, let the bridge account consume that note on Miden, and verified the Sepolia release. In this mock, the bridge account returned in the quote is the same deterministic Miden account used by the solver role.

1

Test setup: user Miden source account funded from Sepolia

The user's Miden account needed spendable Miden funds before it could create the outbound public note.

2

Outbound quote created

POST /v0/quote miden-testnet:eth -> eth-sepolia:eth returned the stable bridge account and BridgeOutV1 memo.

3

User created the public BridgeOutV1 note

The note carried the Miden asset plus metadata that binds it to the outbound quote hash and bridge account.

4

Bridge consumed the Miden note

The bridge poller validated target account, quote hash, faucet, and amount before consuming the note with the stable bridge account.

5

Bridge released Sepolia ETH to the user

The test user Sepolia balance increased by exactly the quoted amount after the release transaction landed.

Sequence Diagrams

Inbound: Sepolia deposit to Miden claim

sequenceDiagram
    participant User
    participant BridgeAPI as Bridge API
    participant Postgres
    participant Sepolia
    participant Solver as Solver role
    participant Miden
    participant Recipient

    User->>BridgeAPI: POST /v0/quote eth-sepolia:eth to miden-testnet:eth
    BridgeAPI->>Postgres: Persist quote and deposit address
    BridgeAPI-->>User: Return Sepolia deposit address
    User->>Sepolia: Send native ETH deposit
    User->>BridgeAPI: POST /v0/deposit/submit with txHash
    BridgeAPI->>Sepolia: Verify tx pays quoted deposit address
    BridgeAPI->>Postgres: Record deposit tx and PROCESSING status
    BridgeAPI->>Solver: Request Miden payout settlement
    Solver->>Miden: Sign and submit public P2ID mint
    Miden-->>Solver: Mint tx committed
    Solver->>Postgres: Persist Miden mint tx id and SUCCESS
    User->>BridgeAPI: GET /v0/status
    BridgeAPI->>Postgres: Load final quote state
    BridgeAPI-->>User: /v0/status SUCCESS
    Recipient->>Miden: Consume public P2ID note
    Miden-->>Recipient: Wallet balance updated

Outbound: Miden public note to Sepolia release

sequenceDiagram
    participant User
    participant BridgeAPI as Bridge API
    participant Postgres
    participant Miden
    participant Poller as Bridge poller
    participant Solver as Solver role
    participant Sepolia

    User->>BridgeAPI: POST /v0/quote miden-testnet:eth to eth-sepolia:eth
    BridgeAPI->>Postgres: Persist quote, quote hash, recipient
    BridgeAPI-->>User: Return solver/bridge Miden account and BridgeOutV1 memo
    User->>Miden: Create public BridgeOutV1 note to bridge account
    Poller->>Miden: Sync and scan public notes
    Poller->>Postgres: Load quote and expected memo fields
    Poller->>Poller: Validate quote hash, target account, faucet, amount
    Poller->>Solver: Request note consumption and Sepolia release
    Solver->>Miden: Consume note with solver/bridge account
    Miden-->>Solver: Consume tx committed
    Solver->>Sepolia: Release native ETH to recipient
    Solver->>Postgres: Persist consume tx, release tx, and SUCCESS
    User->>BridgeAPI: GET /v0/status
    BridgeAPI-->>User: SUCCESS with release tx hash

Reproduce

Start the Sepolia profile with funded SOLVER_PRIVATE_KEY and DEMO_EVM_FUNDED_PRIVATE_KEY, then run the live evidence runner. The runner uses the mock 1Click /v0/* API and does not print private keys.

cp .env.sepolia.example .env
# Fill EVM_RPC_URL, SOLVER_PRIVATE_KEY, DEMO_EVM_FUNDED_PRIVATE_KEY, and MIDEN_MASTER_SEED_HEX.
make sepolia
RUSTFLAGS='-C debug-assertions=no' cargo run --bin sepolia_e2e 2>&1 | tee sepolia-e2e-live.log

Raw evidence lines

SEPOLIA_E2E_EVIDENCE inbound correlation_id=3e5ec16b-2fa2-4c0a-8ce7-0ae8725bbac1 evm_deposit_tx_hash=0xaca72ebac72cfbda3cd5957605b8e01f107c37acc9d2bfe118552b0c7cab311a miden_mint_tx_ids=["0x7a4c0ed23a0b13eb4f559ed2f9f82282b38b99dda2138a9b1e94759b3aefa0b6"] claim_tx_id=0x6bf05ee2a2d9f772823abe66cf2417995ecaa71fdbe731b247694ec0f66eccfb
SEPOLIA_E2E_EVIDENCE outbound funding_correlation_id=8b1920ef-ca3b-4fbc-82c5-35f6f8670332 outbound_correlation_id=ab2b3f5d-0d5e-4b86-a013-0f4ddcef05aa funding_evm_deposit_tx_hash=0x3c0e444fa726496ee09cda9c72d2d14d8a07235de81bdf8de94d0a559c899644 bridge_out_note_tx_id=0xe9db64f8a00db3527ebb1f5d443c09ce2ec80c639ccabd7e5b4b6195ea045f2d miden_consume_tx_ids=["0xbaa1789bb950b97bb8300aaebc53e817760f4791ce04b5d971b85f69e4577f81"] evm_release_tx_hashes=["0x23640d4ad68277a065fa6ec70cc26b6bc7d2acf181bf0b6669da1b03fa668885"] balance_delta_wei=1000000000000
Scope: Sepolia native ETH is validated end to end. ERC20 Sepolia assets still need token registry entries and separate live token-transfer evidence.