Skip to main content

nym_validator_client/signing/
mod.rs

1// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::signing::direct_wallet::DirectSecp256k1HdWalletError;
5use bip32::XPrv;
6use cosmrs::bip32::DerivationPath;
7use cosmrs::crypto::secp256k1::SigningKey;
8use cosmrs::crypto::PublicKey;
9use cosmrs::tendermint::chain;
10use cosmrs::tx::{AccountNumber, SequenceNumber};
11use cosmrs::AccountId;
12
13pub mod direct_wallet;
14pub mod signer;
15pub mod tx_signer;
16
17pub(crate) type Secp256k1Keypair = (SigningKey, PublicKey);
18
19/// Derivation information required to derive a keypair and an address from a mnemonic.
20#[derive(Debug, Clone)]
21pub(crate) struct Secp256k1Derivation {
22    hd_path: DerivationPath,
23    prefix: String,
24}
25
26impl Secp256k1Derivation {
27    pub(crate) fn try_derive_account<S>(
28        &self,
29        seed: S,
30    ) -> Result<AccountData, DirectSecp256k1HdWalletError>
31    where
32        S: AsRef<[u8]>,
33    {
34        let keypair = derive_keypair(seed, &self.hd_path)?;
35
36        // it seems this can only fail if the provided account prefix is invalid
37        let address = keypair
38            .1
39            .account_id(&self.prefix)
40            .map_err(|source| DirectSecp256k1HdWalletError::AccountDerivationError { source })?;
41
42        Ok(AccountData {
43            address,
44            public_key: keypair.1,
45            private_key: keypair.0,
46        })
47    }
48}
49
50pub fn derive_keypair<S>(
51    seed: S,
52    hd_path: &DerivationPath,
53) -> Result<Secp256k1Keypair, DirectSecp256k1HdWalletError>
54where
55    S: AsRef<[u8]>,
56{
57    let extended_private_key = derive_extended_private_key(seed, hd_path)?;
58
59    let private_key: SigningKey = extended_private_key.into();
60    let public_key = private_key.public_key();
61
62    Ok((private_key, public_key))
63}
64
65pub fn derive_extended_private_key<S>(
66    seed: S,
67    hd_path: &DerivationPath,
68) -> Result<XPrv, DirectSecp256k1HdWalletError>
69where
70    S: AsRef<[u8]>,
71{
72    Ok(XPrv::derive_from_path(seed, hd_path)?)
73}
74
75pub struct AccountData {
76    pub address: AccountId,
77
78    pub(crate) public_key: PublicKey,
79
80    pub(crate) private_key: SigningKey,
81}
82
83impl AccountData {
84    pub fn address(&self) -> &AccountId {
85        &self.address
86    }
87
88    pub fn public_key(&self) -> PublicKey {
89        self.public_key
90    }
91
92    pub fn private_key(&self) -> &SigningKey {
93        &self.private_key
94    }
95}
96
97/// Signing information for a single signer that is not included in the transaction.
98#[derive(Debug)]
99pub struct SignerData {
100    pub account_number: AccountNumber,
101    pub sequence: SequenceNumber,
102    pub chain_id: chain::Id,
103}
104
105impl SignerData {
106    pub fn new(
107        account_number: AccountNumber,
108        sequence: SequenceNumber,
109        chain_id: chain::Id,
110    ) -> Self {
111        SignerData {
112            account_number,
113            sequence,
114            chain_id,
115        }
116    }
117
118    pub fn new_from_sequence_response(
119        response: crate::nyxd::cosmwasm_client::types::SequenceResponse,
120        chain_id: chain::Id,
121    ) -> Self {
122        SignerData {
123            account_number: response.account_number,
124            sequence: response.sequence,
125            chain_id,
126        }
127    }
128}