forked from TrueCloudLab/neoneo-go
cli: move wallet-related flags handling to options package
Move GetAccFromContext, GetUnlockedAccount, ReadWalletConfig handling into options package to reuse this code from all CLI handlers. getDecryptedAccount is replaced by GetUnlockedAccount. Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
This commit is contained in:
parent
f93e2fbba4
commit
d7cab3b82c
9 changed files with 119 additions and 150 deletions
|
@ -11,18 +11,24 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"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/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultTimeout is the default timeout used for RPC requests.
|
// DefaultTimeout is the default timeout used for RPC requests.
|
||||||
|
@ -97,6 +103,8 @@ var Debug = cli.BoolFlag{
|
||||||
|
|
||||||
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
|
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
|
||||||
var errInvalidHistoric = errors.New("invalid 'historic' parameter, neither a block number, nor a block/state hash")
|
var errInvalidHistoric = errors.New("invalid 'historic' parameter, neither a block number, nor a block/state hash")
|
||||||
|
var errNoWallet = errors.New("no wallet parameter found, specify it with the '--wallet' or '-w' flag or specify wallet config file with the '--wallet-config' flag")
|
||||||
|
var errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location")
|
||||||
|
|
||||||
// GetNetwork examines Context's flags and returns the appropriate network. It
|
// GetNetwork examines Context's flags and returns the appropriate network. It
|
||||||
// defaults to PrivNet if no flags are given.
|
// defaults to PrivNet if no flags are given.
|
||||||
|
@ -279,3 +287,93 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
|
||||||
log, err := cc.Build()
|
log, err := cc.Build()
|
||||||
return log, &cc.Level, _winfileSinkCloser, err
|
return log, &cc.Level, _winfileSinkCloser, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAccFromContext returns account and wallet from context. If address is not set, default address is used.
|
||||||
|
func GetAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error) {
|
||||||
|
var addr util.Uint160
|
||||||
|
|
||||||
|
wPath := ctx.String("wallet")
|
||||||
|
walletConfigPath := ctx.String("wallet-config")
|
||||||
|
if len(wPath) != 0 && len(walletConfigPath) != 0 {
|
||||||
|
return nil, nil, errConflictingWalletFlags
|
||||||
|
}
|
||||||
|
if len(wPath) == 0 && len(walletConfigPath) == 0 {
|
||||||
|
return nil, nil, errNoWallet
|
||||||
|
}
|
||||||
|
var pass *string
|
||||||
|
if len(walletConfigPath) != 0 {
|
||||||
|
cfg, err := ReadWalletConfig(walletConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
wPath = cfg.Path
|
||||||
|
pass = &cfg.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
wall, err := wallet.NewWalletFromFile(wPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
addrFlag := ctx.Generic("address").(*flags.Address)
|
||||||
|
if addrFlag.IsSet {
|
||||||
|
addr = addrFlag.Uint160()
|
||||||
|
} else {
|
||||||
|
addr = wall.GetChangeAddress()
|
||||||
|
if addr.Equals(util.Uint160{}) {
|
||||||
|
return nil, wall, errors.New("can't get default address")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acc, err := GetUnlockedAccount(wall, addr, pass)
|
||||||
|
return acc, wall, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUnlockedAccount returns account from wallet, address and uses pass to unlock specified account if given.
|
||||||
|
// If the password is not given, then it is requested from user.
|
||||||
|
func GetUnlockedAccount(wall *wallet.Wallet, addr util.Uint160, pass *string) (*wallet.Account, error) {
|
||||||
|
acc := wall.GetAccount(addr)
|
||||||
|
if acc == nil {
|
||||||
|
return nil, fmt.Errorf("wallet contains no account for '%s'", address.Uint160ToString(addr))
|
||||||
|
}
|
||||||
|
|
||||||
|
if acc.CanSign() || acc.EncryptedWIF == "" {
|
||||||
|
return acc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if pass == nil {
|
||||||
|
rawPass, err := input.ReadPassword(
|
||||||
|
fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error reading password: %w", err)
|
||||||
|
}
|
||||||
|
trimmed := strings.TrimRight(string(rawPass), "\n")
|
||||||
|
pass = &trimmed
|
||||||
|
}
|
||||||
|
err := acc.Decrypt(*pass, wall.Scrypt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return acc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadWalletConfig reads wallet config from the given path.
|
||||||
|
func ReadWalletConfig(configPath string) (*config.Wallet, error) {
|
||||||
|
file, err := os.Open(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
configData, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to read wallet config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.Wallet{}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(configData, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal wallet config YAML: %w", err)
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"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/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
|
@ -37,7 +38,7 @@ func manifestAddGroup(ctx *cli.Context) error {
|
||||||
|
|
||||||
h := state.CreateContractHash(sender, nf.Checksum, m.Name)
|
h := state.CreateContractHash(sender, nf.Checksum, m.Name)
|
||||||
|
|
||||||
gAcc, w, err := GetAccFromContext(ctx)
|
gAcc, w, err := options.GetAccFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't get account to sign group with: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't get account to sign group with: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,11 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"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/txctx"
|
"github.com/nspcc-dev/neo-go/cli/txctx"
|
||||||
cliwallet "github.com/nspcc-dev/neo-go/cli/wallet"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
|
@ -39,16 +36,14 @@ import (
|
||||||
const addressFlagName = "address, a"
|
const addressFlagName = "address, a"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoInput = errors.New("no input file was found, specify an input file with the '--in or -i' flag")
|
errNoInput = errors.New("no input file was found, specify an input file with the '--in or -i' flag")
|
||||||
errNoConfFile = errors.New("no config file was found, specify a config file with the '--config' or '-c' flag")
|
errNoConfFile = errors.New("no config file was found, specify a config file with the '--config' or '-c' flag")
|
||||||
errNoManifestFile = errors.New("no manifest file was found, specify manifest file with '--manifest' or '-m' flag")
|
errNoManifestFile = errors.New("no manifest file was found, specify manifest file with '--manifest' or '-m' flag")
|
||||||
errNoMethod = errors.New("no method specified for function invocation command")
|
errNoMethod = errors.New("no method specified for function invocation command")
|
||||||
errNoWallet = errors.New("no wallet parameter found, specify it with the '--wallet' or '-w' flag or specify wallet config file with the '--wallet-config' flag")
|
errNoScriptHash = errors.New("no smart contract hash was provided, specify one as the first argument")
|
||||||
errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location")
|
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
|
||||||
errNoScriptHash = errors.New("no smart contract hash was provided, specify one as the first argument")
|
errFileExist = errors.New("A file with given smart-contract name already exists")
|
||||||
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
|
addressFlag = flags.AddressFlag{
|
||||||
errFileExist = errors.New("A file with given smart-contract name already exists")
|
|
||||||
addressFlag = flags.AddressFlag{
|
|
||||||
Name: addressFlagName,
|
Name: addressFlagName,
|
||||||
Usage: "address to use as transaction signee (and gas source)",
|
Usage: "address to use as transaction signee (and gas source)",
|
||||||
}
|
}
|
||||||
|
@ -570,7 +565,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
w *wallet.Wallet
|
w *wallet.Wallet
|
||||||
)
|
)
|
||||||
if signAndPush {
|
if signAndPush {
|
||||||
acc, w, err = GetAccFromContext(ctx)
|
acc, w, err = options.GetAccFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -746,71 +741,6 @@ func inspect(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccFromContext returns account and wallet from context. If address is not set, default address is used.
|
|
||||||
func GetAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error) {
|
|
||||||
var addr util.Uint160
|
|
||||||
|
|
||||||
wPath := ctx.String("wallet")
|
|
||||||
walletConfigPath := ctx.String("wallet-config")
|
|
||||||
if len(wPath) != 0 && len(walletConfigPath) != 0 {
|
|
||||||
return nil, nil, errConflictingWalletFlags
|
|
||||||
}
|
|
||||||
if len(wPath) == 0 && len(walletConfigPath) == 0 {
|
|
||||||
return nil, nil, errNoWallet
|
|
||||||
}
|
|
||||||
var pass *string
|
|
||||||
if len(walletConfigPath) != 0 {
|
|
||||||
cfg, err := cliwallet.ReadWalletConfig(walletConfigPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
wPath = cfg.Path
|
|
||||||
pass = &cfg.Password
|
|
||||||
}
|
|
||||||
|
|
||||||
wall, err := wallet.NewWalletFromFile(wPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
addrFlag := ctx.Generic("address").(*flags.Address)
|
|
||||||
if addrFlag.IsSet {
|
|
||||||
addr = addrFlag.Uint160()
|
|
||||||
} else {
|
|
||||||
addr = wall.GetChangeAddress()
|
|
||||||
}
|
|
||||||
|
|
||||||
acc, err := GetUnlockedAccount(wall, addr, pass)
|
|
||||||
return acc, wall, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUnlockedAccount returns account from wallet, address and uses pass to unlock specified account if given.
|
|
||||||
// If the password is not given, then it is requested from user.
|
|
||||||
func GetUnlockedAccount(wall *wallet.Wallet, addr util.Uint160, pass *string) (*wallet.Account, error) {
|
|
||||||
acc := wall.GetAccount(addr)
|
|
||||||
if acc == nil {
|
|
||||||
return nil, fmt.Errorf("wallet contains no account for '%s'", address.Uint160ToString(addr))
|
|
||||||
}
|
|
||||||
|
|
||||||
if acc.CanSign() {
|
|
||||||
return acc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if pass == nil {
|
|
||||||
rawPass, err := input.ReadPassword(
|
|
||||||
fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr)))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Error reading password: %w", err)
|
|
||||||
}
|
|
||||||
trimmed := strings.TrimRight(string(rawPass), "\n")
|
|
||||||
pass = &trimmed
|
|
||||||
}
|
|
||||||
err := acc.Decrypt(*pass, wall.Scrypt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return acc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// contractDeploy deploys contract.
|
// contractDeploy deploys contract.
|
||||||
func contractDeploy(ctx *cli.Context) error {
|
func contractDeploy(ctx *cli.Context) error {
|
||||||
nefFile, f, err := readNEFFile(ctx.String("in"))
|
nefFile, f, err := readNEFFile(ctx.String("in"))
|
||||||
|
@ -836,7 +766,7 @@ func contractDeploy(ctx *cli.Context) error {
|
||||||
appCallParams = append(appCallParams, data[0])
|
appCallParams = append(appCallParams, data[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
acc, w, err := GetAccFromContext(ctx)
|
acc, w, err := options.GetAccFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't get sender address: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't get sender address: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/options"
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
"github.com/nspcc-dev/neo-go/cli/smartcontract"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||||
|
@ -40,7 +39,7 @@ func cancelTx(ctx *cli.Context) error {
|
||||||
if mainTx != nil && !mainTx.Blockhash.Equals(util.Uint256{}) {
|
if mainTx != nil && !mainTx.Blockhash.Equals(util.Uint256{}) {
|
||||||
return cli.NewExitError(fmt.Errorf("transaction %s is already accepted at block %s", txHash, mainTx.Blockhash.StringLE()), 1)
|
return cli.NewExitError(fmt.Errorf("transaction %s is already accepted at block %s", txHash, mainTx.Blockhash.StringLE()), 1)
|
||||||
}
|
}
|
||||||
acc, w, err := smartcontract.GetAccFromContext(ctx)
|
acc, w, err = options.GetAccFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"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/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
@ -46,7 +47,7 @@ func newWalletV2FromFile(path string, configPath string) (*walletV2, *string, er
|
||||||
}
|
}
|
||||||
var pass *string
|
var pass *string
|
||||||
if len(configPath) != 0 {
|
if len(configPath) != 0 {
|
||||||
cfg, err := ReadWalletConfig(configPath)
|
cfg, err := options.ReadWalletConfig(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,6 @@ func signStoredTransaction(ctx *cli.Context) error {
|
||||||
if err := cmdargs.EnsureNone(ctx); err != nil {
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wall, pass, err := readWallet(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
defer wall.Close()
|
|
||||||
|
|
||||||
pc, err := paramcontext.Read(ctx.String("in"))
|
pc, err := paramcontext.Read(ctx.String("in"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,9 +30,7 @@ func signStoredTransaction(ctx *cli.Context) error {
|
||||||
if !addrFlag.IsSet {
|
if !addrFlag.IsSet {
|
||||||
return cli.NewExitError("address was not provided", 1)
|
return cli.NewExitError("address was not provided", 1)
|
||||||
}
|
}
|
||||||
|
acc, _, err := options.GetAccFromContext(ctx)
|
||||||
var ch = addrFlag.Uint160()
|
|
||||||
acc, err := getDecryptedAccount(wall, ch, pass)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,7 +522,7 @@ func multiTransferNEP17(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
acc, err := getDecryptedAccount(wall, from, pass)
|
acc, err := options.GetUnlockedAccount(wall, from, pass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -618,7 +618,7 @@ func transferNEP(ctx *cli.Context, standard string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
acc, err := getDecryptedAccount(wall, from, pass)
|
acc, err := options.GetUnlockedAccount(wall, from, pass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"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/txctx"
|
"github.com/nspcc-dev/neo-go/cli/txctx"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
@ -111,7 +110,7 @@ func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *w
|
||||||
return cli.NewExitError("address was not provided", 1)
|
return cli.NewExitError("address was not provided", 1)
|
||||||
}
|
}
|
||||||
addr := addrFlag.Uint160()
|
addr := addrFlag.Uint160()
|
||||||
acc, err := getDecryptedAccount(wall, addr, pass)
|
acc, err := options.GetUnlockedAccount(wall, addr, pass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -153,32 +152,3 @@ func handleVote(ctx *cli.Context) error {
|
||||||
return contract.VoteUnsigned(addr, pub)
|
return contract.VoteUnsigned(addr, pub)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDecryptedAccount tries to get and unlock the specified account if it has a
|
|
||||||
// key inside (otherwise it's returned as is, without an ability to sign). If
|
|
||||||
// password is nil, it will be requested via terminal.
|
|
||||||
func getDecryptedAccount(wall *wallet.Wallet, addr util.Uint160, password *string) (*wallet.Account, error) {
|
|
||||||
acc := wall.GetAccount(addr)
|
|
||||||
if acc == nil {
|
|
||||||
return nil, fmt.Errorf("can't find account for the address: %s", address.Uint160ToString(addr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// No private key available, nothing to decrypt, but it's still a useful account for many purposes.
|
|
||||||
if acc.EncryptedWIF == "" {
|
|
||||||
return acc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if password == nil {
|
|
||||||
pass, err := input.ReadPassword(EnterPasswordPrompt)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error reading password", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
password = &pass
|
|
||||||
}
|
|
||||||
err := acc.Decrypt(*password, wall.Scrypt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return acc, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ 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/txctx"
|
"github.com/nspcc-dev/neo-go/cli/txctx"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
@ -26,7 +25,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -822,7 +820,7 @@ func createWallet(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
var pass *string
|
var pass *string
|
||||||
if len(configPath) != 0 {
|
if len(configPath) != 0 {
|
||||||
cfg, err := ReadWalletConfig(configPath)
|
cfg, err := options.ReadWalletConfig(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -946,7 +944,7 @@ func getWalletPathAndPass(ctx *cli.Context, canUseWalletConfig bool) (string, *s
|
||||||
}
|
}
|
||||||
var pass *string
|
var pass *string
|
||||||
if len(configPath) != 0 {
|
if len(configPath) != 0 {
|
||||||
cfg, err := ReadWalletConfig(configPath)
|
cfg, err := options.ReadWalletConfig(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
@ -956,27 +954,6 @@ func getWalletPathAndPass(ctx *cli.Context, canUseWalletConfig bool) (string, *s
|
||||||
return path, pass, nil
|
return path, pass, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadWalletConfig(configPath string) (*config.Wallet, error) {
|
|
||||||
file, err := os.Open(configPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
configData, err := os.ReadFile(configPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to read wallet config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := &config.Wallet{}
|
|
||||||
|
|
||||||
err = yaml.Unmarshal(configData, &cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to unmarshal wallet config YAML: %w", err)
|
|
||||||
}
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAccountFromWIF(w io.Writer, wif string, scrypt keys.ScryptParams, label *string, pass *string) (*wallet.Account, error) {
|
func newAccountFromWIF(w io.Writer, wif string, scrypt keys.ScryptParams, label *string, pass *string) (*wallet.Account, error) {
|
||||||
var (
|
var (
|
||||||
phrase, name string
|
phrase, name string
|
||||||
|
|
Loading…
Reference in a new issue