| 485 | } |
| 486 | |
| 487 | RPCHelpMan getbalances() |
| 488 | { |
| 489 | return RPCHelpMan{ |
| 490 | "getbalances", |
| 491 | "Returns an object with all balances in " + CURRENCY_UNIT + ".\n", |
| 492 | {}, |
| 493 | RPCResult{ |
| 494 | RPCResult::Type::OBJ, "", "", |
| 495 | { |
| 496 | {RPCResult::Type::OBJ, "mine", "balances from outputs that the wallet can sign", |
| 497 | { |
| 498 | {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"}, |
| 499 | {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"}, |
| 500 | {RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"}, |
| 501 | {RPCResult::Type::STR_AMOUNT, "used", /*optional=*/true, "(only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)"}, |
| 502 | }}, |
| 503 | {RPCResult::Type::OBJ, "watchonly", /*optional=*/true, "watchonly balances (not present if wallet does not watch anything)", |
| 504 | { |
| 505 | {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"}, |
| 506 | {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"}, |
| 507 | {RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"}, |
| 508 | }}, |
| 509 | } |
| 510 | }, |
| 511 | RPCExamples{ |
| 512 | HelpExampleCli("getbalances", "") + |
| 513 | HelpExampleRpc("getbalances", "")}, |
| 514 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 515 | { |
| 516 | const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request); |
| 517 | if (!rpc_wallet) return NullUniValue; |
| 518 | const CWallet& wallet = *rpc_wallet; |
| 519 | |
| 520 | // Make sure the results are valid at least up to the most recent block |
| 521 | // the user could have gotten from another RPC command prior to now |
| 522 | wallet.BlockUntilSyncedToCurrentChain(); |
| 523 | |
| 524 | LOCK(wallet.cs_wallet); |
| 525 | |
| 526 | const auto bal = GetBalance(wallet); |
| 527 | UniValue balances{UniValue::VOBJ}; |
| 528 | { |
| 529 | UniValue balances_mine{UniValue::VOBJ}; |
| 530 | balances_mine.pushKV("trusted", AmountMapToUniv(bal.m_mine_trusted, "")); |
| 531 | balances_mine.pushKV("untrusted_pending", AmountMapToUniv(bal.m_mine_untrusted_pending, "")); |
| 532 | balances_mine.pushKV("immature", AmountMapToUniv(bal.m_mine_immature, "")); |
| 533 | if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) { |
| 534 | // If the AVOID_REUSE flag is set, bal has been set to just the un-reused address balance. Get |
| 535 | // the total balance, and then subtract bal to get the reused address balance. |
| 536 | const auto full_bal = GetBalance(wallet, 0, false); |
| 537 | balances_mine.pushKV("used", AmountMapToUniv(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending, "")); |
| 538 | } |
| 539 | balances.pushKV("mine", balances_mine); |
| 540 | } |
| 541 | auto spk_man = wallet.GetLegacyScriptPubKeyMan(); |
| 542 | if (spk_man && spk_man->HaveWatchOnly()) { |
| 543 | UniValue balances_watchonly{UniValue::VOBJ}; |
| 544 | balances_watchonly.pushKV("trusted", AmountMapToUniv(bal.m_watchonly_trusted, "")); |
nothing calls this directly
no test coverage detected