Merge pull request #3235 from nspcc-dev/actor_refactor

cli: move actor handling
This commit is contained in:
Anna Shaleva 2023-12-11 12:19:33 +05:00 committed by GitHub
commit 6f3a219d67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 191 additions and 226 deletions

View file

@ -11,18 +11,25 @@ import (
"os"
"runtime"
"strconv"
"strings"
"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/netmode"
"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/rpcclient"
"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/util"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/urfave/cli"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/yaml.v3"
)
// DefaultTimeout is the default timeout used for RPC requests.
@ -97,6 +104,8 @@ var Debug = cli.BoolFlag{
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 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
// defaults to PrivNet if no flags are given.
@ -279,3 +288,108 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
log, err := cc.Build()
return log, &cc.Level, _winfileSinkCloser, err
}
// GetRPCWithActor returns an RPC client instance and Actor instance for the given context.
func GetRPCWithActor(gctx context.Context, ctx *cli.Context, signers []actor.SignerAccount) (*rpcclient.Client, *actor.Actor, cli.ExitCoder) {
c, err := GetRPCClient(gctx, ctx)
if err != nil {
return nil, nil, err
}
a, actorErr := actor.New(c, signers)
if actorErr != nil {
c.Close()
return nil, nil, cli.NewExitError(fmt.Errorf("failed to create Actor: %w", actorErr), 1)
}
return c, a, 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 := 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
}

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"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/smartcontract/manifest"
"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)
gAcc, w, err := GetAccFromContext(ctx)
gAcc, w, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("can't get account to sign group with: %w", err), 1)
}

View file

