1use crate::query::{CollectData, ResponseData, Variables};
2use anyhow::{anyhow, Context, Result};
3use graphql_client::{GraphQLQuery, Response};
4use reqwest::header::AUTHORIZATION;
5use reqwest::Client;
6
7mod query;
8
9const TW_LOG: &str = "timegraph";
10
11#[derive(Clone, Debug)]
12pub struct TimegraphData {
13 pub collection: String,
15 pub task_id: u64,
17 pub task_cycle: u64,
19 pub target_block_number: u64,
21 pub timechain_block_number: u64,
23 pub shard_id: u64,
25 pub signature: [u8; 64],
27 pub data: Vec<String>,
29}
30
31pub struct Timegraph {
32 client: Client,
33 url: String,
34 ssk: String,
35}
36
37impl Timegraph {
38 pub fn new(url: String, ssk: String) -> Result<Self> {
39 let client = Client::new();
40 Ok(Self { client, url, ssk })
41 }
42
43 pub async fn submit_data(&self, data: TimegraphData) -> Result<()> {
45 let variables = Variables {
46 feed: data.collection,
47 task_id: data.task_id as _,
48 task_cycle: data.task_cycle as _,
49 target_block: data.target_block_number as _,
50 timechain_block: data.timechain_block_number as _,
51 shard_id: data.shard_id as _,
52 signature: hex::encode(data.signature),
53 data: data.data,
54 };
55
56 let request = CollectData::build_query(variables);
57 let response = self
58 .client
59 .post(&self.url)
60 .json(&request)
61 .header(AUTHORIZATION, &self.ssk)
62 .send()
63 .await
64 .map_err(|e| anyhow!("error post to timegraph {e}"))?;
65 let json = response
66 .json::<Response<ResponseData>>()
67 .await
68 .map_err(|e| anyhow!("Failed to parse timegraph response {e}"))?;
69 let data = json.data.context(format!(
70 "timegraph migrate collect status fail: No reponse {:?}",
71 json.errors
72 ))?;
73 log::info!(
74 target: TW_LOG,
75 "timegraph migrate collect status: {:?}",
76 data.collect.status
77 );
78 Ok(())
79 }
80}