Skip to content

Commit 28146b0

Browse files
authored
feat: Support validator top ups (#63)
1 parent 4d4741b commit 28146b0

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Coinbase Go SDK Changelog
22

3+
## [0.0.27] - 2025-05-09
4+
5+
### Added
6+
7+
- Add support for validator top-ups.
8+
39
## [0.0.26] - 2025-05-06
410

511
### Added
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"math/big"
7+
"os"
8+
9+
"github.com/coinbase/coinbase-sdk-go/pkg/coinbase"
10+
"github.com/ethereum/go-ethereum/core/types"
11+
"github.com/ethereum/go-ethereum/crypto"
12+
"github.com/ethereum/go-ethereum/ethclient"
13+
)
14+
15+
/*
16+
* This example code tops up an existing validator on the Hoodi network with some ETH.
17+
* Run the code with 'go run examples/ethereum/dedicated-eth-top-up/main.go <api_key_file_path> <funding_wallet_address> <top-up-validator-pubkey> <private_key> <rpc_url>'
18+
*/
19+
20+
func main() {
21+
ctx := context.Background()
22+
23+
client, err := coinbase.NewClient(
24+
coinbase.WithAPIKeyFromJSON(os.Args[1]),
25+
)
26+
27+
if err != nil {
28+
log.Fatalf("error creating coinbase client: %v", err)
29+
}
30+
31+
address := coinbase.NewExternalAddress(coinbase.EthereumHoodi, os.Args[2])
32+
33+
options := []coinbase.StakingOperationOption{
34+
coinbase.WithNativeStakingOperationMode(),
35+
coinbase.WithTopUpValidatorPublicKey(os.Args[3]),
36+
}
37+
38+
topUpOperation, err := client.BuildStakeOperation(
39+
ctx,
40+
big.NewFloat(1), // Top Up 1 ETH
41+
coinbase.Eth,
42+
address,
43+
options...,
44+
)
45+
if err != nil {
46+
log.Fatalf("error building staking operation: %v", err)
47+
}
48+
49+
log.Printf("staking operation ID: %s\n", topUpOperation.ID())
50+
51+
if err := client.Wait(ctx, topUpOperation, coinbase.WithWaitTimeoutSeconds(600)); err != nil {
52+
log.Fatalf("error waiting for staking operation: %v", err)
53+
}
54+
55+
// Load your wallet's private key from which you initiated the above top up operation.
56+
key, err := crypto.HexToECDSA(os.Args[4])
57+
if err != nil {
58+
log.Fatal(err)
59+
}
60+
61+
log.Printf("Signing top up operation ...")
62+
63+
// Sign the transactions within staking operation resource with your private key.
64+
if err := topUpOperation.Sign(key); err != nil {
65+
log.Fatal(err)
66+
}
67+
68+
// For Hoodi, publicly available RPC URL's can be found here https://chainlist.org/chain/560048
69+
ethClient, err := ethclient.Dial(os.Args[5])
70+
if err != nil {
71+
log.Fatal(err)
72+
}
73+
74+
// Broadcast each of the signed transactions to the network.
75+
for index, transaction := range topUpOperation.Transactions() {
76+
log.Printf("Deposit tx %d: %s\n", index+1, transaction.UnsignedPayload())
77+
78+
rawTx, ok := transaction.Raw().(*types.Transaction)
79+
if !ok {
80+
log.Fatal("Failed to cast to *types.Transaction")
81+
}
82+
83+
if err := ethClient.SendTransaction(context.Background(), rawTx); err != nil {
84+
log.Fatal(err)
85+
}
86+
87+
log.Printf("Broadcasted transaction hash: %s", rawTx.Hash().Hex())
88+
}
89+
}

pkg/auth/transport.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
3636
"Correlation-Context",
3737
fmt.Sprintf(
3838
"%s,%s",
39-
fmt.Sprintf("%s=%s", "sdk_version", "0.0.26"),
39+
fmt.Sprintf("%s=%s", "sdk_version", "0.0.27"),
4040
fmt.Sprintf("%s=%s", "sdk_language", "go"),
4141
),
4242
)

pkg/coinbase/staking_operation.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ func WithTargetValidatorPublicKey(targetValidatorPublicKey string) StakingOperat
9595
return WithStakingOperationOption("target_validator_pubkey", targetValidatorPublicKey)
9696
}
9797

98+
// WithTopUpValidatorPublicKey allows for the setting of the top up validator public key.
99+
func WithTopUpValidatorPublicKey(validatorPublicKey string) StakingOperationOption {
100+
return WithStakingOperationOption("top_up_validator_pubkey", validatorPublicKey)
101+
}
102+
98103
type ConsensusLayerExitOptionBuilder struct {
99104
validatorPubKeys []string
100105
}

0 commit comments

Comments
 (0)