wallet: allow to add token contracts to the wallet

This commit is contained in:
Evgenii Stratonikov 2020-03-06 15:58:24 +03:00
parent d447064515
commit 564a8e429d
3 changed files with 101 additions and 1 deletions

60
pkg/wallet/token.go Normal file
View file

@ -0,0 +1,60 @@
package wallet
import (
"encoding/json"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// Token represents imported token contract.
type Token struct {
Name string
Hash util.Uint160
Decimals int64
Symbol string
Address string
}
type tokenAux struct {
Name string `json:"name"`
Hash util.Uint160 `json:"script_hash"`
Decimals int64 `json:"decimals"`
Symbol string `json:"symbol"`
}
// NewToken returns new token contract info.
func NewToken(tokenHash util.Uint160, name, symbol string, decimals int64) *Token {
return &Token{
Name: name,
Hash: tokenHash,
Decimals: decimals,
Symbol: symbol,
Address: address.Uint160ToString(tokenHash),
}
}
// MarshalJSON implements json.Marshaler interface.
func (t *Token) MarshalJSON() ([]byte, error) {
m := &tokenAux{
Name: t.Name,
Hash: t.Hash.Reverse(), // address should be marshaled in LE but default marshaler uses BE.
Decimals: t.Decimals,
Symbol: t.Symbol,
}
return json.Marshal(m)
}
// UnmarshalJSON implements json.Unmarshaler interface.
func (t *Token) UnmarshalJSON(data []byte) error {
aux := new(tokenAux)
if err := json.Unmarshal(data, aux); err != nil {
return err
}
t.Name = aux.Name
t.Hash = aux.Hash.Reverse()
t.Decimals = aux.Decimals
t.Symbol = aux.Symbol
t.Address = address.Uint160ToString(t.Hash)
return nil
}

29
pkg/wallet/token_test.go Normal file
View file

@ -0,0 +1,29 @@
package wallet
import (
"encoding/json"
"testing"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require"
)
func TestToken_MarshalJSON(t *testing.T) {
// From the https://neo-python.readthedocs.io/en/latest/prompt.html#import-nep5-compliant-token
h, err := util.Uint160DecodeStringLE("f8d448b227991cf07cb96a6f9c0322437f1599b9")
require.NoError(t, err)
tok := NewToken(h, "NEP5 Standard", "NEP5", 8)
require.Equal(t, "NEP5 Standard", tok.Name)
require.Equal(t, "NEP5", tok.Symbol)
require.EqualValues(t, 8, tok.Decimals)
require.Equal(t, h, tok.Hash)
require.Equal(t, "AYhE3Svuqdfh1RtzvE8hUhNR7HSpaSDFQg", tok.Address)
data, err := json.Marshal(tok)
require.NoError(t, err)
actual := new(Token)
require.NoError(t, json.Unmarshal(data, actual))
require.Equal(t, tok, actual)
}

View file

@ -28,7 +28,7 @@ type Wallet struct {
// Extra metadata can be used for storing arbitrary data.
// This field can be empty.
Extra interface{} `json:"extra"`
Extra Extra `json:"extra"`
// Path where the wallet file is located..
path string
@ -37,6 +37,12 @@ type Wallet struct {
rw io.ReadWriter
}
// Extra stores imported token contracts.
type Extra struct {
// Tokens is a list of imported token contracts.
Tokens []*Token
}
// NewWallet creates a new NEO wallet at the given location.
func NewWallet(location string) (*Wallet, error) {
file, err := os.Create(location)
@ -96,6 +102,11 @@ func (w *Wallet) AddAccount(acc *Account) {
w.Accounts = append(w.Accounts, acc)
}
// AddToken adds new token to a wallet.
func (w *Wallet) AddToken(tok *Token) {
w.Extra.Tokens = append(w.Extra.Tokens, tok)
}
// Path returns the location of the wallet on the filesystem.
func (w *Wallet) Path() string {
return w.path