mirror of
https://github.com/LBRYFoundation/lbcwallet.git
synced 2025-08-23 17:47:29 +00:00
parent
243acf5491
commit
e685d0279f
1 changed files with 100 additions and 119 deletions
219
rpcserver.go
219
rpcserver.go
|
@ -49,6 +49,7 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"listtransactions": ListTransactions,
|
"listtransactions": ListTransactions,
|
||||||
"sendfrom": SendFrom,
|
"sendfrom": SendFrom,
|
||||||
"sendmany": SendMany,
|
"sendmany": SendMany,
|
||||||
|
"sendtoaddress": SendToAddress,
|
||||||
"settxfee": SetTxFee,
|
"settxfee": SetTxFee,
|
||||||
"walletlock": WalletLock,
|
"walletlock": WalletLock,
|
||||||
"walletpassphrase": WalletPassphrase,
|
"walletpassphrase": WalletPassphrase,
|
||||||
|
@ -72,7 +73,6 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"listunspent": Unimplemented,
|
"listunspent": Unimplemented,
|
||||||
"lockunspent": Unimplemented,
|
"lockunspent": Unimplemented,
|
||||||
"move": Unimplemented,
|
"move": Unimplemented,
|
||||||
"sendtoaddress": Unimplemented,
|
|
||||||
"setaccount": Unimplemented,
|
"setaccount": Unimplemented,
|
||||||
"signmessage": Unimplemented,
|
"signmessage": Unimplemented,
|
||||||
"signrawtransaction": Unimplemented,
|
"signrawtransaction": Unimplemented,
|
||||||
|
@ -1088,130 +1088,19 @@ func ListAllTransactions(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendFrom handles a sendfrom RPC request by creating a new transaction
|
// sendPairs is a helper routine to reduce duplicated code when creating and
|
||||||
// spending unspent transaction outputs for a wallet to another payment
|
// sending payment transactions.
|
||||||
// address. Leftover inputs not sent to the payment address or a fee for
|
func sendPairs(icmd btcjson.Cmd, account string, amounts map[string]int64,
|
||||||
// the miner are sent back to a new address in the wallet. Upon success,
|
minconf int) (interface{}, *btcjson.Error) {
|
||||||
// the TxID for the created transaction is returned.
|
|
||||||
func SendFrom(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
|
||||||
// Type assert icmd to access parameters.
|
|
||||||
cmd, ok := icmd.(*btcjson.SendFromCmd)
|
|
||||||
if !ok {
|
|
||||||
return nil, &btcjson.ErrInternal
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that signed integer parameters are positive.
|
|
||||||
if cmd.Amount < 0 {
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrInvalidParameter.Code,
|
|
||||||
Message: "amount must be positive",
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
if cmd.MinConf < 0 {
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrInvalidParameter.Code,
|
|
||||||
Message: "minconf must be positive",
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the account specified in the request exists.
|
// Check that the account specified in the request exists.
|
||||||
a, err := AcctMgr.Account(cmd.FromAccount)
|
a, err := AcctMgr.Account(account)
|
||||||
if err != nil {
|
|
||||||
return nil, &btcjson.ErrWalletInvalidAccountName
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create map of address and amount pairs.
|
|
||||||
pairs := map[string]int64{
|
|
||||||
cmd.ToAddress: cmd.Amount,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create transaction, replying with an error if the creation
|
|
||||||
// was not successful.
|
|
||||||
createdTx, err := a.txToPairs(pairs, cmd.MinConf)
|
|
||||||
switch {
|
|
||||||
case err == ErrNonPositiveAmount:
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrInvalidParameter.Code,
|
|
||||||
Message: "amount must be positive",
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
|
|
||||||
case err == wallet.ErrWalletLocked:
|
|
||||||
return nil, &btcjson.ErrWalletUnlockNeeded
|
|
||||||
|
|
||||||
case err != nil:
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrInternal.Code,
|
|
||||||
Message: err.Error(),
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark txid as having send history so handlers adding receive history
|
|
||||||
// wait until all send history has been written.
|
|
||||||
SendTxHistSyncChans.add <- createdTx.txid
|
|
||||||
|
|
||||||
// If a change address was added, sync wallet to disk and request
|
|
||||||
// transaction notifications to the change address.
|
|
||||||
if createdTx.changeAddr != nil {
|
|
||||||
AcctMgr.ds.ScheduleWalletWrite(a)
|
|
||||||
if err := AcctMgr.ds.FlushAccount(a); err != nil {
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrWallet.Code,
|
|
||||||
Message: "Cannot write account: " + err.Error(),
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
a.ReqNewTxsForAddress(createdTx.changeAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
hextx := hex.EncodeToString(createdTx.rawTx)
|
|
||||||
// NewSendRawTransactionCmd will never fail so don't check error.
|
|
||||||
sendtx, _ := btcjson.NewSendRawTransactionCmd(<-NewJSONID, hextx)
|
|
||||||
request := NewServerRequest(sendtx, new(string))
|
|
||||||
response := <-CurrentServerConn().SendRequest(request)
|
|
||||||
txid := *response.Result().(*string)
|
|
||||||
|
|
||||||
if response.Error() != nil {
|
|
||||||
SendTxHistSyncChans.remove <- createdTx.txid
|
|
||||||
return nil, response.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
return handleSendRawTxReply(cmd, txid, a, createdTx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMany handles a sendmany RPC request by creating a new transaction
|
|
||||||
// spending unspent transaction outputs for a wallet to any number of
|
|
||||||
// payment addresses. Leftover inputs not sent to the payment address
|
|
||||||
// or a fee for the miner are sent back to a new address in the wallet.
|
|
||||||
// Upon success, the TxID for the created transaction is returned.
|
|
||||||
func SendMany(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
|
||||||
// Type assert icmd to access parameters.
|
|
||||||
cmd, ok := icmd.(*btcjson.SendManyCmd)
|
|
||||||
if !ok {
|
|
||||||
return nil, &btcjson.ErrInternal
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that minconf is positive.
|
|
||||||
if cmd.MinConf < 0 {
|
|
||||||
e := btcjson.Error{
|
|
||||||
Code: btcjson.ErrInvalidParameter.Code,
|
|
||||||
Message: "minconf must be positive",
|
|
||||||
}
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the account specified in the request exists.
|
|
||||||
a, err := AcctMgr.Account(cmd.FromAccount)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &btcjson.ErrWalletInvalidAccountName
|
return nil, &btcjson.ErrWalletInvalidAccountName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create transaction, replying with an error if the creation
|
// Create transaction, replying with an error if the creation
|
||||||
// was not successful.
|
// was not successful.
|
||||||
createdTx, err := a.txToPairs(cmd.Amounts, cmd.MinConf)
|
createdTx, err := a.txToPairs(amounts, minconf)
|
||||||
switch {
|
switch {
|
||||||
case err == ErrNonPositiveAmount:
|
case err == ErrNonPositiveAmount:
|
||||||
e := btcjson.Error{
|
e := btcjson.Error{
|
||||||
|
@ -1261,7 +1150,96 @@ func SendMany(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
return nil, response.Error()
|
return nil, response.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleSendRawTxReply(cmd, txid, a, createdTx)
|
return handleSendRawTxReply(icmd, txid, a, createdTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SendFrom handles a sendfrom RPC request by creating a new transaction
|
||||||
|
// spending unspent transaction outputs for a wallet to another payment
|
||||||
|
// address. Leftover inputs not sent to the payment address or a fee for
|
||||||
|
// the miner are sent back to a new address in the wallet. Upon success,
|
||||||
|
// the TxID for the created transaction is returned.
|
||||||
|
func SendFrom(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
|
// Type assert icmd to access parameters.
|
||||||
|
cmd, ok := icmd.(*btcjson.SendFromCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, &btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that signed integer parameters are positive.
|
||||||
|
if cmd.Amount < 0 {
|
||||||
|
e := btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: "amount must be positive",
|
||||||
|
}
|
||||||
|
return nil, &e
|
||||||
|
}
|
||||||
|
if cmd.MinConf < 0 {
|
||||||
|
e := btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: "minconf must be positive",
|
||||||
|
}
|
||||||
|
return nil, &e
|
||||||
|
}
|
||||||
|
// Create map of address and amount pairs.
|
||||||
|
pairs := map[string]int64{
|
||||||
|
cmd.ToAddress: cmd.Amount,
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendPairs(cmd, cmd.FromAccount, pairs, cmd.MinConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMany handles a sendmany RPC request by creating a new transaction
|
||||||
|
// spending unspent transaction outputs for a wallet to any number of
|
||||||
|
// payment addresses. Leftover inputs not sent to the payment address
|
||||||
|
// or a fee for the miner are sent back to a new address in the wallet.
|
||||||
|
// Upon success, the TxID for the created transaction is returned.
|
||||||
|
func SendMany(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
|
// Type assert icmd to access parameters.
|
||||||
|
cmd, ok := icmd.(*btcjson.SendManyCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, &btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that minconf is positive.
|
||||||
|
if cmd.MinConf < 0 {
|
||||||
|
e := btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: "minconf must be positive",
|
||||||
|
}
|
||||||
|
return nil, &e
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendPairs(cmd, cmd.FromAccount, cmd.Amounts, cmd.MinConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendToAddress handles a sendtoaddress RPC request by creating a new
|
||||||
|
// transaction spending unspent transaction outputs for a wallet to another
|
||||||
|
// payment address. Leftover inputs not sent to the payment address or a fee
|
||||||
|
// for the miner are sent back to a new address in the wallet. Upon success,
|
||||||
|
// the TxID for the created transaction is returned.
|
||||||
|
func SendToAddress(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
|
||||||
|
// Type assert icmd to access parameters.
|
||||||
|
cmd, ok := icmd.(*btcjson.SendToAddressCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, &btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that signed integer parameters are positive.
|
||||||
|
if cmd.Amount < 0 {
|
||||||
|
e := btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: "amount must be positive",
|
||||||
|
}
|
||||||
|
return nil, &e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock up map of address and amount pairs.
|
||||||
|
pairs := map[string]int64{
|
||||||
|
cmd.Address: cmd.Amount,
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendPairs(cmd, "", pairs, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Channels to manage SendBeforeReceiveHistorySync.
|
// Channels to manage SendBeforeReceiveHistorySync.
|
||||||
|
@ -1394,6 +1372,9 @@ func handleSendRawTxReply(icmd btcjson.Cmd, txIDStr string, a *Account, txInfo *
|
||||||
|
|
||||||
case *btcjson.SendManyCmd:
|
case *btcjson.SendManyCmd:
|
||||||
_ = cmd.Comment
|
_ = cmd.Comment
|
||||||
|
case *btcjson.SendToAddressCmd:
|
||||||
|
_ = cmd.Comment
|
||||||
|
_ = cmd.CommentTo
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Successfully sent transaction %v", txIDStr)
|
log.Infof("Successfully sent transaction %v", txIDStr)
|
||||||
|
|
Loading…
Add table
Reference in a new issue