dimo_rust_sdk/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
pub mod environments;
pub mod graphql;
pub mod rest;
pub mod utils;

pub use serde_json::Value;
pub use utils::credentials::get_credentials;
use environments::dimo_environment;
use graphql::{Identity, Telemetry};
use rest::{
    attestation::AttestationClient,
    auth::{AccessToken, AuthClient},
    devicedefinitions::DeviceDefinitions,
    devices::Devices,
    tokenexchange::TokenExchange,
    trips::Trips,
    valuations::Valuations,
    vehiclesignaldecoding::VehicleSignalDecoding,
};

#[derive(Clone, Copy)]
pub enum Environment {
    Production,
    Dev,
}

pub struct DIMO {
    pub attestation: AttestationClient,
    pub auth: AuthClient,
    pub devicedefinitions: DeviceDefinitions,
    pub devices: Devices,
    pub tokenexchange: TokenExchange,
    pub trips: Trips,
    pub valuations: Valuations,
    pub vehiclesignaldecoding: VehicleSignalDecoding,
    pub identity: Identity,
    pub telemetry: Telemetry,
}

impl DIMO {
    pub fn new(env: Environment) -> Self {
        let routes = match env {
            Environment::Production => dimo_environment::PRODUCTION.routes,
            Environment::Dev => dimo_environment::DEV.routes,
        };
        let constants = match env {
            Environment::Production => dimo_environment::PRODUCTION.constants,
            Environment::Dev => dimo_environment::DEV.constants,
        };

        Self {
            attestation: AttestationClient::new(routes.attestation.to_string()),
            auth: AuthClient::new(routes.auth.to_string()),
            devicedefinitions: DeviceDefinitions::new(routes.device_definitions),
            devices: Devices::new(routes.devices),
            tokenexchange: TokenExchange::new(routes.token_exchange, constants.nft_address),
            trips: Trips::new(routes.trips),
            valuations: Valuations::new(routes.valuations),
            vehiclesignaldecoding: VehicleSignalDecoding::new(routes.vehicle_signal_decoding),
            identity: Identity::new(routes.identity),
            telemetry: Telemetry::new(routes.telemetry),
        }
    }

    pub async fn get_token(&mut self) -> Result<AccessToken, Box<dyn std::error::Error>> {
        let creds = get_credentials()?;

        let challenge = self
            .auth
            .generate_challenge(&creds.client_id, &creds.domain)
            .await
            .expect("error generating challenge");

        let state = challenge.state;
        let challenge = challenge.challenge;
        let signature = self
            .auth
            .sign_challenge(&challenge, &creds.private_key)
            .expect("error signing challenge");

        let token = self
            .auth
            .submit_challenge(&creds.client_id, &creds.domain, &state, &signature)
            .await
            .expect("error submitting challenge");

        Ok(token)
    }
}