soblendwa 0.1.0

SoblendWA: a blazing fast WhatsApp Web multi-device client library written in Rust. Crafted by Soblend Development Studio.
Documentation
use serde::{Deserialize, Serialize};

use crate::crypto::{self, KeyPair};
use crate::jid::Jid;
use crate::serde_b64;

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SignedPreKey {
    pub id: u32,
    pub key_pair: KeyPair,
    #[serde(with = "serde_b64::array")]
    pub signature: [u8; 64],
}

impl SignedPreKey {
    pub fn generate(identity: &KeyPair, id: u32) -> Self {
        let key_pair = KeyPair::generate();
        let signature = identity.sign(&key_pair.signal_public());
        SignedPreKey { id, key_pair, signature }
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Creds {
    pub noise_key: KeyPair,
    pub pairing_ephemeral_key: KeyPair,
    pub identity_key: KeyPair,
    pub signed_pre_key: SignedPreKey,
    pub registration_id: u32,
    #[serde(with = "serde_b64::array")]
    pub adv_secret_key: [u8; 32],
    pub next_pre_key_id: u32,
    pub first_unuploaded_pre_key_id: u32,
    #[serde(default)]
    pub me: Option<Jid>,
    #[serde(default)]
    pub lid: Option<Jid>,
    #[serde(default)]
    pub push_name: Option<String>,
    #[serde(default, with = "serde_b64::option")]
    pub account: Option<Vec<u8>>,
    #[serde(default)]
    pub platform: Option<String>,
    #[serde(default)]
    pub business_name: Option<String>,
    #[serde(default)]
    pub pairing_code: Option<String>,
    #[serde(default, with = "serde_b64::option")]
    pub routing_info: Option<Vec<u8>>,
    #[serde(default)]
    pub registered: bool,
    #[serde(default)]
    pub wa_version: Option<[u32; 3]>,
    #[serde(default)]
    pub app_state_key_id: Option<String>,
    #[serde(default)]
    pub signed_pre_key_rotated_at: i64,
}

impl Creds {
    pub fn generate() -> Self {
        let identity_key = KeyPair::generate();
        let signed_pre_key = SignedPreKey::generate(&identity_key, 1);
        Creds {
            noise_key: KeyPair::generate(),
            pairing_ephemeral_key: KeyPair::generate(),
            identity_key,
            signed_pre_key,
            registration_id: (crypto::random_u32() & 0x3fff).max(1),
            adv_secret_key: crypto::random_array(),
            next_pre_key_id: 1,
            first_unuploaded_pre_key_id: 1,
            me: None,
            lid: None,
            push_name: None,
            account: None,
            platform: None,
            business_name: None,
            pairing_code: None,
            routing_info: None,
            registered: false,
            wa_version: None,
            app_state_key_id: None,
            signed_pre_key_rotated_at: 0,
        }
    }

    pub fn is_logged_in(&self) -> bool {
        self.me.is_some() && self.account.is_some()
    }
}

impl Default for Creds {
    fn default() -> Self {
        Self::generate()
    }
}