Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Secret

A trait abstraction over a private key that can sign Dango transactions.

Definition

pub trait Secret: Sized {
    type Private;
    type Public;
    type Signature;
 
    fn new_random() -> Self {
        Self::from_rng(&mut OsRng)
    }
    fn from_rng(rng: &mut impl CryptoRngCore) -> Self;
    fn from_bytes(bytes: Self::Private) -> anyhow::Result<Self>;
    fn from_mnemonic(mnemonic: &Mnemonic, coin_type: usize) -> anyhow::Result<Self>;
 
    fn private_key(&self) -> Self::Private;
    fn public_key(&self) -> Self::Public;
    fn key(&self) -> dango_types::auth::Key;
    fn key_hash(&self) -> grug::Hash256;
 
    fn sign_transaction(
        &self,
        sign_doc: dango_types::auth::SignDoc,
    ) -> anyhow::Result<dango_types::auth::Signature>;
}

new_random is provided; everything else is implementor-defined.

Implementors

Secp256k1

pub struct Secp256k1 { /* k256 SigningKey */ }
  • type Private = [u8; 32]
  • type Public = [u8; 33] (compressed)
  • type Signature = [u8; 64]
  • Signs sign_doc.to_sign_data() (SHA-256 of the canonical encoding) with raw secp256k1.
  • key() returns Key::Secp256k1(public_key).
  • key_hash() is sha256(public_key).

Eip712

pub struct Eip712 {
    inner: Secp256k1,
    pub address: eth_utils::Address,
}
  • Same Private/Public shapes as Secp256k1.
  • type Signature = [u8; 65] (signature + 1-byte recovery id).
  • Signs the SignDoc as EIP-712 typed data with domain { name: "dango", chain_id: EIP155_CHAIN_ID, verifying_contract: <sender as U160> }.
  • key() returns Key::Ethereum(self.address).
  • key_hash() is sha256(Addr::from(self.address).to_string().as_bytes()) — the string form of the address, not the raw bytes. This differs from Secp256k1::key_hash, which hashes the compressed pubkey directly.
  • impl From<Secp256k1> for Eip712 — derives the Ethereum address from the verifying key.

Secp256r1 is not implemented. The source has a TODO for it.

Example

use {
    anyhow::Result,
    bip32::Mnemonic,
    dango_sdk::{DEFAULT_DERIVATION_PATH, Eip712, Secp256k1, Secret},
};
 
fn make() -> Result<()> {
    // From the system RNG.
    let _: Secp256k1 = Secp256k1::new_random();
 
    // From raw bytes.
    let _: Secp256k1 = Secp256k1::from_bytes([0u8; 32])?;
 
    // From a BIP-39 mnemonic at BIP-44 path m/44'/60'/0'/0/0.
    let mnemonic = Mnemonic::new(
        "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
        Default::default(),
    ).map_err(|_| anyhow::anyhow!("bad mnemonic"))?;
    let _: Secp256k1 = Secp256k1::from_mnemonic(&mnemonic, 60)?;
 
    // Ethereum-flavoured.
    let _: Eip712 = Eip712::new_random();
 
    println!("default derivation path: {DEFAULT_DERIVATION_PATH}");
    Ok(())
}

Notes

  • from_mnemonic uses BIP-44 path m/44'/{coin_type}'/0'/0/0 with an empty seed password (consistent with Terra Station and Keplr).
  • Secret is implemented privately for the two concrete types only — external implementors are possible in principle but the SDK does not expose helpers for them.

See also