Add megapool exit & claim lifecycle UI (follow-up to #154) - #159
Conversation
b38de52 to
f6da607
Compare
|
Six weeks on, so a status ping — and a note that this one now needs a rebase.
No rush on my side, and no problem if the answer is "not now" or "not this way" — I'd just rather close it cleanly than leave it sitting open indefinitely. Let me know either way and I'll act on it. |
- UPSTREAM_VERSION / upstreamVersion v1.19.3 -> v1.20.3 (latest stable
Smartnode release, 2026-05-21); package version 0.1.8 -> 0.1.9.
- Fix auto_check.yml so future Smartnode releases auto-PR:
- push trigger watched 'master' but default branch is 'main'
- no permissions block -> read-only GITHUB_TOKEN could not open the
bump branch/PR (dappnodesdk bump-upstream needs write)
- bumped actions/checkout v2 -> v4; added workflow_dispatch
- Add the v1.20.x native-mode Smartnode HTTP API port default (8280) to the generated settings template without exposing it publicly.\n- Add Lodestar's QUIC P2P port default (8001), matching the existing Lighthouse/Prysm entries and upstream v1.20.3 config.\n- Add the explicit IPv6 default (disabled) and align root.version with the bundled Smartnode v1.20.3.
The settings template rendered network: ${NETWORK} (= hoodi), but the
Smartnode daemon only accepts mainnet|testnet|devnet. "testnet" is Hoodi
internally (chainId 560048, RocketStorage 0x594Fb75D...). With network: hoodi
the daemon cannot resolve the storage address and every on-chain call fails
with "The Rocket Pool storage contract was not found".
Introduce SMARTNODE_NETWORK (mainnet -> mainnet, hoodi/testnet -> testnet),
pass it through envsubst, and use it for the template's network: field. The
dappnode package keeps using NETWORK=hoodi for its own identity (web3signer-hoodi,
globals, urls); only the smartnode setting is remapped.
Verified live on Hoodi: with network: testnet, node register + 4-ETH megapool
deposit succeed and all megapool routes resolve.
Adds the full megapool exit + claim/withdraw actions on top of the deposit-only UI: API (build/api/src/index.ts): - megapool can-exit-queue / exit-queue (validatorIndex) - megapool can-exit-validator / exit-validator (validatorId) - megapool can-notify-validator-exit / notify-validator-exit (validatorId) - megapool pending-rewards, calculate-rewards, beacon-withdrawal-queue-estimate - megapool can-distribute / distribute - megapool can-claim-refund / claim-refund - executeCommand now waits on the txHash for exit-queue / notify-validator-exit / distribute / claim-refund (exit-validator is a beacon voluntary exit, no tx) UI: - AppService methods for each action (mirrors existing deposit/claim pattern) - New types: CanExit, CanDistribute, CanClaimRefund, MegapoolRewards - New MegapoolActions component (Exit + Claim sections, preflight->execute->wait, TxsLinksBox, MUI) rendered in MinipoolDetails All routes verified live against a v1.20.x daemon on Hoodi (external client mode). Both API and UI builds pass.
f6da607 to
aa589ca
Compare
|
Rebased onto current Same conflict resolution as #154: This PR still stacks on #154 — it adds the exit & claim lifecycle on top of the deposit UI, so #154 should land first. Re-verified after the rebase:
Ready for review. |
Megapool exit & claim lifecycle (follow-up to #154)
This adds the exit + claim/withdraw half of the megapool lifecycle, so node operators can manage validators after deposit — not just create them.
This branch is built on top of #154's deposit branch, so it shares those commits. The only new commit here is
b38de52("Add megapool exit & claim lifecycle to UI", +409 lines / 8 files). Everything else is #154. Intended sequencing: merge #154 first, then this. Kept separate on purpose so the deposit UI can land independently and operators get both options.The new commit only adds files/handlers — it does not modify the deposit logic.
What's added
🚪 Exit (state-aware — UI picks the right path per validator state):
exit-queue(byvalidatorIndex) — exit a validator still in the entry queue, before it stakesexit-validator(byvalidatorId) — beacon voluntary exit for an active validatornotify-validator-exit(byvalidatorId) — notify the protocol of the exit💰 Claim / withdraw:
pending-rewards— surfaces claimable node rewards in the UIdistribute— claim accrued megapool ETH/rewards to the nodeclaim-refund— claim the node's bond/refund backcalculate-rewards,beacon-withdrawal-queue-estimateHow it's wired (mirrors the existing deposit pattern)
build/api/src/index.ts): 13 newmegapool ...action handlers.executeCommandnow waits on thetxHashfor the 4 actions that broadcast a transaction (exit-queue,notify-validator-exit,distribute,claim-refund).exit-validatoris a beacon voluntary exit and returns no on-chain tx, so it is correctly not waited on.AppServicemethods + 4 new response types (CanExit,CanDistribute,CanClaimRefund,MegapoolRewards) + a newMegapoolActionscomponent (Exit + Claim sections, preflight → execute → wait,TxsLinksBox, MUI), rendered inMinipoolDetails.Validation — exercised live on Hoodi against a real deployed megapool
Built the v1.20.x daemon and ran it in external-client mode against public Hoodi endpoints. Registered a node and deposited a real 4-ETH megapool validator, then exercised every new route against the live megapool:
0x080fc2df40ec100e1a85a8626836b2b01f6a6209, validatorCount 1pending-rewards✅ success (clean reward split)can-distribute✅ success (megapoolNotDeployed: false)can-claim-refund✅ success (canClaim: true, real gas estimate ~42k)can-exit-validator✅ success (invalidStatus: true— validator not yet active on beacon, the correct state)Both API and UI builds pass (
tscclean; UI production build ~180 kB gzip; only a pre-existingMinipools.tsxeslint warning, untouched here).