Skip to content

Using KeyMap and DescriptorSecretKey for signing transactions #495

@evd0kim

Description

@evd0kim

From an outsider point of view KeyMap looks like interesting way to handle keys after importing descriptor.

Let's say for example we have such descriptor where we supply tprv which will be imported into KeyMap

"wsh(t:or_c(pk(02a7d30ac6b0cd55b6868f5a65aff1dbdaa18f4315fe04de809fffb2899340ae0f),v:multi(1,[255f0d9b]tprv8ZgxMBicQKsPerMTN7nhwCpqaAEPkaBCDeE8c9ekAY1xhPmF3HM9r3oz33V8JTwsJYp9FYLDQumLzNssLo6UNMNesVwPP1KcgA5atrSqU2w/84'/1'/1/0/0,02f17cce1778c101e3b0ac5c76997af3752b0a221b1ebffc23af679328f3f5d6fc,02350b5a9a12df96579d150f3f751de416e58a67f2ba9bc99f6964b7a48a79042b)))"

We could use KeyMap later in similar loop

        for (public, private) in &keys {
                  // ... doing something with keys
        }

The problem though is that public and private are DescriptorPublicKey and DescriptorSecretKey objects do not really contain convenient API even for extracting keys and using them in signing. I have a code example and honestly I am not entirely sure I didn't something wrong. Besides It doesn't actually work and I think the problem is that there is just wrong key in &prv.xkey.private_key.

        for (pk, prv) in &self.keys {
            match prv {
                DescriptorSecretKey::Single(prv) => {
                    let sig = self.secp.sign_ecdsa(&msg, &prv.key.inner);
                    let public = &prv.key.inner.public_key(&self.secp);
                    assert!(self.secp.verify_ecdsa(&msg, &sig, public).is_ok());
                    psbt.inputs[0].partial_sigs.insert(
                        public.to_public_key(),
                        bitcoin::EcdsaSig {
                            sig,
                            hash_ty: hash_ty,
                        },
                    );
                },
                DescriptorSecretKey::XPrv(prv) => {
                    let sig = self.secp.sign_ecdsa(&msg, &prv.xkey.private_key);
                    let public = &prv.xkey.private_key.public_key(&self.secp);
                    println!("{}", &public);
                    assert!(self.secp.verify_ecdsa(&msg, &sig, public).is_ok());
                    psbt.inputs[0].partial_sigs.insert(
                        public.to_public_key(),
                        bitcoin::EcdsaSig {
                            sig,
                            hash_ty: hash_ty,
                        },
                    );
                },
            };
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions