diff --git a/src/BitcoinLib/Requests/FundRawTransaction/FundRawTransactionOptions.cs b/src/BitcoinLib/Requests/FundRawTransaction/FundRawTransactionOptions.cs new file mode 100644 index 0000000..20ad1f6 --- /dev/null +++ b/src/BitcoinLib/Requests/FundRawTransaction/FundRawTransactionOptions.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; + +namespace BitcoinLib.Requests.FundRawTransaction +{ + /// <summary> + /// + /// </summary> + public class FundRawTransactionOptions + { + /// <summary> + /// + /// </summary> + public Dictionary<string, object> Data = new Dictionary<string, object>(); + + /// <summary> + /// (string, optional, default=pool address) The Bitcoin Cash address to receive the change + /// </summary> + public string changeAddress { set => Data[nameof(changeAddress)] = value; } + + /// <summary> + /// (numeric, optional, default=random) The index of the change output + /// </summary> + public double? changePosition { set => Data[nameof(changePosition)] = value; } + + /// <summary> + /// (boolean, optional, default=false) Also select inputs which are watch only + /// </summary> + public bool? includeWatching { set => Data[nameof(includeWatching)] = value; } + + /// <summary> + /// (boolean, optional, default=false) Lock selected unspent outputs + /// </summary> + public bool? lockUnspents { set => Data[nameof(lockUnspents)] = value; } + + /// <summary> + /// (numeric or string, optional, default=not set: makes wallet determine the fee) Set a specific fee rate in BCH/kB + /// </summary> + public double? feeRate { set => Data[nameof(feeRate)] = value; } + + /// <summary> + /// [ (json array, optional) A json array of integers. + /// The fee will be equally deducted from the amount of each specified output. + /// The outputs are specified by their zero-based index, before any change output is added. + /// Those recipients will receive less bitcoins than you enter in their corresponding amount field. + /// If no outputs are specified here, the sender pays the fee. + /// vout_index, (numeric) The zero-based output index, before a change output is added. + /// ... + /// ] + /// </summary> + public List<int> subtractFeeFromOutputs { set => Data[nameof(subtractFeeFromOutputs)] = value; } + } +} diff --git a/src/BitcoinLib/Services/RpcServices/RpcService/IRpcService.cs b/src/BitcoinLib/Services/RpcServices/RpcService/IRpcService.cs index d1be8c3..c56bbb0 100644 --- a/src/BitcoinLib/Services/RpcServices/RpcService/IRpcService.cs +++ b/src/BitcoinLib/Services/RpcServices/RpcService/IRpcService.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using BitcoinLib.Requests.AddNode; using BitcoinLib.Requests.CreateRawTransaction; +using BitcoinLib.Requests.FundRawTransaction; using BitcoinLib.Requests.SignRawTransaction; using BitcoinLib.Responses; @@ -85,7 +86,7 @@ public interface IRpcService SignRawTransactionResponse SignRawTransaction(SignRawTransactionRequest signRawTransactionRequest); SignRawTransactionWithKeyResponse SignRawTransactionWithKey(SignRawTransactionWithKeyRequest signRawTransactionWithKeyRequest); SignRawTransactionWithWalletResponse SignRawTransactionWithWallet(SignRawTransactionWithWalletRequest signRawTransactionWithWalletRequest); - GetFundRawTransactionResponse GetFundRawTransaction(string rawTransactionHex); + GetFundRawTransactionResponse GetFundRawTransaction(string rawTransactionHex, FundRawTransactionOptions options = null); #endregion diff --git a/src/BitcoinLib/Services/RpcServices/RpcService/RpcService.cs b/src/BitcoinLib/Services/RpcServices/RpcService/RpcService.cs index 64546e6..e552dc9 100644 --- a/src/BitcoinLib/Services/RpcServices/RpcService/RpcService.cs +++ b/src/BitcoinLib/Services/RpcServices/RpcService/RpcService.cs @@ -1,10 +1,6 @@ // Copyright (c) 2014 - 2016 George Kimionis // See the accompanying file LICENSE for the Software License Aggrement -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; using BitcoinLib.Requests.AddNode; using BitcoinLib.Requests.CreateRawTransaction; using BitcoinLib.Requests.SignRawTransaction; @@ -13,6 +9,12 @@ using BitcoinLib.RPC.Specifications; using BitcoinLib.Services.Coins.Base; using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using BitcoinLib.Requests.FundRawTransaction; +using Newtonsoft.Json; namespace BitcoinLib.Services { @@ -77,22 +79,22 @@ public string CreateRawTransaction(CreateRawTransactionRequest rawTransaction) return _rpcConnector.MakeRequest<string>(RpcMethods.createrawtransaction, rawTransaction.Inputs, rawTransaction.Outputs); } - /// <summary> - /// Lower level CreateRawTransaction RPC request to allow other kinds of output, e.g. - /// "data":"text" for OP_RETURN Null Data for chat on the blockchain. CreateRawTransaction( - /// CreateRawTransactionRequest) only allows for "receiver":amount outputs. - /// </summary> - public string CreateRawTransaction(IList<CreateRawTransactionInput> inputs, - string chatHex, string receiverAddress, decimal receiverAmount) - { - // Must be a dictionary to become an json object, an array will fail on the RPC side - var outputs = new Dictionary<string, string> - { - { "data", chatHex }, - { receiverAddress, receiverAmount.ToString(NumberFormatInfo.InvariantInfo) } - }; - return _rpcConnector.MakeRequest<string>(RpcMethods.createrawtransaction, inputs, outputs); - } + /// <summary> + /// Lower level CreateRawTransaction RPC request to allow other kinds of output, e.g. + /// "data":"text" for OP_RETURN Null Data for chat on the blockchain. CreateRawTransaction( + /// CreateRawTransactionRequest) only allows for "receiver":amount outputs. + /// </summary> + public string CreateRawTransaction(IList<CreateRawTransactionInput> inputs, + string chatHex, string receiverAddress, decimal receiverAmount) + { + // Must be a dictionary to become an json object, an array will fail on the RPC side + var outputs = new Dictionary<string, string> + { + { "data", chatHex }, + { receiverAddress, receiverAmount.ToString(NumberFormatInfo.InvariantInfo) } + }; + return _rpcConnector.MakeRequest<string>(RpcMethods.createrawtransaction, inputs, outputs); + } public DecodeRawTransactionResponse DecodeRawTransaction(string rawTransactionHexString) { @@ -284,7 +286,7 @@ public GetRawMemPoolResponse GetRawMemPool(bool verbose) if (!verbose) { - var rpcResponseAsArray = (JArray) rpcResponse; + var rpcResponseAsArray = (JArray)rpcResponse; foreach (string txId in rpcResponseAsArray) { @@ -294,7 +296,7 @@ public GetRawMemPoolResponse GetRawMemPool(bool verbose) return getRawMemPoolResponse; } - IList<KeyValuePair<string, JToken>> rpcResponseAsKvp = (new EnumerableQuery<KeyValuePair<string, JToken>>(((JObject) (rpcResponse)))).ToList(); + IList<KeyValuePair<string, JToken>> rpcResponseAsKvp = (new EnumerableQuery<KeyValuePair<string, JToken>>(((JObject)(rpcResponse)))).ToList(); IList<JToken> children = JObject.Parse(rpcResponse.ToString()).Children().ToList(); for (var i = 0; i < children.Count(); i++) @@ -589,7 +591,8 @@ public bool LockUnspent(bool unlock, IList<ListUnspentResponse> listUnspentRespo { transactions.Add(new { - txid = listUnspentResponse.TxId, vout = listUnspentResponse.Vout + txid = listUnspentResponse.TxId, + vout = listUnspentResponse.Vout }); } @@ -725,9 +728,10 @@ public SignRawTransactionWithWalletResponse SignRawTransactionWithWallet(SignRaw return _rpcConnector.MakeRequest<SignRawTransactionWithWalletResponse>(RpcMethods.signrawtransactionwithwallet, request.RawTransactionHex, request.Inputs, request.SigHashType); } - public GetFundRawTransactionResponse GetFundRawTransaction(string rawTransactionHex) + public GetFundRawTransactionResponse GetFundRawTransaction(string rawTransactionHex, FundRawTransactionOptions options = null) { - return _rpcConnector.MakeRequest<GetFundRawTransactionResponse>(RpcMethods.fundrawtransaction, rawTransactionHex); + var jData = JObject.Parse(JsonConvert.SerializeObject(options.Data)); + return _rpcConnector.MakeRequest<GetFundRawTransactionResponse>(RpcMethods.fundrawtransaction, rawTransactionHex, jData); } public string Stop()