forked from TrueCloudLab/neoneo-go
cli: print zero balance of known token if token
flag specified
Close #2313.
This commit is contained in:
parent
501ca0dedb
commit
cf3ec6d9ac
2 changed files with 78 additions and 8 deletions
|
@ -49,6 +49,16 @@ func TestNEP17Balance(t *testing.T) {
|
||||||
b := e.Chain.GetUtilityTokenBalance(validatorHash)
|
b := e.Chain.GetUtilityTokenBalance(validatorHash)
|
||||||
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$")
|
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$")
|
||||||
})
|
})
|
||||||
|
t.Run("zero balance of known token", func(t *testing.T) {
|
||||||
|
e.Run(t, append(cmdbase, []string{"--token", "NEO"}...)...)
|
||||||
|
addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
|
||||||
|
require.NoError(t, err)
|
||||||
|
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1))
|
||||||
|
e.checkNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
|
||||||
|
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(0).String()+"$")
|
||||||
|
e.checkNextLine(t, "^\\s*Updated:")
|
||||||
|
e.checkNextLine(t, "^\\s*$")
|
||||||
|
})
|
||||||
t.Run("all accounts", func(t *testing.T) {
|
t.Run("all accounts", func(t *testing.T) {
|
||||||
e.Run(t, cmdbase...)
|
e.Run(t, cmdbase...)
|
||||||
addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
|
addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
|
||||||
|
|
|
@ -11,9 +11,11 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/cli/options"
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
@ -188,6 +190,7 @@ func getNEP17Balance(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(ctx.App.Writer, "Account %s\n", acc.Address)
|
fmt.Fprintf(ctx.App.Writer, "Account %s\n", acc.Address)
|
||||||
|
|
||||||
|
var tokenFound bool
|
||||||
for i := range balances.Balances {
|
for i := range balances.Balances {
|
||||||
var tokenName, tokenSymbol string
|
var tokenName, tokenSymbol string
|
||||||
tokenDecimals := 0
|
tokenDecimals := 0
|
||||||
|
@ -203,27 +206,84 @@ func getNEP17Balance(ctx *cli.Context) error {
|
||||||
tokenName = token.Name
|
tokenName = token.Name
|
||||||
tokenSymbol = token.Symbol
|
tokenSymbol = token.Symbol
|
||||||
tokenDecimals = int(token.Decimals)
|
tokenDecimals = int(token.Decimals)
|
||||||
|
tokenFound = true
|
||||||
} else {
|
} else {
|
||||||
if name != "" {
|
if name != "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tokenSymbol = "UNKNOWN"
|
tokenSymbol = "UNKNOWN"
|
||||||
}
|
}
|
||||||
fmt.Fprintf(ctx.App.Writer, "%s: %s (%s)\n", tokenSymbol, tokenName, asset.StringLE())
|
printAssetBalance(ctx, asset, tokenName, tokenSymbol, tokenDecimals, balances.Balances[i])
|
||||||
amount := balances.Balances[i].Amount
|
}
|
||||||
if tokenDecimals != 0 {
|
if name == "" || tokenFound {
|
||||||
b, ok := new(big.Int).SetString(amount, 10)
|
continue
|
||||||
if ok {
|
}
|
||||||
amount = fixedn.ToString(b, tokenDecimals)
|
// Token was explicitly specified, but was not found among balances, thus either balance is 0
|
||||||
|
// or the token doesn't exist. Try to find token by its address/hash/name/symbol and print zero
|
||||||
|
// balance if found. Search into wallet first.
|
||||||
|
token, err := getMatchingToken(ctx, wall, name, manifest.NEP17StandardName)
|
||||||
|
if err != nil {
|
||||||
|
// The wallet doesn't contain specified token, so try to ask chain.
|
||||||
|
h, err := flags.ParseAddress(name)
|
||||||
|
if err != nil {
|
||||||
|
h, err = c.GetNativeContractHash(name)
|
||||||
|
if err != nil {
|
||||||
|
// Try to get native NEP17 with matching symbol.
|
||||||
|
var gasSymbol, neoSymbol string
|
||||||
|
gasSymbol, h, err = getNativeNEP17Symbol(c, nativenames.Gas)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if gasSymbol != name {
|
||||||
|
neoSymbol, h, err = getNativeNEP17Symbol(c, nativenames.Neo)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if neoSymbol != name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", amount)
|
token, err = c.NEP17TokenInfo(h)
|
||||||
fmt.Fprintf(ctx.App.Writer, "\tUpdated: %d\n", balances.Balances[i].LastUpdated)
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
printAssetBalance(ctx, token.Hash, token.Name, token.Symbol, int(token.Decimals), result.NEP17Balance{
|
||||||
|
Asset: token.Hash,
|
||||||
|
Amount: "0",
|
||||||
|
LastUpdated: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printAssetBalance(ctx *cli.Context, asset util.Uint160, tokenName, tokenSymbol string, tokenDecimals int, balance result.NEP17Balance) {
|
||||||
|
fmt.Fprintf(ctx.App.Writer, "%s: %s (%s)\n", tokenSymbol, tokenName, asset.StringLE())
|
||||||
|
amount := balance.Amount
|
||||||
|
if tokenDecimals != 0 {
|
||||||
|
b, ok := new(big.Int).SetString(amount, 10)
|
||||||
|
if ok {
|
||||||
|
amount = fixedn.ToString(b, tokenDecimals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", amount)
|
||||||
|
fmt.Fprintf(ctx.App.Writer, "\tUpdated: %d\n", balance.LastUpdated)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNativeNEP17Symbol(c *client.Client, name string) (string, util.Uint160, error) {
|
||||||
|
h, err := c.GetNativeContractHash(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", util.Uint160{}, fmt.Errorf("failed to get native %s hash: %w", name, err)
|
||||||
|
}
|
||||||
|
symbol, err := c.NEP17Symbol(h)
|
||||||
|
if err != nil {
|
||||||
|
return "", util.Uint160{}, fmt.Errorf("failed to get native %s symbol: %w", name, err)
|
||||||
|
}
|
||||||
|
return symbol, h, nil
|
||||||
|
}
|
||||||
|
|
||||||
func getMatchingToken(ctx *cli.Context, w *wallet.Wallet, name string, standard string) (*wallet.Token, error) {
|
func getMatchingToken(ctx *cli.Context, w *wallet.Wallet, name string, standard string) (*wallet.Token, error) {
|
||||||
return getMatchingTokenAux(ctx, func(i int) *wallet.Token {
|
return getMatchingTokenAux(ctx, func(i int) *wallet.Token {
|
||||||
return w.Extra.Tokens[i]
|
return w.Extra.Tokens[i]
|
||||||
|
|
Loading…
Reference in a new issue