| 534 | return true; |
| 535 | } |
| 536 | bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override |
| 537 | { |
| 538 | if (m_derive == DeriveType::HARDENED_RANGED) { |
| 539 | out = ToString(StringType::PUBLIC, /*normalized=*/true); |
| 540 | |
| 541 | return true; |
| 542 | } |
| 543 | // Step backwards to find the last hardened step in the path |
| 544 | int i = (int)m_path.size() - 1; |
| 545 | for (; i >= 0; --i) { |
| 546 | if (m_path.at(i) >> 31) { |
| 547 | break; |
| 548 | } |
| 549 | } |
| 550 | // Either no derivation or all unhardened derivation |
| 551 | if (i == -1) { |
| 552 | out = ToString(); |
| 553 | return true; |
| 554 | } |
| 555 | // Get the path to the last hardened stup |
| 556 | KeyOriginInfo origin; |
| 557 | int k = 0; |
| 558 | for (; k <= i; ++k) { |
| 559 | // Add to the path |
| 560 | origin.path.push_back(m_path.at(k)); |
| 561 | } |
| 562 | // Build the remaining path |
| 563 | KeyPath end_path; |
| 564 | for (; k < (int)m_path.size(); ++k) { |
| 565 | end_path.push_back(m_path.at(k)); |
| 566 | } |
| 567 | // Get the fingerprint |
| 568 | CKeyID id = m_root_extkey.pubkey.GetID(); |
| 569 | std::copy(id.begin(), id.begin() + 4, origin.fingerprint); |
| 570 | |
| 571 | CExtPubKey xpub; |
| 572 | CExtKey lh_xprv; |
| 573 | // If we have the cache, just get the parent xpub |
| 574 | if (cache != nullptr) { |
| 575 | cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub); |
| 576 | } |
| 577 | if (!xpub.pubkey.IsValid()) { |
| 578 | // Cache miss, or nor cache, or need privkey |
| 579 | CExtKey xprv; |
| 580 | if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false; |
| 581 | xpub = lh_xprv.Neuter(); |
| 582 | } |
| 583 | assert(xpub.pubkey.IsValid()); |
| 584 | |
| 585 | // Build the string |
| 586 | std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path); |
| 587 | out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path); |
| 588 | if (IsRange()) { |
| 589 | out += "/*"; |
| 590 | assert(m_derive == DeriveType::UNHARDENED_RANGED); |
| 591 | } |
| 592 | return true; |
| 593 | } |
nothing calls this directly
no test coverage detected