| 1379 | } |
| 1380 | |
| 1381 | std::vector<CScript> |
| 1382 | EvalDescriptorStringOrObject(const UniValue &scanobject, |
| 1383 | FlatSigningProvider &provider) { |
| 1384 | std::string desc_str; |
| 1385 | std::pair<int64_t, int64_t> range = {0, 1000}; |
| 1386 | if (scanobject.isStr()) { |
| 1387 | desc_str = scanobject.get_str(); |
| 1388 | } else if (scanobject.isObject()) { |
| 1389 | const UniValue &desc_uni{scanobject.find_value("desc")}; |
| 1390 | if (desc_uni.isNull()) { |
| 1391 | throw JSONRPCError( |
| 1392 | RPC_INVALID_PARAMETER, |
| 1393 | "Descriptor needs to be provided in scan object"); |
| 1394 | } |
| 1395 | desc_str = desc_uni.get_str(); |
| 1396 | const UniValue &range_uni{scanobject.find_value("range")}; |
| 1397 | if (!range_uni.isNull()) { |
| 1398 | range = ParseDescriptorRange(range_uni); |
| 1399 | } |
| 1400 | } else { |
| 1401 | throw JSONRPCError( |
| 1402 | RPC_INVALID_PARAMETER, |
| 1403 | "Scan object needs to be either a string or an object"); |
| 1404 | } |
| 1405 | |
| 1406 | std::string error; |
| 1407 | auto desc = Parse(desc_str, provider, error); |
| 1408 | if (!desc) { |
| 1409 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); |
| 1410 | } |
| 1411 | if (!desc->IsRange()) { |
| 1412 | range.first = 0; |
| 1413 | range.second = 0; |
| 1414 | } |
| 1415 | std::vector<CScript> ret; |
| 1416 | for (int i = range.first; i <= range.second; ++i) { |
| 1417 | std::vector<CScript> scripts; |
| 1418 | if (!desc->Expand(i, provider, scripts, provider)) { |
| 1419 | throw JSONRPCError( |
| 1420 | RPC_INVALID_ADDRESS_OR_KEY, |
| 1421 | strprintf("Cannot derive script without private keys: '%s'", |
| 1422 | desc_str)); |
| 1423 | } |
| 1424 | std::move(scripts.begin(), scripts.end(), std::back_inserter(ret)); |
| 1425 | } |
| 1426 | return ret; |
| 1427 | } |
| 1428 | |
| 1429 | UniValue GetServicesNames(ServiceFlags services) { |
| 1430 | UniValue servicesNames(UniValue::VARR); |