Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
539523f
Add HTTP API server infrastructure to node daemon
0xfornax Feb 25, 2026
c474e06
Migrate queue and service modules to HTTP API
0xfornax Feb 25, 2026
beccb6c
Migrate auction, network, and wallet modules to HTTP API
0xfornax Feb 25, 2026
2db029f
Migrate security and megapool modules to HTTP API
0xfornax Feb 25, 2026
0c53a73
Migrate minipool module to HTTP API
0xfornax Feb 25, 2026
8862903
Migrate odao and pdao modules to HTTP API
0xfornax Feb 25, 2026
6433ea0
Migrate node module to HTTP API
0xfornax Feb 25, 2026
e097fab
Remove old commands
0xfornax Feb 25, 2026
7145eaa
wip
0xfornax Feb 25, 2026
d5b09a1
fix lint
0xfornax Mar 6, 2026
b222ead
Adjust upgrade to use the web api
0xfornax Mar 19, 2026
fe0d0e5
Fix lint
0xfornax Mar 25, 2026
7063afd
Add blank line at the end of responses
0xfornax Mar 26, 2026
3663d13
Remove OpenAPIPort options. will always be opened just to localhost
0xfornax Mar 27, 2026
f3bb482
Fix flag types
0xfornax Mar 29, 2026
8c9b771
Fix set-use-latest
0xfornax Mar 29, 2026
d8ddebd
Pass gas settings to the api
0xfornax Mar 30, 2026
352bca4
Pass the nonce override on the request body
0xfornax Mar 30, 2026
d0d0f46
Remove timeout when waiting for tx to be included in a block
0xfornax Mar 30, 2026
c72e6cc
Remove the daemon-path flag
0xfornax Mar 31, 2026
c66b31f
use-latest-delegate as a cmd flag
0xfornax Mar 31, 2026
0a0a624
Add response errors
0xfornax Apr 1, 2026
cd85f7c
Revert "Remove the daemon-path flag"
0xfornax Apr 1, 2026
bd5ecc7
Add debug endpoint to fetch rewards events
0xfornax Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions bindings/rewards/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,150 @@ func getMainnetIntervalRewardsEvent(rp *rocketpool.RocketPool, index uint64) (Re
intervalEndTime = time.Unix(1746682539, 0)
submissionTime = time.Unix(1746691523, 0)
userETH.SetString("38934754761348367759", 10)
case 36:
treasuryRPL.SetString("22048941282103056576253", 10)
trustedNodeRPL.SetString("2004449207463914234114", 10)
nodeRPL.SetString("56124577808989598554500", 10)
executionBlock = big.NewInt(22636374)
consensusBlock = big.NewInt(11856479)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x704c7c2f6faeb97b20535a9a325e9ba573ec066ee579853b3e94b175114a8fd7")
intervalStartTime = time.Unix(1746682539, 0)
intervalEndTime = time.Unix(1749101739, 0)
submissionTime = time.Unix(1749113279, 0)
nodeETH.SetString("50039863506253385959", 10)
userETH.SetString("57244908435972245571", 10)
case 37:
treasuryRPL.SetString("22131620846710572152925", 10)
trustedNodeRPL.SetString("2011965531519142922898", 10)
nodeRPL.SetString("56335034882536001840574", 10)
nodeETH.SetString("45418705066756834715", 10)
executionBlock = big.NewInt(22836652)
consensusBlock = big.NewInt(12058079)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0xf4db744c50762a7ae1b19ee26120a582207eb1c535614711aae4cc5c598e42cf")
intervalStartTime = time.Unix(1749101739, 0)
intervalEndTime = time.Unix(1751520939, 0)
submissionTime = time.Unix(1751532611, 0)
userETH.SetString("48318015461156177248", 10)
case 38:
treasuryRPL.SetString("22214610444816577609208", 10)
trustedNodeRPL.SetString("2019510040437870691659", 10)
nodeRPL.SetString("56546281132260379365673", 10)
nodeETH.SetString("40700127824685134045", 10)
executionBlock = big.NewInt(23037044)
consensusBlock = big.NewInt(12259679)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0xf7809e999791fb6c73712c7d281624020ba773dc144fdfbb41c86b2e3cbb42fd")
intervalStartTime = time.Unix(1751520939, 0)
intervalEndTime = time.Unix(1753940139, 0)
submissionTime = time.Unix(1753948367, 0)
userETH.SetString("40528725716465757725", 10)
case 39:
treasuryRPL.SetString("22297911238990936999935", 10)
trustedNodeRPL.SetString("2027082839908266999911", 10)
nodeRPL.SetString("56758319517431475996754", 10)
nodeETH.SetString("34921409718655333629", 10)
executionBlock = big.NewInt(23237567)
consensusBlock = big.NewInt(12461279)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0xec51162c8af79d86e4b8f6546ec0e1ec3b4172b12574893e938c4f5bdd408efe")
intervalStartTime = time.Unix(1753940139, 0)
intervalEndTime = time.Unix(1756359339, 0)
submissionTime = time.Unix(1756395407, 0)
userETH.SetString("31594532680318853963", 10)
case 40:
// {"status":"success","error":"","found":true,"index":"40","executionBlock":"23438005","consensusBlock":"12662879","merkleRoot":"0x2ad908aa47f988d09dd9884c8026e6213262e231bab0d5051eedb2bef6aefe1e","intervalsPassed":"1","treasuryRPL":"22381524396162942297937","trustedNodeRPL":["2034684036014812936091"],"nodeRPL":["56971153008414762209929"],"nodeETH":["24246940457789627532"],"userETH":"13888515305764133572","intervalStartTime":1756359339,"intervalEndTime":1758778539,"submissionTime":1758785783}
treasuryRPL.SetString("22381524396162942297937", 10)
trustedNodeRPL.SetString("2034684036014812936091", 10)
nodeRPL.SetString("56971153008414762209929", 10)
nodeETH.SetString("24246940457789627532", 10)
executionBlock = big.NewInt(23438005)
consensusBlock = big.NewInt(12662879)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x2ad908aa47f988d09dd9884c8026e6213262e231bab0d5051eedb2bef6aefe1e")
intervalStartTime = time.Unix(1756359339, 0)
intervalEndTime = time.Unix(1758778539, 0)
submissionTime = time.Unix(1758785783, 0)
userETH.SetString("13888515305764133572", 10)
case 41:
treasuryRPL.SetString("22465451087637660464639", 10)
trustedNodeRPL.SetString("2042313735239787314880", 10)
nodeRPL.SetString("57184784586714044816063", 10)
nodeETH.SetString("43676270282606810107", 10)
executionBlock = big.NewInt(23638162)
consensusBlock = big.NewInt(12864479)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0xe8af8737484cfd3d3fd5106ef189333e92f9bbc2de0ac057f4c01c473b2ec958")
intervalStartTime = time.Unix(1758778539, 0)
intervalEndTime = time.Unix(1761197739, 0)
submissionTime = time.Unix(1761205211, 0)
userETH.SetString("47268078777290226308", 10)
case 42:
treasuryRPL.SetString("22549692489112341819332", 10)
trustedNodeRPL.SetString("2049972044464758347124", 10)
nodeRPL.SetString("57399217245013233718952", 10)
nodeETH.SetString("25631914712861974454", 10)
executionBlock = big.NewInt(23838215)
consensusBlock = big.NewInt(13066079)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x9f8c89596b48d377279bf703444a2e0cd5e98ac4cc0f5c490324c394c1ba3ce8")
intervalStartTime = time.Unix(1761197739, 0)
intervalEndTime = time.Unix(1763616939, 0)
submissionTime = time.Unix(1763642831, 0)
userETH.SetString("17561894202841328207", 10)
case 43:
treasuryRPL.SetString("22634249780692889936981", 10)
trustedNodeRPL.SetString("2057659070972080903284", 10)
nodeRPL.SetString("57614453987218265291225", 10)
nodeETH.SetString("18947687367286040081", 10)
executionBlock = big.NewInt(24037441)
consensusBlock = big.NewInt(13267679)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0xa98c94badfa30d41fcde8a3c5ccdadadbe441e43883919567b2d45682e476ca3")
intervalStartTime = time.Unix(1763616939, 0)
intervalEndTime = time.Unix(1766036139, 0)
submissionTime = time.Unix(1766046599, 0)
userETH.SetString("8352566574518930988", 10)
case 44:
treasuryRPL.SetString("22719124146910393305039", 10)
trustedNodeRPL.SetString("2065374922446399391296", 10)
nodeRPL.SetString("57830497828499182955594", 10)
nodeETH.SetString("15367476931278801422", 10)
executionBlock = big.NewInt(24238059)
consensusBlock = big.NewInt(13469279)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x72ed38107b2b6c1a0469800af741c04adf5563aebe5a0ae5d77fb9b2354c64a5")
intervalStartTime = time.Unix(1766036139, 0)
intervalEndTime = time.Unix(1768455339, 0)
submissionTime = time.Unix(1768461851, 0)
userETH.SetString("4223474559072201135", 10)
case 45:
treasuryRPL.SetString("22804316776737718971210", 10)
trustedNodeRPL.SetString("2073119706976156270036", 10)
nodeRPL.SetString("58047351795332375560374", 10)
nodeETH.SetString("28550894583322805236", 10)
executionBlock = big.NewInt(24438645)
consensusBlock = big.NewInt(13670879)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x97dc8f589c86c3650a96568ab05c08a9e160aec7eb405e35ec2e62c6e1af559c")
intervalStartTime = time.Unix(1768455339, 0)
intervalEndTime = time.Unix(1770874539, 0)
submissionTime = time.Unix(1770894827, 0)
userETH.SetString("22178758316567204991", 10)
case 46:
treasuryRPL.SetString("22889828863606168413868", 10)
trustedNodeRPL.SetString("2080893533055106219373", 10)
nodeRPL.SetString("58265018925542974141956", 10)
nodeETH.SetString("19997007660595265346", 10)
executionBlock = big.NewInt(24639334)
consensusBlock = big.NewInt(13872479)
intervalsPassed = big.NewInt(1)
merkleRoot = common.HexToHash("0x8cb45bcefd498b8788e6291c4dc086694c85b495fb60e9d5b047e7b921929d48")
intervalStartTime = time.Unix(1770874539, 0)
intervalEndTime = time.Unix(1773293739, 0)
submissionTime = time.Unix(1773299819, 0)
userETH.SetString("12369109587853762785", 10)
default:
return RewardsEvent{}, false, nil
}
Expand Down
3 changes: 3 additions & 0 deletions bindings/utils/eth/units.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ func EthToWei(eth float64) *big.Int {

// Convert wei to gigawei
func WeiToGwei(wei *big.Int) float64 {
if wei == nil {
return 0
}
var weiFloat big.Float
var gwei big.Float
weiFloat.SetInt(wei)
Expand Down
41 changes: 21 additions & 20 deletions bindings/utils/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package utils
import (
"context"
"errors"
"fmt"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -12,32 +11,30 @@ import (
"github.com/rocket-pool/smartnode/bindings/rocketpool"
)

// Wait for a transaction to get mined
func WaitForTransaction(client rocketpool.ExecutionClient, hash common.Hash) (*types.Receipt, error) {

// Wait for a transaction to get included, respecting the provided context for cancellation.
// The transaction lookup retries indefinitely (with 1-second pauses) until found or ctx is done.
func WaitForTransactionWithContext(ctx context.Context, client rocketpool.ExecutionClient, hash common.Hash) (*types.Receipt, error) {
var tx *types.Transaction
var err error

// Get the transaction from its hash, retrying for 30 sec if it wasn't found
for i := 0; i < 30; i++ {
if i == 29 {
return nil, fmt.Errorf("Transaction not found after 30 seconds.")
// Get the transaction from its hash, retrying until found or ctx is cancelled.
for {
var err error
tx, _, err = client.TransactionByHash(ctx, hash)
if err == nil {
break
}

tx, _, err = client.TransactionByHash(context.Background(), hash)
if err != nil {
if err.Error() == "not found" {
time.Sleep(1 * time.Second)
continue
}
if err.Error() != "not found" {
return nil, err
} else {
break
}
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(1 * time.Second):
}
}

// Wait for transaction to be mined
txReceipt, err := bind.WaitMined(context.Background(), client, tx)
txReceipt, err := bind.WaitMined(ctx, client, tx)
if err != nil {
return nil, err
}
Expand All @@ -47,6 +44,10 @@ func WaitForTransaction(client rocketpool.ExecutionClient, hash common.Hash) (*t
return txReceipt, errors.New("Transaction failed with status 0")
}

// Return
return txReceipt, nil
}

// Wait for a transaction to get mined
func WaitForTransaction(client rocketpool.ExecutionClient, hash common.Hash) (*types.Receipt, error) {
return WaitForTransactionWithContext(context.Background(), client, hash)
}
38 changes: 20 additions & 18 deletions rocketpool-cli/megapool/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
Name: "yes",
Usage: "Automatically confirm the action",
},
&cli.StringFlag{
&cli.Uint64Flag{
Name: "validator-id",
Usage: "The validator id to exit",
},
Expand Down Expand Up @@ -277,7 +277,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
Name: "yes",
Usage: "Automatically confirm the action",
},
&cli.StringFlag{
&cli.Uint64Flag{
Name: "validator-id",
Usage: "The validator id to exit",
},
Expand Down Expand Up @@ -318,7 +318,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
Name: "yes",
Usage: "Automatically confirm the action",
},
&cli.StringFlag{
&cli.Uint64Flag{
Name: "validator-id",
Usage: "The validator id for which the exit is being notified",
},
Expand Down Expand Up @@ -359,7 +359,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
Name: "yes",
Usage: "Automatically confirm the action",
},
&cli.StringFlag{
&cli.Uint64Flag{
Name: "validator-id",
Usage: "The validator id for which the final balance is being notified",
},
Expand Down Expand Up @@ -409,33 +409,35 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) {
return distribute(c.Bool("yes"))
},
},
// Add set-use-latest-delegate command
{
Name: "set-use-latest-delegate",
Aliases: []string{"l"},
Usage: "Set the megapool to always use the latest delegate",
UsageText: "rocketpool megapool set-use-latest-delegate use-latest-delegate",

UsageText: "rocketpool megapool set-use-latest-delegate",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "use-latest-delegate",
Usage: "Enable (true) or disable (false) automatic using the latest delegate; omit to be prompted based on the current setting",
},
&cli.BoolFlag{
Name: "yes",
Usage: "Automatically confirm the action",
},
},
Action: func(ctx context.Context, c *cli.Command) error {

// Validate args
if err := cliutils.ValidateArgCount(c, 1); err != nil {
if err := cliutils.ValidateArgCount(c, 0); err != nil {
return err
}

useLatest, err := cliutils.ValidateBool("use-latest-delegate", c.Args().Get(0))
if err != nil {
return err
var useLatest *bool
if c.IsSet("use-latest-delegate") {
val := c.Bool("use-latest-delegate")
useLatest = &val
}

return setUseLatestDelegateMegapool(useLatest, c.Bool("yes"))
},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "yes",
Usage: "Automatically confirm the action",
},
},
},
},
})
Expand Down
35 changes: 29 additions & 6 deletions rocketpool-cli/megapool/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/rocket-pool/smartnode/shared/utils/cli/prompt"
)

