From 9feab9d470278e4eecffa059b476dbf3c9417d8d Mon Sep 17 00:00:00 2001
From: Aaron Buchwald <aaron.buchwald56@gmail.com>
Date: Fri, 20 Nov 2020 09:58:28 -0500
Subject: Cleanup client, mod file, and client example

---
 examples/client/main.go | 220 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 220 insertions(+)
 create mode 100644 examples/client/main.go

(limited to 'examples')

diff --git a/examples/client/main.go b/examples/client/main.go
new file mode 100644
index 0000000..5f61e6a
--- /dev/null
+++ b/examples/client/main.go
@@ -0,0 +1,220 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"math/big"
+
+	"github.com/ava-labs/avalanchego/utils/crypto"
+	"github.com/ava-labs/avalanchego/utils/formatting"
+	"github.com/ava-labs/coreth/ethclient"
+	"github.com/ava-labs/coreth/plugin/evm"
+
+	"github.com/ava-labs/coreth"
+	"github.com/ava-labs/coreth/core/types"
+	"github.com/ethereum/go-ethereum/common"
+)
+
+var (
+	key                = "ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN"
+	prefixedPrivateKey = fmt.Sprintf("PrivateKey-%s", key)
+	ipAddr             = "127.0.0.1"
+	port               = 9650
+)
+
+type ethWSAPITestExecutor struct {
+	uri            string
+	requestTimeout time.Duration
+}
+
+// ExecuteTest ...
+func (e *ethWSAPITestExecutor) ExecuteTest() error {
+	client, err := ethclient.Dial(e.uri)
+	if err != nil {
+		return fmt.Errorf("Failed to create ethclient: %w", err)
+	}
+	fmt.Printf("Created ethclient\n")
+
+	ctx := context.Background()
+
+	cb58 := formatting.CB58{}
+	factory := crypto.FactorySECP256K1R{}
+	_ = cb58.FromString(key)
+	pk, _ := factory.ToPrivateKey(cb58.Bytes)
+	secpKey := pk.(*crypto.PrivateKeySECP256K1R)
+	ethAddr := evm.GetEthAddress(secpKey)
+
+	if err := testSubscription(ctx, client); err != nil {
+		return fmt.Errorf("Subscription Test failed: %w", err)
+	}
+
+	if err := testHeaderAndBlockCalls(ctx, client, ethAddr); err != nil {
+		return fmt.Errorf("HeaderAndBlockCalls Test failed: %w", err)
+	}
+
+	return nil
+}
+
+type ethRPCAPITestExecutor struct {
+	uri            string
+	requestTimeout time.Duration
+}
+
+// ExecuteTest ...
+func (e *ethRPCAPITestExecutor) ExecuteTest() error {
+	client, err := ethclient.Dial(e.uri)
+	if err != nil {
+		return fmt.Errorf("Failed to create ethclient: %w", err)
+	}
+	fmt.Printf("Created ethclient\n")
+
+	ctx := context.Background()
+
+	cb58 := formatting.CB58{}
+	factory := crypto.FactorySECP256K1R{}
+	_ = cb58.FromString(key)
+	pk, _ := factory.ToPrivateKey(cb58.Bytes)
+	secpKey := pk.(*crypto.PrivateKeySECP256K1R)
+	ethAddr := evm.GetEthAddress(secpKey)
+
+	if err := testHeaderAndBlockCalls(ctx, client, ethAddr); err != nil {
+		return fmt.Errorf("HeaderAndBlockCalls Test failed: %w", err)
+	}
+
+	return nil
+}
+
+func testSubscription(ctx context.Context, client *ethclient.Client) error {
+	headerChan := make(chan *types.Header)
+	subscription, err := client.SubscribeNewHead(ctx, headerChan)
+	if err != nil {
+		return fmt.Errorf("Failed to create subscription: %s", err)
+	}
+	fmt.Printf("Created subscription: %s\n", subscription)
+
+	suggestedGasPrice, err := client.SuggestGasPrice(ctx)
+	if err != nil {
+		return fmt.Errorf("Failed to get suggested gas price: %s", err)
+	}
+	fmt.Printf("Suggested gas price: %d\n", suggestedGasPrice.Uint64())
+
+	logChan := make(chan types.Log)
+	query := coreth.FilterQuery{
+		BlockHash: nil,
+		FromBlock: nil,
+		ToBlock:   nil,
+		Addresses: []common.Address{},
+		Topics:    [][]common.Hash{},
+	}
+	subscription, err = client.SubscribeFilterLogs(ctx, query, logChan)
+	if err != nil {
+		return fmt.Errorf("Failed to create subscription: %s", err)
+	}
+	fmt.Printf("Created subscription: %s\n", subscription)
+
+	return nil
+}
+
+func testHeaderAndBlockCalls(ctx context.Context, client *ethclient.Client, ethAddr common.Address) error {
+	// Test Header and Block ByNumber work for special cases
+	for i := 0; i > -3; i-- {
+		if err := checkHeaderAndBlocks(ctx, client, i, ethAddr); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func checkHeaderAndBlocks(ctx context.Context, client *ethclient.Client, i int, ethAddr common.Address) error {
+	fmt.Printf("Checking HeaderAndBlocks for i = %d\n", i)
+
+	header1, err := client.HeaderByNumber(ctx, big.NewInt(int64(i)))
+	if err != nil {
+		return fmt.Errorf("Failed to retrieve HeaderByNumber: %w", err)
+	}
+	fmt.Printf("HeaderByNumber (Block Number: %d, Block Hash: %s)\n", header1.Number, header1.Hash().Hex())
+
+	originalHash := header1.Hash()
+	originalBlockNumber := header1.Number
+	if i >= 0 && int(originalBlockNumber.Int64()) != i {
+		return fmt.Errorf("Requested block number %d, but found block number %d", i, originalBlockNumber)
+	}
+
+	header2, err := client.HeaderByHash(ctx, header1.Hash())
+	if err != nil {
+		return fmt.Errorf("Failed to retrieve HeaderByHash: %w", err)
+	}
+	fmt.Printf("HeaderByNumber (Block Number: %d, Block Hash: %s)\n", header2.Number, header2.Hash().Hex())
+
+	if originalHash.Hex() != header2.Hash().Hex() {
+		return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header2.Hash().Hex())
+	}
+
+	if originalBlockNumber.Cmp(header2.Number) != 0 {
+		return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header2.Number)
+	}
+
+	block1, err := client.BlockByNumber(ctx, big.NewInt(int64(i)))
+	if err != nil {
+		return fmt.Errorf("Failed to retrieve BlockByNumber: %w", err)
+	}
+	header3 := block1.Header()
+	fmt.Printf("BlockByNumber (Block Number: %d, Block Hash: %s)\n", header3.Number, header3.Hash().Hex())
+
+	if originalHash.Hex() != header3.Hash().Hex() {
+		return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header3.Hash().Hex())
+	}
+
+	if originalBlockNumber.Cmp(header3.Number) != 0 {
+		return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header3.Number)
+	}
+
+	block2, err := client.BlockByHash(ctx, header1.Hash())
+	if err != nil {
+		return fmt.Errorf("Failed to retrieve BlockByHash: %w", err)
+	}
+	header4 := block2.Header()
+	fmt.Printf("BlockByHash (Block Number: %d, Block Hash: %s)\n", header4.Number, header4.Hash().Hex())
+	if originalHash.Hex() != header4.Hash().Hex() {
+		return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header4.Hash().Hex())
+	}
+
+	if originalBlockNumber.Cmp(header4.Number) != 0 {
+		return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header4.Number)
+	}
+
+	balance, err := client.BalanceAt(ctx, ethAddr, big.NewInt(int64(i)))
+	if err != nil {
+		return fmt.Errorf("Failed to get balance: %s", err)
+	}
+	fmt.Printf("Balance: %d for address: %s\n", balance, ethAddr.Hex())
+
+	return nil
+}
+
+func main() {
+	wsURI := fmt.Sprintf("ws://%s:%d/ext/bc/C/ws", ipAddr, port)
+	wsTest := &ethWSAPITestExecutor{
+		uri:            wsURI,
+		requestTimeout: 3 * time.Second,
+	}
+	if err := wsTest.ExecuteTest(); err != nil {
+		fmt.Printf("WebSocket Test failed due to %s\n", err)
+	} else {
+		fmt.Printf("WebSocket Test succeeded!\n")
+	}
+
+	rpcURI := fmt.Sprintf("http://%s:%d/ext/bc/C/rpc", ipAddr, port)
+	rpcTest := &ethRPCAPITestExecutor{
+		uri:            rpcURI,
+		requestTimeout: 3 * time.Second,
+	}
+	if err := rpcTest.ExecuteTest(); err != nil {
+		fmt.Printf("RPC Test failed due to %s\n", err)
+	} else {
+		fmt.Printf("RPC Test succeeded!\n")
+	}
+}
-- 
cgit v1.2.3-70-g09d2