github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/bsc/bscrpc.go (about)

     1  package bsc
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  
     7  	"github.com/ethereum/go-ethereum/ethclient"
     8  	"github.com/ethereum/go-ethereum/rpc"
     9  	"github.com/golang/glog"
    10  	"github.com/juju/errors"
    11  	"github.com/trezor/blockbook/bchain"
    12  	"github.com/trezor/blockbook/bchain/coins/eth"
    13  )
    14  
    15  const (
    16  	// MainNet is production network
    17  	MainNet eth.Network = 56
    18  
    19  	// bsc token type names
    20  	BEP20TokenType   bchain.TokenTypeName = "BEP20"
    21  	BEP721TokenType  bchain.TokenTypeName = "BEP721"
    22  	BEP1155TokenType bchain.TokenTypeName = "BEP1155"
    23  )
    24  
    25  // BNBSmartChainRPC is an interface to JSON-RPC bsc service.
    26  type BNBSmartChainRPC struct {
    27  	*eth.EthereumRPC
    28  }
    29  
    30  // NewBNBSmartChainRPC returns new BNBSmartChainRPC instance.
    31  func NewBNBSmartChainRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
    32  	c, err := eth.NewEthereumRPC(config, pushHandler)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	// overwrite EthereumTokenTypeMap with bsc specific token type names
    38  	bchain.EthereumTokenTypeMap = []bchain.TokenTypeName{BEP20TokenType, BEP721TokenType, BEP1155TokenType}
    39  
    40  	s := &BNBSmartChainRPC{
    41  		EthereumRPC: c.(*eth.EthereumRPC),
    42  	}
    43  
    44  	return s, nil
    45  }
    46  
    47  // Initialize bnb smart chain rpc interface
    48  func (b *BNBSmartChainRPC) Initialize() error {
    49  	b.OpenRPC = func(url string) (bchain.EVMRPCClient, bchain.EVMClient, error) {
    50  		r, err := rpc.Dial(url)
    51  		if err != nil {
    52  			return nil, nil, err
    53  		}
    54  		rc := &eth.EthereumRPCClient{Client: r}
    55  		ec := &eth.EthereumClient{Client: ethclient.NewClient(r)}
    56  		return rc, ec, nil
    57  	}
    58  
    59  	rc, ec, err := b.OpenRPC(b.ChainConfig.RPCURL)
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	// set chain specific
    65  	b.Client = ec
    66  	b.RPC = rc
    67  	b.MainNetChainID = MainNet
    68  	b.NewBlock = eth.NewEthereumNewBlock()
    69  	b.NewTx = eth.NewEthereumNewTx()
    70  
    71  	ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
    72  	defer cancel()
    73  
    74  	id, err := b.Client.NetworkID(ctx)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	// parameters for getInfo request
    80  	switch eth.Network(id.Uint64()) {
    81  	case MainNet:
    82  		b.Testnet = false
    83  		b.Network = "livenet"
    84  	default:
    85  		return errors.Errorf("Unknown network id %v", id)
    86  	}
    87  
    88  	glog.Info("rpc: block chain ", b.Network)
    89  
    90  	return nil
    91  }