Skip to main content

iota_package_dump/
client.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use anyhow::{Context, Result, anyhow};
6use cynic::{Operation, QueryBuilder, http::ReqwestExt};
7use reqwest::IntoUrl;
8use serde::{Serialize, de::DeserializeOwned};
9
10pub(crate) struct Client {
11    inner: reqwest::Client,
12    url: reqwest::Url,
13}
14
15impl Client {
16    /// Create a new GraphQL client, talking to an IOTA GraphQL service at
17    /// `url`.
18    pub(crate) fn new(url: impl IntoUrl) -> Result<Self> {
19        let _ = rustls::crypto::ring::default_provider().install_default();
20        Ok(Self {
21            inner: reqwest::Client::builder()
22                .user_agent(concat!("iota-package-dump/", env!("CARGO_PKG_VERSION")))
23                .build()
24                .context("failed to create GraphQL client")?,
25            url: url.into_url().context("invalid RPC URL")?,
26        })
27    }
28
29    pub(crate) async fn query<Q, V>(&self, query: Operation<Q, V>) -> Result<Q>
30    where
31        V: Serialize,
32        Q: DeserializeOwned + QueryBuilder<V> + 'static,
33    {
34        self.inner
35            .post(self.url.clone())
36            .run_graphql(query)
37            .await
38            .context("failed to send GraphQL query")?
39            .data
40            .ok_or_else(|| anyhow!("empty response to query"))
41    }
42}