Skip to content

Commit a4b06fb

Browse files
committed
Create wallet RPCs for PSBT
walletprocesspsbt takes a PSBT format transaction, updates the PSBT with any inputs related to this wallet, signs, and finalizes the transaction. There is also an option to not sign and just update. walletcreatefundedpsbt creates a PSBT from user provided data in the same form as createrawtransaction. It also funds the transaction and takes an options argument in the same form as fundrawtransaction. The resulting PSBT is blank with no input or output data filled in.
1 parent c27fe41 commit a4b06fb

File tree

8 files changed

+385
-17
lines changed

8 files changed

+385
-17
lines changed

src/core_io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
2626
uint256 ParseHashStr(const std::string&, const std::string& strName);
2727
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
2828
bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
29+
int ParseSighashString(const UniValue& sighash);
2930

3031
// core_write.cpp
3132
UniValue ValueFromAmount(const CAmount& amount);

src/core_read.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,26 @@ std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strN
197197
throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
198198
return ParseHex(strHex);
199199
}
200+
201+
int ParseSighashString(const UniValue& sighash)
202+
{
203+
int hash_type = SIGHASH_ALL;
204+
if (!sighash.isNull()) {
205+
static std::map<std::string, int> map_sighash_values = {
206+
{std::string("ALL"), int(SIGHASH_ALL)},
207+
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
208+
{std::string("NONE"), int(SIGHASH_NONE)},
209+
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
210+
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
211+
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
212+
};
213+
std::string strHashType = sighash.get_str();
214+
const auto& it = map_sighash_values.find(strHashType);
215+
if (it != map_sighash_values.end()) {
216+
hash_type = it->second;
217+
} else {
218+
throw std::runtime_error(strHashType + " is not a valid sighash parameter.");
219+
}
220+
}
221+
return hash_type;
222+
}

src/rpc/client.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ static const CRPCConvertParam vRPCConvertParams[] =
109109
{ "combinerawtransaction", 0, "txs" },
110110
{ "fundrawtransaction", 1, "options" },
111111
{ "fundrawtransaction", 2, "iswitness" },
112+
{ "walletcreatefundedpsbt", 0, "inputs" },
113+
{ "walletcreatefundedpsbt", 1, "outputs" },
114+
{ "walletcreatefundedpsbt", 2, "locktime" },
115+
{ "walletcreatefundedpsbt", 3, "replaceable" },
116+
{ "walletcreatefundedpsbt", 4, "options" },
117+
{ "walletcreatefundedpsbt", 5, "bip32derivs" },
118+
{ "walletprocesspsbt", 1, "sign" },
119+
{ "walletprocesspsbt", 3, "bip32derivs" },
112120
{ "createpsbt", 0, "inputs" },
113121
{ "createpsbt", 1, "outputs" },
114122
{ "createpsbt", 2, "locktime" },

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -840,23 +840,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
840840
}
841841
}
842842

843-
int nHashType = SIGHASH_ALL;
844-
if (!hashType.isNull()) {
845-
static std::map<std::string, int> mapSigHashValues = {
846-
{std::string("ALL"), int(SIGHASH_ALL)},
847-
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
848-
{std::string("NONE"), int(SIGHASH_NONE)},
849-
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
850-
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
851-
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
852-
};
853-
std::string strHashType = hashType.get_str();
854-
if (mapSigHashValues.count(strHashType)) {
855-
nHashType = mapSigHashValues[strHashType];
856-
} else {
857-
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
858-
}
859-
}
843+
int nHashType = ParseSighashString(hashType);
860844

861845
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
862846

src/script/sign.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,13 @@ void PSBTOutput::Merge(const PSBTOutput& output)
614614
if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script;
615615
if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script;
616616
}
617+
618+
bool PublicOnlySigningProvider::GetCScript(const CScriptID &scriptid, CScript& script) const
619+
{
620+
return m_provider->GetCScript(scriptid, script);
621+
}
622+
623+
bool PublicOnlySigningProvider::GetPubKey(const CKeyID &address, CPubKey& pubkey) const
624+
{
625+
return m_provider->GetPubKey(address, pubkey);
626+
}

src/script/sign.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ class SigningProvider
3232

3333
extern const SigningProvider& DUMMY_SIGNING_PROVIDER;
3434

35+
class PublicOnlySigningProvider : public SigningProvider
36+
{
37+
private:
38+
const SigningProvider* m_provider;
39+
40+
public:
41+
PublicOnlySigningProvider(const SigningProvider* provider) : m_provider(provider) {}
42+
bool GetCScript(const CScriptID &scriptid, CScript& script) const;
43+
bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const;
44+
};
45+
3546
/** Interface for signature creators. */
3647
class BaseSignatureCreator {
3748
public:

0 commit comments

Comments
 (0)