@ -11,14 +11,11 @@ import (
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"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/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/core/state"
"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/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -43,8 +40,6 @@ var (
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")
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")
errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location")
errNoScriptHash = errors.New("no smart contract hash was provided, specify one as the first argument")
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
errFileExist = errors.New("A file with given smart-contract name already exists")
@ -570,7 +565,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
w *wallet.Wallet
)
if signAndPush {
acc, w, err = GetAccFromContext(ctx)
acc, w, err = options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -597,19 +592,14 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet,
}
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
if signAndPush {
_, act, err = options.GetRPCWithActor(gctx, ctx, signersAccounts)
if err != nil {
return err
}
if signAndPush {
act, err = actor.New(c, signersAccounts)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
}
inv = &act.Invoker
} else {
inv, err = options.GetInvoker(c, ctx, cosigners)
_, inv, err = options.GetRPCWithInvoker(gctx, ctx, cosigners)
if err != nil {
return err
}
@ -746,71 +736,6 @@ func inspect(ctx *cli.Context) error {
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.
func contractDeploy(ctx *cli.Context) error {
nefFile, f, err := readNEFFile(ctx.String("in"))
@ -836,7 +761,7 @@ func contractDeploy(ctx *cli.Context) error {
appCallParams = append(appCallParams, data[0])
}
acc, w, err := GetAccFromContext(ctx)
acc, w, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("can't get sender address: %w", err), 1)
}

View file

@ -4,9 +4,9 @@ import (
"fmt"
"strings"
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"github.com/nspcc-dev/neo-go/cli/flags"
"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/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
@ -31,30 +31,30 @@ func cancelTx(ctx *cli.Context) error {
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
acc, w, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create RPC client: %w", err), 1)
return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1)
}
defer w.Close()
signers, err := cmdargs.GetSignersAccounts(acc, w, nil, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
c, a, exitErr := options.GetRPCWithActor(gctx, ctx, signers)
if exitErr != nil {
return exitErr
}
mainTx, _ := c.GetRawTransactionVerbose(txHash)
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)
}
acc, w, err := smartcontract.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to get account from context to sign the conflicting transaction: %w", err), 1)
}
defer w.Close()
if mainTx != nil && !mainTx.HasSigner(acc.ScriptHash()) {
return cli.NewExitError(fmt.Errorf("account %s is not a signer of the conflicting transaction", acc.Address), 1)
}
a, err := actor.NewSimple(c, acc)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create Actor: %w", err), 1)
}
resHash, _, err := a.SendTunedRun([]byte{byte(opcode.RET)}, []transaction.Attribute{{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: txHash}}}, func(r *result.Invoke, t *transaction.Transaction) error {
err := actor.DefaultCheckerModifier(r, t)
if err != nil {

View file

@ -8,6 +8,7 @@ import (
"errors"
"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/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -46,7 +47,7 @@ func newWalletV2FromFile(path string, configPath string) (*walletV2, *string, er
}
var pass *string
if len(configPath) != 0 {
cfg, err := ReadWalletConfig(configPath)
cfg, err := options.ReadWalletConfig(configPath)
if err != nil {
return nil, nil, err
}

View file

@ -21,11 +21,6 @@ func signStoredTransaction(ctx *cli.Context) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
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"))
if err != nil {
@ -35,9 +30,7 @@ func signStoredTransaction(ctx *cli.Context) error {
if !addrFlag.IsSet {
return cli.NewExitError("address was not provided", 1)
}
var ch = addrFlag.Uint160()
acc, err := getDecryptedAccount(wall, ch, pass)
acc, _, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -47,20 +40,13 @@ func signStoredTransaction(ctx *cli.Context) error {
return cli.NewExitError("verifiable item is not a transaction", 1)
}
signerFound := false
for i := range tx.Signers {
if tx.Signers[i].Account == ch {
signerFound = true
break
}
}
if !signerFound {
if !tx.HasSigner(acc.ScriptHash()) {
return cli.NewExitError("tx signers don't contain provided account", 1)
}
if acc.CanSign() {
sign := acc.SignHashable(pc.Network, pc.Verifiable)
if err := pc.AddSignature(ch, acc.Contract, acc.PublicKey(), sign); err != nil {
if err := pc.AddSignature(acc.ScriptHash(), acc.Contract, acc.PublicKey(), sign); err != nil {
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
}
} else if rpcNode == "" {

View file

@ -522,7 +522,7 @@ func multiTransferNEP17(ctx *cli.Context) error {
if err != nil {
return cli.NewExitError(err, 1)
}
acc, err := getDecryptedAccount(wall, from, pass)
acc, err := options.GetUnlockedAccount(wall, from, pass)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -530,25 +530,36 @@ func multiTransferNEP17(ctx *cli.Context) error {
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
if ctx.NArg() == 0 {
return cli.NewExitError("empty recipients list", 1)
}
var (
recipients []transferTarget
cosignersOffset = ctx.NArg()
cosignersSepPos = ctx.NArg() // `--` position.
)
cache := make(map[string]*wallet.Token)
for i := 0; i < ctx.NArg(); i++ {
arg := ctx.Args().Get(i)
if arg == cmdargs.CosignersSeparator {
cosignersOffset = i + 1
cosignersSepPos = i
break
}
}
cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersSepPos+1)
if extErr != nil {
return extErr
}
signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
c, act, exitErr := options.GetRPCWithActor(gctx, ctx, signersAccounts)
if exitErr != nil {
return exitErr
}
cache := make(map[string]*wallet.Token)
for i := 0; i < cosignersSepPos; i++ {
arg := ctx.Args().Get(i)
ss := strings.SplitN(arg, ":", 3)
if len(ss) != 3 {
return cli.NewExitError("send format must be '<token>:<addr>:<amount>", 1)
@ -580,19 +591,6 @@ func multiTransferNEP17(ctx *cli.Context) error {
})
}
cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset)
if extErr != nil {
return extErr
}
signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
act, err := actor.New(c, signersAccounts)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
}
tx, err := makeMultiTransferNEP17(act, recipients)
if err != nil {
return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1)
@ -618,7 +616,7 @@ func transferNEP(ctx *cli.Context, standard string) error {
if err != nil {
return cli.NewExitError(err, 1)
}
acc, err := getDecryptedAccount(wall, from, pass)
acc, err := options.GetUnlockedAccount(wall, from, pass)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -626,9 +624,22 @@ func transferNEP(ctx *cli.Context, standard string) error {
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
cosignersOffset, data, extErr := cmdargs.GetDataFromContext(ctx)
if extErr != nil {
return extErr
}
cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset)
if extErr != nil {
return extErr
}
signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(err, 1)
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
c, act, exitErr := options.GetRPCWithActor(gctx, ctx, signersAccounts)
if exitErr != nil {
return exitErr
}
toFlag := ctx.Generic("to").(*flags.Address)
@ -644,24 +655,6 @@ func transferNEP(ctx *cli.Context, standard string) error {
}
}
cosignersOffset, data, extErr := cmdargs.GetDataFromContext(ctx)
if extErr != nil {
return extErr
}
cosigners, extErr := cmdargs.GetSignersFromContext(ctx, cosignersOffset)
if extErr != nil {
return extErr
}
signersAccounts, err := cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
act, err := actor.New(c, signersAccounts)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
}
amountArg := ctx.String("amount")
amount, err := fixedn.FromString(amountArg, int(token.Decimals))
// It's OK for NEP-11 transfer to not have amount set.

View file

@ -5,13 +5,10 @@ import (
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"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/txctx"
"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/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet"
@ -111,7 +108,7 @@ func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *w
return cli.NewExitError("address was not provided", 1)
}
addr := addrFlag.Uint160()
acc, err := getDecryptedAccount(wall, addr, pass)
acc, err := options.GetUnlockedAccount(wall, addr, pass)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -119,13 +116,13 @@ func handleNeoAction(ctx *cli.Context, mkTx func(*neo.Contract, util.Uint160, *w
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
signers, err := cmdargs.GetSignersAccounts(acc, wall, nil, transaction.CalledByEntry)
if err != nil {
return cli.NewExitError(err, 1)
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
act, err := actor.NewSimple(c, acc)
if err != nil {
return cli.NewExitError(fmt.Errorf("RPC actor issue: %w", err), 1)
_, act, exitErr := options.GetRPCWithActor(gctx, ctx, signers)
if exitErr != nil {
return exitErr
}
contract := neo.New(act)
@ -153,32 +150,3 @@ func handleVote(ctx *cli.Context) error {
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
}

View file

@ -15,7 +15,6 @@ import (
"github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/cli/options"
"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/crypto/keys"
"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/wallet"
"github.com/urfave/cli"
"gopkg.in/yaml.v3"
)
const (
@ -822,7 +820,7 @@ func createWallet(ctx *cli.Context) error {
}
var pass *string
if len(configPath) != 0 {
cfg, err := ReadWalletConfig(configPath)
cfg, err := options.ReadWalletConfig(configPath)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -946,7 +944,7 @@ func getWalletPathAndPass(ctx *cli.Context, canUseWalletConfig bool) (string, *s
}
var pass *string
if len(configPath) != 0 {
cfg, err := ReadWalletConfig(configPath)
cfg, err := options.ReadWalletConfig(configPath)
if err != nil {
return "", nil, err
}
@ -956,27 +954,6 @@ func getWalletPathAndPass(ctx *cli.Context, canUseWalletConfig bool) (string, *s
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) {
var (
phrase, name string