diff --git a/api/api.go b/api/api.go index 97f3f1010..ff6017571 100644 --- a/api/api.go +++ b/api/api.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain/address" + "github.com/filecoin-project/go-lotus/chain/types" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" @@ -72,6 +73,7 @@ type API interface { WalletNew(context.Context, string) (address.Address, error) WalletList(context.Context) ([]address.Address, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) // // import // // export // // (on cli - cmd to list associations) diff --git a/api/struct.go b/api/struct.go index 483831fe4..8a44f193d 100644 --- a/api/struct.go +++ b/api/struct.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain/address" + "github.com/filecoin-project/go-lotus/chain/types" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" @@ -25,8 +26,9 @@ type Struct struct { MinerStart func(context.Context, address.Address) error MinerCreateBlock func(context.Context, address.Address, *chain.TipSet, []chain.Ticket, chain.ElectionProof, []*chain.SignedMessage) (*chain.BlockMsg, error) - WalletNew func(context.Context, string) (address.Address, error) - WalletList func(context.Context) ([]address.Address, error) + WalletNew func(context.Context, string) (address.Address, error) + WalletList func(context.Context) ([]address.Address, error) + WalletBalance func(context.Context, address.Address) (types.BigInt, error) ClientImport func(ctx context.Context, path string) (cid.Cid, error) ClientListImports func(ctx context.Context) ([]Import, error) @@ -99,4 +101,8 @@ func (c *Struct) WalletList(ctx context.Context) ([]address.Address, error) { return c.Internal.WalletList(ctx) } +func (c *Struct) WalletBalance(ctx context.Context, a address.Address) (types.BigInt, error) { + return c.Internal.WalletBalance(ctx, a) +} + var _ API = &Struct{} diff --git a/chain/chain.go b/chain/chain.go index 790379600..a971b0e4d 100644 --- a/chain/chain.go +++ b/chain/chain.go @@ -507,3 +507,24 @@ func (cs *ChainStore) LoadMessagesFromCids(cids []cid.Cid) ([]*SignedMessage, er return msgs, nil } + +func (cs *ChainStore) GetBalance(addr address.Address) (types.BigInt, error) { + ts := cs.GetHeaviestTipSet() + stcid, err := cs.TipSetState(ts.Cids()) + if err != nil { + return types.BigInt{}, err + } + + cst := hamt.CSTFromBstore(cs.bs) + state, err := LoadStateTree(cst, stcid) + if err != nil { + return types.BigInt{}, err + } + + act, err := state.GetActor(addr) + if err != nil { + return types.BigInt{}, err + } + + return act.Balance, nil +} diff --git a/cli/wallet.go b/cli/wallet.go index ab8e3f394..ba8ce007a 100644 --- a/cli/wallet.go +++ b/cli/wallet.go @@ -3,6 +3,7 @@ package cli import ( "fmt" + "github.com/filecoin-project/go-lotus/chain/address" "gopkg.in/urfave/cli.v2" ) @@ -12,6 +13,7 @@ var walletCmd = &cli.Command{ Subcommands: []*cli.Command{ walletNew, walletList, + walletBalance, }, } @@ -62,3 +64,28 @@ var walletList = &cli.Command{ return nil }, } + +var walletBalance = &cli.Command{ + Name: "balance", + Usage: "get account balance", + Action: func(cctx *cli.Context) error { + api, err := getAPI(cctx) + if err != nil { + return err + } + ctx := reqContext(cctx) + + addr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + balance, err := api.WalletBalance(ctx, addr) + if err != nil { + return err + } + + fmt.Printf("%s\n", balance.String()) + return nil + }, +} diff --git a/node/api.go b/node/api.go index b164fef33..e2700fb8f 100644 --- a/node/api.go +++ b/node/api.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-lotus/build" "github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain/address" + "github.com/filecoin-project/go-lotus/chain/types" "github.com/filecoin-project/go-lotus/miner" "github.com/filecoin-project/go-lotus/node/client" @@ -113,6 +114,10 @@ func (a *API) WalletList(ctx context.Context) ([]address.Address, error) { return a.Wallet.ListAddrs() } +func (a *API) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) { + return a.Chain.GetBalance(addr) +} + func (a *API) NetConnect(ctx context.Context, p peer.AddrInfo) error { return a.Host.Connect(ctx, p) }