-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from coinbase/solana-staking-example
This PR adds an abstraction around the SDK's signing support in order to support signing staking operations for ETH and SOL using the same interface. This PR relies heavily on Golang's stdlib `crypto/rand`. Alongside these changes, I included numerous Solana stake examples to provide full examples of how to stake SOL. Our current Solana staking endpoint can take significant periods of time to get data from the underlying Solana nodes, so I've added the ability to modify the timeout on the client.
- Loading branch information
Showing
22 changed files
with
1,253 additions
and
518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"os" | ||
"time" | ||
|
||
"github.com/coinbase/coinbase-sdk-go/pkg/coinbase" | ||
) | ||
|
||
/* | ||
* This example code list historical staking balances for any ETH validator or Shared ETH Staking wallet address. | ||
* For example: the addresses: | ||
* * Shared ETH Staking wallet address: 0xddb00798137e9e7cc89f1e9679e6ce6ea580b8f9 | ||
* * ETH Validator: 0xadbf3776d60b3f9dd30cb3257b50583898745deb40cb6cb842120753bf055f6c3863e0f5bdb5c403d9aa5a275ce165e8 | ||
* Run the code with 'go run examples/ethereum/list-staking-balances/main.go <api_key_file_path> <wallet_address>' | ||
*/ | ||
|
||
func main() { | ||
ctx := context.Background() | ||
|
||
client, err := coinbase.NewClient( | ||
coinbase.WithAPIKeyFromJSON(os.Args[1]), | ||
) | ||
if err != nil { | ||
log.Fatalf("error creating coinbase client: %v", err) | ||
} | ||
|
||
address := coinbase.NewExternalAddress( | ||
"ethereum-mainnet", | ||
os.Args[1], | ||
) | ||
|
||
balances, err := client.ListHistoricalStakingBalances( | ||
ctx, | ||
coinbase.Eth, | ||
address, | ||
time.Now().Add(-7*24*time.Hour), | ||
time.Now(), | ||
) | ||
if err != nil { | ||
log.Fatalf("error listing balances: %v", err) | ||
} | ||
|
||
for _, balance := range balances { | ||
println(balance) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"os" | ||
"time" | ||
|
||
api "github.com/coinbase/coinbase-sdk-go/gen/client" | ||
"github.com/coinbase/coinbase-sdk-go/pkg/coinbase" | ||
) | ||
|
||
/* | ||
* This example code list historical staking rewards for any ETH validator or Shared ETH Staking wallet address. | ||
* For example: the addresses: | ||
* * Shared ETH Staking wallet address: 0xddb00798137e9e7cc89f1e9679e6ce6ea580b8f9 | ||
* * ETH Validator: 0xa1d1ad0714035353258038e964ae9675dc0252ee22cea896825c01458e1807bfad2f9969338798548d9858a571f7425c | ||
* Run the code with 'go run examples/ethereum/list-staking-rewards/main.go <api_key_file_path> <wallet_address>' | ||
*/ | ||
|
||
func main() { | ||
ctx := context.Background() | ||
|
||
client, err := coinbase.NewClient( | ||
coinbase.WithAPIKeyFromJSON(os.Args[1]), | ||
) | ||
if err != nil { | ||
log.Fatalf("error creating coinbase client: %v", err) | ||
} | ||
|
||
address := coinbase.NewExternalAddress( | ||
"ethereum-mainnet", | ||
os.Args[1], | ||
) | ||
|
||
rewards, err := client.ListStakingRewards( | ||
ctx, | ||
coinbase.Eth, | ||
[]coinbase.Address{*address}, | ||
time.Now().Add(-7*24*time.Hour), | ||
time.Now(), | ||
api.STAKINGREWARDFORMAT_USD, | ||
) | ||
if err != nil { | ||
log.Fatalf("error listing rewards: %v", err) | ||
} | ||
|
||
for _, reward := range rewards { | ||
println(reward.ToJSON()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"math/big" | ||
"os" | ||
|
||
"github.com/coinbase/coinbase-sdk-go/pkg/coinbase" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/ethclient" | ||
) | ||
|
||
/* | ||
* This example code stakes ETH on the Holesky network via Shared ETH Staking. | ||
* Run the code with 'go run examples/ethereum/stake/main.go <api_key_file_path> <wallet_address> <wallet_private_key>' | ||
*/ | ||
|
||
func main() { | ||
ctx := context.Background() | ||
|
||
client, err := coinbase.NewClient( | ||
coinbase.WithAPIKeyFromJSON(os.Args[1]), | ||
) | ||
if err != nil { | ||
log.Fatalf("error creating coinbase client: %v", err) | ||
} | ||
|
||
address := coinbase.NewExternalAddress("ethereum-holesky", os.Args[2]) | ||
|
||
stakeableBalance, err := client.GetStakeableBalance(ctx, coinbase.Eth, address, coinbase.WithStakingBalanceMode(coinbase.StakingOperationModePartial)) | ||
if err != nil { | ||
log.Fatalf("error getting stakeable balance: %v", err) | ||
} | ||
|
||
log.Printf("stakeable balance: %s\n", stakeableBalance) | ||
|
||
stakeOperation, err := client.BuildStakeOperation( | ||
ctx, | ||
big.NewFloat(0.0001), | ||
coinbase.Eth, | ||
address, | ||
coinbase.WithStakingOperationMode(coinbase.StakingOperationModePartial), | ||
) | ||
if err != nil { | ||
log.Fatalf("error building staking operation: %v", err) | ||
} | ||
|
||
log.Printf("staking operation ID: %s\n", stakeOperation.ID()) | ||
|
||
key, err := crypto.HexToECDSA(os.Args[3]) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Sign the transactions within staking operation resource with your private key. | ||
err = stakeOperation.Sign(key) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// For Holesky, publicly available RPC URL's can be found here https://chainlist.org/chain/17000 | ||
ethClient, err := ethclient.Dial("<RPC_NODE_URL>") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Broadcast each of the signed transactions to the network. | ||
for _, transaction := range stakeOperation.Transactions() { | ||
rawTx := transaction.Raw() | ||
ethTx, ok := rawTx.(*types.Transaction) | ||
if !ok { | ||
log.Fatal("failed to cast transaction to Ethereum transaction") | ||
} | ||
|
||
if err := ethClient.SendTransaction(context.Background(), ethTx); err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
log.Printf("Broadcasted transaction hash: %s", ethTx.Hash().Hex()) | ||
} | ||
} |
Oops, something went wrong.