Example #1
0
// SendRawTransaction sends a hex-encoded transaction for relay.
func SendRawTransaction(rpc ServerConn, hextx string) (txid string, error *btcjson.Error) {
	// NewSendRawTransactionCmd cannot fail, so omit the check.
	cmd, _ := btcjson.NewSendRawTransactionCmd(<-NewJSONID, hextx)
	request := NewServerRequest(cmd, new(string))
	response := <-rpc.SendRequest(request)
	if response.Error() != nil {
		return "", response.Error()
	}
	return *response.Result().(*string), nil
}
Example #2
0
// SendRawTransaction sends a hex-encoded transaction for relay.
func SendRawTransaction(rpc ServerConn, hextx string) (txid string, error *btcjson.Error) {
	// NewSendRawTransactionCmd cannot fail, so omit the check.
	cmd, _ := btcjson.NewSendRawTransactionCmd(<-NewJSONID, hextx)
	response := <-rpc.SendRequest(NewServerRequest(cmd))

	var resultData string
	_, jsonErr := response.FinishUnmarshal(&resultData)
	if jsonErr != nil {
		return "", jsonErr
	}
	return resultData, nil
}
Example #3
0
// SendRawTransactionAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See SendRawTransaction for the blocking version and more details.
func (c *Client) SendRawTransactionAsync(tx *btcwire.MsgTx, allowHighFees bool) FutureSendRawTransactionResult {
	txHex := ""
	if tx != nil {
		// Serialize the transaction and convert to hex string.
		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
		if err := tx.Serialize(buf); err != nil {
			return newFutureError(err)
		}
		txHex = hex.EncodeToString(buf.Bytes())
	}

	id := c.NextID()
	cmd, err := btcjson.NewSendRawTransactionCmd(id, txHex, allowHighFees)
	if err != nil {
		return newFutureError(err)
	}

	return c.sendCmd(cmd)
}
Example #4
0
// makeSendRawTransaction generates the cmd structure for sendrawtransaction
// commands.
func makeSendRawTransaction(args []interface{}) (btcjson.Cmd, error) {
	return btcjson.NewSendRawTransactionCmd("btcctl", args[0].(string))
}
Example #5
0
// 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 := accountstore.Account(cmd.FromAccount)
	if err != nil {
		return nil, &btcjson.ErrWalletInvalidAccountName
	}

	// Create transaction, replying with an error if the creation
	// was not successful.
	createdTx, err := a.txToPairs(cmd.Amounts, 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: // any other non-nil error
		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 {
		a.ScheduleWalletWrite()
		if err := a.WriteScheduledToDisk(); 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)
	var txid string
	request := NewRPCRequest(sendtx, txid)
	response := <-CurrentRPCConn().SendRequest(request)
	txid = response.Result.(string)

	if response.Err != nil {
		SendTxHistSyncChans.remove <- createdTx.txid
		return nil, response.Err
	}

	return handleSendRawTxReply(cmd, txid, a, createdTx)
}
Example #6
0
// sendPairs is a helper routine to reduce duplicated code when creating and
// sending payment transactions.
func sendPairs(icmd btcjson.Cmd, account string, amounts map[string]int64,
	minconf int) (interface{}, *btcjson.Error) {
	// Check that the account specified in the request exists.
	a, err := AcctMgr.Account(account)
	if err != nil {
		return nil, &btcjson.ErrWalletInvalidAccountName
	}

	// Create transaction, replying with an error if the creation
	// was not successful.
	createdTx, err := a.txToPairs(amounts, 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: // any other non-nil error
		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(icmd, txid, a, createdTx)
}