func setUseLatestDelegateMegapool(setting bool, yes bool) error {
func setUseLatestDelegateMegapool(setting *bool, yes bool) error {
// Get RP client
rp, err := rocketpool.NewClient().WithReady()
if err != nil {
Expand All @@ -29,26 +29,49 @@ func setUseLatestDelegateMegapool(setting bool, yes bool) error {
return nil
}

// If no flag was provided, prompt the user based on the current setting
if setting == nil {
currentSetting := status.Megapool.UseLatestDelegate
var desired bool
if currentSetting {
fmt.Println("Your megapool currently has automatic delegate upgrades enabled.")
if !prompt.Confirm("Would you like to disable automatic delegate upgrades?") {
fmt.Println("No changes made.")
return nil
}
desired = false
} else {
fmt.Println("Your megapool currently has automatic delegate upgrades disabled.")
if !prompt.Confirm("Would you like to enable automatic delegate upgrades?") {
fmt.Println("No changes made.")
return nil
}
desired = true
}
setting = &desired
}

megapoolAddress := status.Megapool.Address

// Print message we're updating the setting
if setting == true {
if *setting {
fmt.Printf("Updating the use-latest-delegate setting for megapool %s to enabled...\n", megapoolAddress.Hex())
} else {
fmt.Printf("Updating the use-latest-delegate setting for megapool %s to disabled...\n", megapoolAddress.Hex())
}

// Get the gas estimate
canResponse, err := rp.CanSetUseLatestDelegateMegapool(megapoolAddress, setting)
canResponse, err := rp.CanSetUseLatestDelegateMegapool(megapoolAddress, *setting)
if err != nil {
return fmt.Errorf("error checking if megapool %s could have its use-latest-delegate flag changed: %w", megapoolAddress.Hex(), err)
}
if canResponse.MatchesCurrentSetting == true {
if setting == true {
if canResponse.MatchesCurrentSetting {
if *setting {
fmt.Printf("Could not enable use-latest-delegate on the node's megapool, the setting is already enabled.")
} else {
fmt.Printf("Could not disable use-latest-delegate on the node's megapool, the setting is already disabled.")
}
fmt.Println()
return nil
}

Expand All @@ -65,7 +88,7 @@ func setUseLatestDelegateMegapool(setting bool, yes bool) error {
}

// Update flag
response, err := rp.SetUseLatestDelegateMegapool(megapoolAddress, setting)
response, err := rp.SetUseLatestDelegateMegapool(megapoolAddress, *setting)
if err != nil {
fmt.Printf("Could not set use latest delegate for megapool %s: %s. \n", megapoolAddress.Hex(), err)
return nil
Expand Down
1 change: 1 addition & 0 deletions rocketpool-cli/rocketpool-cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func main() {
}

if len(response.Alerts) > 0 {
fmt.Println()
color.YellowPrintln("=== Alerts ===")
for i, alert := range response.Alerts {
fmt.Println(alert.ColorString())
Expand Down
Loading
Loading