@@ -13,6 +13,8 @@ import (
1313 "sync"
1414 "time"
1515
16+ gogogrpc "github.com/gogo/protobuf/grpc"
17+
1618 "github.com/cenkalti/backoff"
1719 "github.com/cosmos/cosmos-sdk/client"
1820 "github.com/cosmos/cosmos-sdk/client/flags"
@@ -21,6 +23,7 @@ import (
2123 codectypes "github.com/cosmos/cosmos-sdk/codec/types"
2224 cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
2325 sdktypes "github.com/cosmos/cosmos-sdk/types"
26+ txtypes "github.com/cosmos/cosmos-sdk/types/tx"
2427 "github.com/cosmos/cosmos-sdk/types/tx/signing"
2528 authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
2629 authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
@@ -59,20 +62,35 @@ const (
5962 defaultFaucetMinAmount = 100
6063)
6164
65+ // FaucetClient allows to mock the cosmosfaucet.Client.
66+ type FaucetClient interface {
67+ Transfer (context.Context , cosmosfaucet.TransferRequest ) (cosmosfaucet.TransferResponse , error )
68+ }
69+
70+ // Gasometer allows to mock the tx.CalculateGas func.
71+ type Gasometer interface {
72+ CalculateGas (clientCtx gogogrpc.ClientConn , txf tx.Factory , msgs ... sdktypes.Msg ) (* txtypes.SimulateResponse , uint64 , error )
73+ }
74+
6275// Client is a client to access your chain by querying and broadcasting transactions.
6376type Client struct {
6477 // RPC is Tendermint RPC.
6578 RPC rpcclient.Client
6679
67- // Factory is a Cosmos SDK tx factory.
68- Factory tx.Factory
80+ // TxFactory is a Cosmos SDK tx factory.
81+ TxFactory tx.Factory
6982
7083 // context is a Cosmos SDK client context.
7184 context client.Context
7285
7386 // AccountRegistry is the retistry to access accounts.
7487 AccountRegistry cosmosaccount.Registry
7588
89+ accountRetriever client.AccountRetriever
90+ bankQueryClient banktypes.QueryClient
91+ faucetClient FaucetClient
92+ gasometer Gasometer
93+
7694 addressPrefix string
7795
7896 nodeAddress string
@@ -188,26 +206,61 @@ func WithBroadcastMode(broadcastMode string) Option {
188206 }
189207}
190208
209+ // WithGenerateOnly tells if txs will be generated only.
191210func WithGenerateOnly (generateOnly bool ) Option {
192211 return func (c * Client ) {
193212 c .generateOnly = generateOnly
194213 }
195214}
196215
197216// WithRPCClient sets a tendermint RPC client.
217+ // Already set by default.
198218func WithRPCClient (rpc rpcclient.Client ) Option {
199219 return func (c * Client ) {
200220 c .RPC = rpc
201221 }
202222}
203223
204224// WithWaitBlockDuration sets the wait duration for WaitForBlock methods.
225+ // Already set by default.
205226func WithWaitBlockDuration (waitBlockDuration time.Duration ) Option {
206227 return func (c * Client ) {
207228 c .waitBlockDuration = waitBlockDuration
208229 }
209230}
210231
232+ // WithAccountRetriever sets the account retriever
233+ // Already set by default.
234+ func WithAccountRetriever (accountRetriever client.AccountRetriever ) Option {
235+ return func (c * Client ) {
236+ c .accountRetriever = accountRetriever
237+ }
238+ }
239+
240+ // WithBankQueryClient sets the bank query client.
241+ // Already set by default.
242+ func WithBankQueryClient (bankQueryClient banktypes.QueryClient ) Option {
243+ return func (c * Client ) {
244+ c .bankQueryClient = bankQueryClient
245+ }
246+ }
247+
248+ // WithFaucetClient sets the faucet client.
249+ // Already set by default.
250+ func WithFaucetClient (faucetClient FaucetClient ) Option {
251+ return func (c * Client ) {
252+ c .faucetClient = faucetClient
253+ }
254+ }
255+
256+ // WithGasometer sets the gasometer.
257+ // Already set by default.
258+ func WithGasometer (gasometer Gasometer ) Option {
259+ return func (c * Client ) {
260+ c .gasometer = gasometer
261+ }
262+ }
263+
211264// New creates a new client with given options.
212265func New (ctx context.Context , options ... Option ) (Client , error ) {
213266 c := Client {
@@ -264,8 +317,20 @@ func New(ctx context.Context, options ...Option) (Client, error) {
264317 }
265318
266319 c .context = c .newContext ()
267- c .Factory = newFactory (c .context )
320+ c .TxFactory = newFactory (c .context )
268321
322+ if c .accountRetriever == nil {
323+ c .accountRetriever = authtypes.AccountRetriever {}
324+ }
325+ if c .bankQueryClient == nil {
326+ c .bankQueryClient = banktypes .NewQueryClient (c .context )
327+ }
328+ if c .faucetClient == nil {
329+ c .faucetClient = cosmosfaucet .NewClient (c .faucetAddress )
330+ }
331+ if c .gasometer == nil {
332+ c .gasometer = gasometer {}
333+ }
269334 // set address prefix in SDK global config
270335 c .SetConfigAddressPrefix ()
271336
@@ -450,7 +515,7 @@ func (c Client) CreateTx(account cosmosaccount.Account, msgs ...sdktypes.Msg) (T
450515 WithFromName (account .Name ).
451516 WithFromAddress (sdkaddr )
452517
453- txf , err := prepareFactory (ctx , c . Factory )
518+ txf , err := c . prepareFactory (ctx )
454519 if err != nil {
455520 return TxService {}, err
456521 }
@@ -462,7 +527,7 @@ func (c Client) CreateTx(account cosmosaccount.Account, msgs ...sdktypes.Msg) (T
462527 return TxService {}, err
463528 }
464529 } else {
465- _ , gas , err = tx .CalculateGas (ctx , txf , msgs ... )
530+ _ , gas , err = c . gasometer .CalculateGas (ctx , txf , msgs ... )
466531 if err != nil {
467532 return TxService {}, err
468533 }
@@ -500,8 +565,7 @@ func (c *Client) makeSureAccountHasTokens(ctx context.Context, address string) e
500565 }
501566
502567 // request coins from the faucet.
503- fc := cosmosfaucet .NewClient (c .faucetAddress )
504- faucetResp , err := fc .Transfer (ctx , cosmosfaucet.TransferRequest {AccountAddress : address })
568+ faucetResp , err := c .faucetClient .Transfer (ctx , cosmosfaucet.TransferRequest {AccountAddress : address })
505569 if err != nil {
506570 return errors .Wrap (errCannotRetrieveFundsFromFaucet , err .Error ())
507571 }
@@ -519,7 +583,7 @@ func (c *Client) makeSureAccountHasTokens(ctx context.Context, address string) e
519583}
520584
521585func (c * Client ) checkAccountBalance (ctx context.Context , address string ) error {
522- resp , err := banktypes . NewQueryClient ( c . context ) .Balance (ctx , & banktypes.QueryBalanceRequest {
586+ resp , err := c . bankQueryClient .Balance (ctx , & banktypes.QueryBalanceRequest {
523587 Address : address ,
524588 Denom : c .faucetDenom ,
525589 })
@@ -550,16 +614,19 @@ func handleBroadcastResult(resp *sdktypes.TxResponse, err error) error {
550614 return nil
551615}
552616
553- func prepareFactory (clientCtx client.Context , txf tx.Factory ) (tx.Factory , error ) {
554- from := clientCtx .GetFromAddress ()
617+ func (c * Client ) prepareFactory (clientCtx client.Context ) (tx.Factory , error ) {
618+ var (
619+ from = clientCtx .GetFromAddress ()
620+ txf = c .TxFactory
621+ )
555622
556- if err := txf . AccountRetriever () .EnsureExists (clientCtx , from ); err != nil {
623+ if err := c . accountRetriever .EnsureExists (clientCtx , from ); err != nil {
557624 return txf , err
558625 }
559626
560627 initNum , initSeq := txf .AccountNumber (), txf .Sequence ()
561628 if initNum == 0 || initSeq == 0 {
562- num , seq , err := txf . AccountRetriever () .GetAccountNumberSequence (clientCtx , from )
629+ num , seq , err := c . accountRetriever .GetAccountNumberSequence (clientCtx , from )
563630 if err != nil {
564631 return txf , err
565632 }
@@ -599,7 +666,7 @@ func (c Client) newContext() client.Context {
599666 WithLegacyAmino (amino ).
600667 WithInput (os .Stdin ).
601668 WithOutput (c .out ).
602- WithAccountRetriever (authtypes. AccountRetriever {} ).
669+ WithAccountRetriever (c . accountRetriever ).
603670 WithBroadcastMode (c .broadcastMode ).
604671 WithHomeDir (c .homePath ).
605672 WithClient (c .RPC ).
0 commit comments