pub mod address;
pub mod hot;
pub mod keychain;

#[cfg(feature = "cert")]
pub mod cert;

#[cfg(feature = "mnemonic")]
pub mod mnemonic;

use std::io;

use crate::ids::short;
use serde::{Deserialize, Serialize};

/// ref. https://github.com/ava-labs/avax-js-cli-tools/blob/3e3f714e4227aca83dc3978fcb6a4fd698e09065/address_gen.js
pub const AVAX_ACCOUNT_DERIV_PATH: &str = "m/44'/9000'/0'";
pub const AVAX_ACCOUNT_DERIV_PATH_0: &str = "m/44'/9000'/0'/0/0";

/// ref. https://github.com/ava-labs/avalanche-wallet/blob/v0.3.8/src/js/wallets/MnemonicWallet.ts
pub const AVAX_ACCOUNT_EXT_PUB_KEY_DERIV_PATH: &str = "m/44'/9000'/0'";
pub const ETH_ACCOUNT_EXT_PUB_KEY_DERIV_PATH: &str = "m/44'/60'/0'/0/0";

#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
#[serde(rename_all = "snake_case")]
pub struct ChainAddresses {
    pub x_address: String,
    pub p_address: String,
    pub c_address: String,
}

/// Key interface that "only" allows "read" operations.
pub trait ReadOnly {
    /// Implements "crypto.PublicKeySECP256K1R.Address()" and "formatting.FormatAddress".
    /// "human readable part" (hrp) must be valid output from "constants.GetHRP(networkID)".
    /// ref. https://pkg.go.dev/github.com/ava-labs/avalanchego/utils/constants
    fn get_address(&self, chain_id_alias: &str, network_id: u32) -> io::Result<String>;
    fn get_short_address(&self) -> short::Id;
    fn get_eth_address(&self) -> String;
}

/// The length of recoverable ECDSA signature.
/// "github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa.SignCompact" outputs
/// 65-byte signature -- see "compactSigSize"
/// ref. "avalanchego/utils/crypto.PrivateKeySECP256K1R.SignHash"
/// ref. https://pkg.go.dev/github.com/ava-labs/avalanchego/utils/crypto#SECP256K1RSigLen
pub const ECDSA_RECOVERABLE_SIG_LEN: usize = 65;

/// Key interface that "only" allows "sign" operations.
pub trait SignOnly {
    /// Signs the message with the ECDSA secret key and appends the recovery code
    /// to the signature.
    /// ref. https://github.com/rust-bitcoin/rust-secp256k1/blob/master/src/ecdsa/recovery.rs
    /// ref. https://docs.rs/secp256k1/latest/secp256k1/struct.SecretKey.html#method.sign_ecdsa
    /// ref. https://docs.rs/secp256k1/latest/secp256k1/struct.Message.html
    /// ref. https://pkg.go.dev/github.com/ava-labs/avalanchego/utils/crypto#PrivateKeyED25519.SignHash
    fn sign_ecdsa_recoverable(&self, msg: &[u8]) -> Vec<u8>;
}
