github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/rpc/config.go (about)

     1  package rpc
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/ethereum/go-ethereum/rpc"
    10  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    11  	"github.com/fibonacci-chain/fbc/app/crypto/hd"
    12  	"github.com/fibonacci-chain/fbc/app/rpc/nacos"
    13  	"github.com/fibonacci-chain/fbc/app/rpc/pendingtx"
    14  	"github.com/fibonacci-chain/fbc/app/rpc/websockets"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/input"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/lcd"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys"
    19  	cmserver "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
    20  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    21  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    22  
    23  	"github.com/spf13/viper"
    24  )
    25  
    26  const (
    27  	flagUnlockKey             = "unlock-key"
    28  	FlagWebsocket             = "wsport"
    29  	FlagPersonalAPI           = "personal-api"
    30  	FlagDebugAPI              = "debug-api"
    31  	FlagRateLimitAPI          = "rpc.rate-limit-api"
    32  	FlagRateLimitCount        = "rpc.rate-limit-count"
    33  	FlagRateLimitBurst        = "rpc.rate-limit-burst"
    34  	FlagDisableAPI            = "rpc.disable-api"
    35  	FlagKafkaAddr             = "pendingtx.kafka-addr"
    36  	FlagKafkaTopic            = "pendingtx.kafka-topic"
    37  	FlagNacosTmrpcUrls        = "rpc.tmrpc_nacos_urls"
    38  	FlagNacosTmrpcNamespaceID = "rpc.tmrpc_nacos_namespace_id"
    39  	FlagNacosTmrpcAppName     = "rpc.tmrpc_application_name"
    40  	FlagRpcExternalAddr       = "rpc.external_laddr"
    41  	FlagRestApplicationName   = "rest.application_name"
    42  	FlagRestNacosUrls         = "rest.nacos_urls"
    43  	FlagRestNacosNamespaceId  = "rest.nacos_namespace_id"
    44  	FlagExternalListenAddr    = "rest.external_laddr"
    45  )
    46  
    47  // RegisterRoutes creates a new server and registers the `/rpc` endpoint.
    48  // Rpc calls are enabled based on their associated module (eg. "eth").
    49  func RegisterRoutes(rs *lcd.RestServer) {
    50  	// register nacos first
    51  	registerNacos(rs.Logger())
    52  
    53  	server := rpc.NewServer()
    54  	accountName := viper.GetString(cmserver.FlagUlockKey)
    55  	accountNames := strings.Split(accountName, ",")
    56  
    57  	var privkeys []ethsecp256k1.PrivKey
    58  	if len(accountName) > 0 {
    59  		var err error
    60  		inBuf := bufio.NewReader(os.Stdin)
    61  
    62  		keyringBackend := viper.GetString(flags.FlagKeyringBackend)
    63  		passphrase := ""
    64  		switch keyringBackend {
    65  		case keys.BackendOS:
    66  			break
    67  		case keys.BackendFile:
    68  			passphrase, err = input.GetPassword(
    69  				"Enter password to unlock key for RPC API: ",
    70  				inBuf)
    71  			if err != nil {
    72  				panic(err)
    73  			}
    74  		}
    75  
    76  		privkeys, err = unlockKeyFromNameAndPassphrase(accountNames, passphrase)
    77  		if err != nil {
    78  			panic(err)
    79  		}
    80  	}
    81  
    82  	apis := GetAPIs(rs.CliCtx, rs.Logger(), privkeys...)
    83  
    84  	// Register all the APIs exposed by the namespace services
    85  	// TODO: handle allowlist and private APIs
    86  	for _, api := range apis {
    87  		if err := server.RegisterName(api.Namespace, api.Service); err != nil {
    88  			panic(err)
    89  		}
    90  	}
    91  
    92  	// Web3 RPC API route
    93  	rs.Mux.HandleFunc("/", server.ServeHTTP).Methods("POST", "OPTIONS")
    94  
    95  	// start websockets server
    96  	websocketAddr := viper.GetString(FlagWebsocket)
    97  	ws := websockets.NewServer(rs.CliCtx, rs.Logger(), websocketAddr)
    98  	ws.Start()
    99  
   100  	// pending tx watcher
   101  	kafkaAddrs := viper.GetString(FlagKafkaAddr)
   102  	kafkaTopic := viper.GetString(FlagKafkaTopic)
   103  	if kafkaAddrs != "" && kafkaTopic != "" {
   104  		kafkaClient := pendingtx.NewKafkaClient(strings.Split(kafkaAddrs, ","), kafkaTopic)
   105  		ptw := pendingtx.NewWatcher(rs.CliCtx, rs.Logger(), kafkaClient)
   106  		ptw.Start()
   107  	}
   108  }
   109  
   110  func unlockKeyFromNameAndPassphrase(accountNames []string, passphrase string) ([]ethsecp256k1.PrivKey, error) {
   111  	keybase, err := keys.NewKeyring(
   112  		sdk.KeyringServiceName(),
   113  		viper.GetString(flags.FlagKeyringBackend),
   114  		viper.GetString(cmserver.FlagUlockKeyHome),
   115  		os.Stdin,
   116  		hd.EthSecp256k1Options()...,
   117  	)
   118  	if err != nil {
   119  		return []ethsecp256k1.PrivKey{}, err
   120  	}
   121  
   122  	// try the for loop with array []string accountNames
   123  	// run through the bottom code inside the for loop
   124  
   125  	keys := make([]ethsecp256k1.PrivKey, len(accountNames))
   126  	for i, acc := range accountNames {
   127  		// With keyring keybase, password is not required as it is pulled from the OS prompt
   128  		privKey, err := keybase.ExportPrivateKeyObject(acc, passphrase)
   129  		if err != nil {
   130  			return []ethsecp256k1.PrivKey{}, err
   131  		}
   132  
   133  		var ok bool
   134  		keys[i], ok = privKey.(ethsecp256k1.PrivKey)
   135  		if !ok {
   136  			panic(fmt.Sprintf("invalid private key type %T at index %d", privKey, i))
   137  		}
   138  	}
   139  
   140  	return keys, nil
   141  }
   142  
   143  func registerNacos(logger log.Logger) {
   144  	nacosUrls := viper.GetString(FlagRestNacosUrls)
   145  	nacosNamespaceId := viper.GetString(FlagRestNacosNamespaceId)
   146  	applicationName := viper.GetString(FlagRestApplicationName)
   147  	externalAddr := viper.GetString(FlagExternalListenAddr)
   148  
   149  	// start nacos client for registering restful service
   150  	if nacosUrls != "" {
   151  		nacos.StartNacosClient(logger, nacosUrls, nacosNamespaceId, applicationName, externalAddr)
   152  	}
   153  
   154  	nacosTmRpcUrls := viper.GetString(FlagNacosTmrpcUrls)
   155  	nacosTmRpcNamespaceID := viper.GetString(FlagNacosTmrpcNamespaceID)
   156  	nacosTmRpcAppName := viper.GetString(FlagNacosTmrpcAppName)
   157  	rpcExternalAddr := viper.GetString(FlagRpcExternalAddr)
   158  	// start nacos client for tmrpc service
   159  	if nacosTmRpcUrls != "" {
   160  		nacos.StartNacosClient(logger, nacosTmRpcUrls, nacosTmRpcNamespaceID, nacosTmRpcAppName, rpcExternalAddr)
   161  	}
   162  }