@@ -164,6 +164,9 @@ struct PubkeyProvider
164
164
165
165
/* * Get the descriptor string form including private data (if available in arg). */
166
166
virtual bool ToPrivateString (const SigningProvider& arg, std::string& out) const = 0;
167
+
168
+ /* * Derive a private key, if private data is available in arg. */
169
+ virtual bool GetPrivKey (int pos, const SigningProvider& arg, CKey& key) const = 0;
167
170
};
168
171
169
172
class OriginPubkeyProvider final : public PubkeyProvider
@@ -195,6 +198,10 @@ class OriginPubkeyProvider final : public PubkeyProvider
195
198
ret = " [" + OriginString () + " ]" + std::move (sub);
196
199
return true ;
197
200
}
201
+ bool GetPrivKey (int pos, const SigningProvider& arg, CKey& key) const override
202
+ {
203
+ return m_provider->GetPrivKey (pos, arg, key);
204
+ }
198
205
};
199
206
200
207
/* * An object representing a parsed constant public key in a descriptor. */
@@ -222,6 +229,10 @@ class ConstPubkeyProvider final : public PubkeyProvider
222
229
ret = EncodeSecret (key);
223
230
return true ;
224
231
}
232
+ bool GetPrivKey (int pos, const SigningProvider& arg, CKey& key) const override
233
+ {
234
+ return arg.GetKey (m_pubkey.GetID (), key);
235
+ }
225
236
};
226
237
227
238
enum class DeriveType {
@@ -266,14 +277,9 @@ class BIP32PubkeyProvider final : public PubkeyProvider
266
277
{
267
278
if (key) {
268
279
if (IsHardened ()) {
269
- CExtKey extkey;
270
- if (!GetExtKey (arg, extkey)) return false ;
271
- for (auto entry : m_path) {
272
- extkey.Derive (extkey, entry);
273
- }
274
- if (m_derive == DeriveType::UNHARDENED) extkey.Derive (extkey, pos);
275
- if (m_derive == DeriveType::HARDENED) extkey.Derive (extkey, pos | 0x80000000UL );
276
- *key = extkey.Neuter ().pubkey ;
280
+ CKey priv_key;
281
+ if (!GetPrivKey (pos, arg, priv_key)) return false ;
282
+ *key = priv_key.GetPubKey ();
277
283
} else {
278
284
// TODO: optimize by caching
279
285
CExtPubKey extkey = m_extkey;
@@ -312,6 +318,18 @@ class BIP32PubkeyProvider final : public PubkeyProvider
312
318
}
313
319
return true ;
314
320
}
321
+ bool GetPrivKey (int pos, const SigningProvider& arg, CKey& key) const override
322
+ {
323
+ CExtKey extkey;
324
+ if (!GetExtKey (arg, extkey)) return false ;
325
+ for (auto entry : m_path) {
326
+ extkey.Derive (extkey, entry);
327
+ }
328
+ if (m_derive == DeriveType::UNHARDENED) extkey.Derive (extkey, pos);
329
+ if (m_derive == DeriveType::HARDENED) extkey.Derive (extkey, pos | 0x80000000UL );
330
+ key = extkey.key ;
331
+ return true ;
332
+ }
315
333
};
316
334
317
335
/* * Base class for all Descriptor implementations. */
@@ -462,6 +480,20 @@ class DescriptorImpl : public Descriptor
462
480
Span<const unsigned char > span = MakeSpan (cache);
463
481
return ExpandHelper (pos, DUMMY_SIGNING_PROVIDER, &span, output_scripts, out, nullptr ) && span.size () == 0 ;
464
482
}
483
+
484
+ void ExpandPrivate (int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
485
+ {
486
+ for (const auto & p : m_pubkey_args) {
487
+ CKey key;
488
+ if (!p->GetPrivKey (pos, provider, key)) continue ;
489
+ out.keys .emplace (key.GetPubKey ().GetID (), key);
490
+ }
491
+ if (m_script_arg) {
492
+ FlatSigningProvider subprovider;
493
+ m_script_arg->ExpandPrivate (pos, provider, subprovider);
494
+ out = Merge (out, subprovider);
495
+ }
496
+ }
465
497
};
466
498
467
499
/* * Construct a vector with one element, which is moved into it. */
0 commit comments