package lnwallet
import (
"errors"
"fmt"
"sync"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcwallet/wallet/txauthor"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
)
type AddressType uint8
const (
UnknownAddressType AddressType = iota
WitnessPubKey
NestedWitnessPubKey
)
var (
DefaultPublicPassphrase = []byte("public")
DefaultPrivatePassphrase = []byte("hello")
ErrDoubleSpend = errors.New("transaction rejected: output already spent")
ErrNotMine = errors.New("the passed output doesn't belong to the wallet")
)
var ErrNoOutputs = errors.New("no outputs")
type Utxo struct {
AddressType AddressType
Value btcutil.Amount
Confirmations int64
PkScript []byte
wire.OutPoint
}
type TransactionDetail struct {
Hash chainhash.Hash
Value btcutil.Amount
NumConfirmations int32
BlockHash *chainhash.Hash
BlockHeight int32
Timestamp int64
TotalFees int64
DestAddresses []btcutil.Address
RawTx []byte
}
type TransactionSubscription interface {
ConfirmedTransactions() chan *TransactionDetail
UnconfirmedTransactions() chan *TransactionDetail
Cancel()
}
type WalletController interface {
FetchInputInfo(prevOut *wire.OutPoint) (*Utxo, error)
ConfirmedBalance(confs int32) (btcutil.Amount, error)
NewAddress(addrType AddressType, change bool) (btcutil.Address, error)
LastUnusedAddress(addrType AddressType) (btcutil.Address, error)
IsOurAddress(a btcutil.Address) bool
SendOutputs(outputs []*wire.TxOut,
feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error)
CreateSimpleTx(outputs []*wire.TxOut, feeRate chainfee.SatPerKWeight,
dryRun bool) (*txauthor.AuthoredTx, error)
ListUnspentWitness(minconfirms, maxconfirms int32) ([]*Utxo, error)
ListTransactionDetails() ([]*TransactionDetail, error)
LockOutpoint(o wire.OutPoint)
UnlockOutpoint(o wire.OutPoint)
PublishTransaction(tx *wire.MsgTx) error
SubscribeTransactions() (TransactionSubscription, error)
IsSynced() (bool, int64, error)
Start() error
Stop() error
BackEnd() string
}
type BlockChainIO interface {
GetBestBlock() (*chainhash.Hash, int32, error)
GetUtxo(op *wire.OutPoint, pkScript []byte, heightHint uint32,
cancel <-chan struct{}) (*wire.TxOut, error)
GetBlockHash(blockHeight int64) (*chainhash.Hash, error)
GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error)
}
type MessageSigner interface {
SignMessage(pubKey *btcec.PublicKey, msg []byte) (input.Signature, error)
}
type WalletDriver struct {
WalletType string
New func(args ...interface{}) (WalletController, error)
BackEnds func() []string
}
var (
wallets = make(map[string]*WalletDriver)
registerMtx sync.Mutex
)
func RegisteredWallets() []*WalletDriver {
registerMtx.Lock()
defer registerMtx.Unlock()
registeredWallets := make([]*WalletDriver, 0, len(wallets))
for _, wallet := range wallets {
registeredWallets = append(registeredWallets, wallet)
}
return registeredWallets
}
func RegisterWallet(driver *WalletDriver) error {
registerMtx.Lock()
defer registerMtx.Unlock()
if _, ok := wallets[driver.WalletType]; ok {
return fmt.Errorf("wallet already registered")
}
wallets[driver.WalletType] = driver
return nil
}
func SupportedWallets() []string {
registerMtx.Lock()
defer registerMtx.Unlock()
supportedWallets := make([]string, 0, len(wallets))
for walletName := range wallets {
supportedWallets = append(supportedWallets, walletName)
}
return supportedWallets
}