dione/rpcclient/ethereum.go

71 lines
1.6 KiB
Go

package rpcclient
import (
"context"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)
type ethereumClient struct {
httpClient *ethclient.Client
wsClient *ethclient.Client
logger log.Logger
}
type EthereumClient interface {
Connect(context.Context, string) error
Balance(context.Context, common.Address) (*big.Int, error)
SubscribeOnSmartContractEvents(context.Context, string)
}
func (c *ethereumClient) Connect(ctx context.Context, url string, connectionType string) error {
client, err := ethclient.Dial(url)
if err != nil {
c.logger.Fatal(err)
}
if connectionType == "websocket" {
c.wsClient = client
} else {
c.httpClient = client
}
return nil
}
// Balance returns the balance of the given ethereum address.
func (c *ethereumClient) Balance(ctx context.Context, address common.Address) (*big.Int, error) {
value, err := c.httpClient.BalanceAt(ctx, address, nil)
if err != nil {
return nil, err
}
return value, nil
}
func (c *ethereumClient) SubscribeOnSmartContractEvents(ctx context.Context, address string) {
contractAddress := common.HexToAddress(address)
query := ethereum.FilterQuery{
Addresses: []common.Address{contractAddress},
}
logs := make(chan types.Log)
sub, err := c.wsClient.SubscribeFilterLogs(context.Background(), query, logs)
if err != nil {
c.logger.Fatal(err)
}
for {
select {
case err := <-sub.Err():
c.logger.Fatal(err)
case vLog := <-logs:
fmt.Println(vLog) // pointer to event log
}
}
}