func decodeAddress(a string, params *chaincfg.Params) (stdaddr.Address, error) {
	addr, err := stdaddr.DecodeAddress(a, params)
	if err != nil {
		return nil, status.Errorf(codes.InvalidArgument, "invalid address %v: %v", a, err)
	}
	return addr, nil
}
decodeAddress decodes an address and verifies it is intended for the active
network.  This should be used preferred to direct usage of
dcrutil.DecodeAddress, which does not perform the network check.
package rpcserver
import (
	"bytes"
	"context"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"net"
	"sort"
	"sync/atomic"
	"time"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"decred.org/dcrwallet/v2/chain"
	"decred.org/dcrwallet/v2/errors"
	"decred.org/dcrwallet/v2/internal/cfgutil"
	"decred.org/dcrwallet/v2/internal/loader"
	"decred.org/dcrwallet/v2/internal/netparams"
	"decred.org/dcrwallet/v2/internal/vsp"
	"decred.org/dcrwallet/v2/p2p"
	"decred.org/dcrwallet/v2/rpc/client/dcrd"
	pb "decred.org/dcrwallet/v2/rpc/walletrpc"
	"decred.org/dcrwallet/v2/spv"
	"decred.org/dcrwallet/v2/ticketbuyer"
	"decred.org/dcrwallet/v2/wallet"
	"decred.org/dcrwallet/v2/wallet/txauthor"
	"decred.org/dcrwallet/v2/wallet/txrules"
	"decred.org/dcrwallet/v2/wallet/udb"
	"decred.org/dcrwallet/v2/walletseed"
	"github.com/decred/dcrd/addrmgr/v2"
	"github.com/decred/dcrd/blockchain/stake/v4"
	"github.com/decred/dcrd/chaincfg/chainhash"
	"github.com/decred/dcrd/chaincfg/v3"
	"github.com/decred/dcrd/dcrutil/v4"
	"github.com/decred/dcrd/gcs/v3"
	"github.com/decred/dcrd/hdkeychain/v3"
	"github.com/decred/dcrd/txscript/v4"
	"github.com/decred/dcrd/txscript/v4/stdaddr"
	"github.com/decred/dcrd/wire"
)
const (
	semverString = "7.12.0"
	semverMajor  = 7
	semverMinor  = 12
	semverPatch  = 0
)
func translateError(err error) error {
	code := errorCode(err)
	return status.Errorf(code, "%s", err.Error())
}
func errorCode(err error) codes.Code {
	var kind errors.Kind
	if errors.As(err, &kind) {
		switch kind {
		case errors.Bug:
		case errors.Invalid:
			return codes.InvalidArgument
		case errors.Permission:
			return codes.PermissionDenied
		case errors.IO:
		case errors.Exist:
			return codes.AlreadyExists
		case errors.NotExist:
			return codes.NotFound
		case errors.Encoding:
		case errors.Crypto:
			return codes.DataLoss
		case errors.Locked:
			return codes.FailedPrecondition
		case errors.Passphrase:
			return codes.InvalidArgument
		case errors.Seed:
			return codes.InvalidArgument
		case errors.WatchingOnly:
			return codes.Unimplemented
		case errors.InsufficientBalance:
			return codes.ResourceExhausted
		case errors.ScriptFailure:
		case errors.Policy:
		case errors.DoubleSpend:
		case errors.Protocol:
		case errors.NoPeers:
			return codes.Unavailable
		}
	}
	if errors.Is(err, hdkeychain.ErrInvalidSeedLen) {
		return codes.InvalidArgument
	}
	return codes.Unknown
}