Skip to main content

farcaster_rs/account/auth/
generate_bearer.rs

1use chrono::{DateTime, Utc};
2use ethers::{
3    prelude::k256::ecdsa::SigningKey,
4    signers::{Signer, Wallet},
5    types::Signature,
6};
7
8use crate::{
9    types::account::auth::bearer::{Bearer, Params, Payload},
10    Farcaster,
11};
12
13use serde_json::{json, Value};
14
15impl Farcaster {
16    /// # Best not to use this function directly
17    /// Instead, use the [Account struct](../types/account/struct.Account.html) methods, such as from_mnemonic, and from_private_key, as that generates these automatically.
18    ///
19    /// However, if you'd really like to use these, go ahead.
20    pub async fn generate_bearer(
21        wallet: &Wallet<SigningKey>,
22        duration_secs: Option<i64>,
23    ) -> Result<Bearer, Box<dyn std::error::Error>> {
24        // Get the current unix timestamp (non-leap seconds since January 1, 1970 00:00:00 UTC)
25        let dt: DateTime<Utc> = Utc::now();
26        let timestamp = dt.timestamp_millis();
27
28        // fill in bearer token parameters
29        let params = Params {
30            timestamp,
31            expires_at: match duration_secs {
32                // with expiration time
33                Some(secs) => Some(timestamp + (secs * 1000)),
34                // without expiration time
35                None => None,
36            },
37        };
38
39        // Initialize a bearer payload using serde_json
40        let payload: Value = json!({
41                "method": "generateToken",
42                "params": params,
43        });
44
45        // Sign the payload using our ethers wallet
46        let signature: Signature = wallet.sign_message(payload.to_string()).await?;
47
48        // Convert our signature to a Vec<u8>
49        let arrayify: Vec<u8> = hex::decode(signature.to_string())?;
50
51        // Encode the signature to a base64 format
52        let base64_signature: String = base64::encode(arrayify);
53
54        // Format our signature
55        let bearer = format!("Bearer eip191:{}", base64_signature);
56
57        let payload = Payload {
58            method: "generateToken".to_string(),
59            params,
60        };
61
62        let bearer = Bearer { bearer, payload };
63
64        Ok(bearer)
65    }
66}