Skip to content
Snippets Groups Projects
Commit c6d37c20 authored by poka's avatar poka Committed by Hugo Trentesaux
Browse files

adapt graphql request to Hasura engine (!26)

* update schema for enums

* update to hasura endpoint

* more macro

* Ignore non_camel_case_types in vscode stage

Are we carring about conventions ?

* 2 macros to rule them all

* example on how to deserialize

* adapt graphql request to Hasura engine
parent 8a97457d
No related branches found
No related tags found
1 merge request!26adapt graphql request to Hasura engine
{
"rust-analyzer.server.extraEnv": null,
"windicss.includeLanguages": {}
"rust-analyzer.diagnostics.disabled": ["non_camel_case_types"],
"windicss.includeLanguages": {},
}
\ No newline at end of file
query IdentityNameByIndex($index: Int!) {
identities(where: { index_eq: $index }) {
identity(where: { index: { _eq: $index } }) {
name
}
}
query NamesByIndexes($indexes: [Int!]!) {
identities(where: {index_in: $indexes}) {
identity(where: { index: { _in: $indexes } }) {
index
name
}
}
query IdentityInfo($index: Int!) {
identities(where: { index_eq: $index }) {
identity(where: { index: { _eq: $index } }) {
name
certIssued(orderBy: expireOn_DESC, where: { isActive_eq: true }) {
certIssued(
orderBy: { expireOn: DESC }
where: { isActive: { _eq: true } }
) {
receiver {
name
}
}
certReceived(orderBy: expireOn_DESC, where: { isActive_eq: true }) {
certReceived(
orderBy: { expireOn: DESC }
where: { isActive: { _eq: true } }
) {
issuer {
name
}
......@@ -27,12 +33,12 @@ query IdentityInfo($index: Int!) {
linkedAccount {
id
}
smithCertIssued(orderBy: createdOn_DESC) {
smithCertIssued(orderBy: { createdOn: DESC }) {
receiver {
name
}
}
smithCertReceived(orderBy: createdOn_DESC) {
smithCertReceived(orderBy: { createdOn: DESC }) {
issuer {
name
}
......@@ -41,13 +47,13 @@ query IdentityInfo($index: Int!) {
}
query IdentityNameByPubkey($pubkey: String!) {
identities(where: { account: { id_eq: $pubkey } }) {
identity(where: { account: { id: { _eq: $pubkey } } }) {
name
}
}
query WasIdentityNameByPubkey($pubkey: String!) {
accountById(id: $pubkey) {
accountByPk(id: $pubkey) {
wasIdentity {
identity {
name
......@@ -57,21 +63,21 @@ query WasIdentityNameByPubkey($pubkey: String!) {
}
query LatestBlock {
blocks(limit: 1, orderBy: height_DESC) {
block(limit: 1, orderBy: { height: DESC }) {
height
hash
}
}
query BlockByNumber($number: Int!) {
blocks(where: { height_eq: $number }) {
block(where: { height: { _eq: $number } }) {
height
hash
}
}
query GenesisHash {
blocks(where: { height_eq: 0 }) {
block(where: { height: { _eq: 0 } }) {
hash
}
}
This diff is collapsed.
This diff is collapsed.
......@@ -288,11 +288,11 @@ pub async fn get_identity(
(
info.cert_issued
.into_iter()
.map(|i| i.receiver.name.to_string())
.map(|i| i.receiver.unwrap().name.to_string())
.collect(),
info.cert_received
.into_iter()
.map(|i| i.issuer.name.to_string())
.map(|i| i.issuer.unwrap().name.to_string())
.collect(),
info.linked_account
.into_iter()
......@@ -300,11 +300,11 @@ pub async fn get_identity(
.collect(),
info.smith_cert_issued
.into_iter()
.map(|i| i.receiver.name.to_string())
.map(|i| i.receiver.unwrap().name.to_string())
.collect(),
info.smith_cert_received
.into_iter()
.map(|i| i.issuer.name.to_string())
.map(|i| i.issuer.unwrap().name.to_string())
.collect(),
)
} else {
......
......@@ -17,9 +17,9 @@ pub const GDEV_DUNITER_ENDPOINTS: [&str; 5] = [
"wss://gdev.pini.fr:443/ws",
];
#[cfg(feature = "gdev")]
pub const GDEV_INDEXER_ENDPOINTS: [&str; 2] = [
"https://subsquid.gdev.coinduf.eu/graphql",
"https://gdev-squid.axiom-team.fr/graphql",
pub const GDEV_INDEXER_ENDPOINTS: [&str; 1] = [
// "https://subsquid.gdev.coinduf.eu/v1/graphql",
"https://gdev-squid.axiom-team.fr/v1/graphql",
];
// data derived from command arguments
......
......@@ -6,7 +6,7 @@ use comfy_table::{ContentArrangement, Table};
use graphql_client::reqwest::post_graphql;
use graphql_client::GraphQLQuery;
use queries::*;
use sp_core::Bytes;
// use sp_core::Bytes;
#[derive(Clone, Debug)]
pub struct Indexer {
......@@ -33,7 +33,7 @@ impl Indexer {
index: index.into(),
})
.await
.identities
.identity
.pop()
.map(|idty| idty.name)
}
......@@ -44,7 +44,7 @@ impl Indexer {
indexes: indexes.iter().map(|i| *i as i64).collect(),
})
.await
.identities
.identity
.into_iter()
.map(|idty| (idty.index as IdtyId, idty.name))
.collect()
......@@ -56,7 +56,7 @@ impl Indexer {
pubkey: pubkey.to_string(),
})
.await
.identities
.identity
.pop()
.map(|idty| idty.name)
}
......@@ -67,26 +67,26 @@ impl Indexer {
pubkey: pubkey.to_string(),
})
.await
.account_by_id
.account_by_pk
.and_then(|mut acc| acc.was_identity.pop())
.map(|idty| idty.identity.name)
.map(|idty| idty.identity.unwrap().name)
}
/// index → info
pub async fn identity_info(&self, index: u32) -> Option<identity_info::IdentityInfoIdentities> {
pub async fn identity_info(&self, index: u32) -> Option<identity_info::IdentityInfoIdentity> {
self.query::<IdentityInfo>(identity_info::Variables {
index: index.into(),
})
.await
.identities
.identity
.pop()
}
/// fetch latest block
pub async fn fetch_latest_block(&self) -> Option<latest_block::LatestBlockBlocks> {
pub async fn fetch_latest_block(&self) -> Option<latest_block::LatestBlockBlock> {
self.query::<LatestBlock>(latest_block::Variables {})
.await
.blocks
.block
.pop()
}
......@@ -94,12 +94,12 @@ impl Indexer {
pub async fn fetch_block_by_number(
&self,
number: BlockNumber,
) -> Option<block_by_number::BlockByNumberBlocks> {
) -> Option<block_by_number::BlockByNumberBlock> {
self.query::<BlockByNumber>(block_by_number::Variables {
number: number.into(),
})
.await
.blocks
.block
.pop()
}
......@@ -114,7 +114,7 @@ impl Indexer {
)
.await
.map_err(|_e| {
// dbg!(_e); // for more info
dbg!(_e); // for more info
GcliError::Indexer(format!("can not connect to indexer {}", &self.gql_url))
})?;
......@@ -127,20 +127,25 @@ impl Indexer {
.ok_or(GcliError::Indexer(
"no field 'data' when getting genesis hash".to_string(),
))?
.blocks
.block
.first()
.ok_or_else(|| GcliError::Indexer("genesis block not yet indexed".to_string()))?
.hash
.clone();
// convert it
Ok(convert_hash(hash))
Ok(convert_hash_bytea(hash))
}
}
/// convert indexer bytes into hash
pub fn convert_hash(hash: Bytes) -> Hash {
let hash = TryInto::<[u8; 32]>::try_into(hash.as_ref()).unwrap();
// pub fn convert_hash(hash: Bytes) -> Hash {
// let hash = TryInto::<[u8; 32]>::try_into(hash.as_ref()).unwrap();
// hash.into()
// }
/// convert indexer bytes into hash
pub fn convert_hash_bytea(hash: queries::Bytea) -> Hash {
let hash = TryInto::<[u8; 32]>::try_into(hash.bytes.as_ref()).unwrap();
hash.into()
}
......@@ -173,7 +178,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
commands::blockchain::fetch_finalized_number_and_hash(&data).await?;
let i_finalized_block = indexer.fetch_block_by_number(d_finalized_n).await;
let (i_finalized_h, i_finalized_n) = if let Some(block) = i_finalized_block {
(Some(convert_hash(block.hash)), Some(block.height))
(Some(convert_hash_bytea(block.hash)), Some(block.height))
} else {
(None, None)
};
......@@ -181,7 +186,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
let (d_latest_n, d_latest_h) =
commands::blockchain::fetch_latest_number_and_hash(&data).await?;
let i_latest_block = indexer.fetch_latest_block().await.expect("no latest block");
let i_latest_h = convert_hash(i_latest_block.hash);
let i_latest_h = convert_hash_bytea(i_latest_block.hash);
let i_latest_n = i_latest_block.height;
fn color(x: bool) -> Color {
......
use graphql_client::GraphQLQuery;
use sp_core::Bytes;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct IdentityNameByIndex;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct IdentityInfo;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct IdentityNameByPubkey;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct WasIdentityNameByPubkey;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct LatestBlock;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct BlockByNumber;
#[derive(GraphQLQuery, Debug)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct GenesisHash;
#[derive(GraphQLQuery, Debug)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct NamesByIndexes;
use serde::{Deserialize, Deserializer};
// implementation of byte array
#[derive(Debug, Clone)]
pub struct Bytea {
pub bytes: Vec<u8>,
}
// Hasura uses lowercase type name
#[allow(non_camel_case_types)]
type bytea = Bytea;
// implement deserializing \\x prefixed hexadecimal
impl<'de> Deserialize<'de> for Bytea {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Deserialize as a string
let hex_string = String::deserialize(deserializer)?;
// Parse the hexadecimal string into a byte vector
let bytes =
hex::decode(hex_string[2..].to_string()).map_err(|e| serde::de::Error::custom(e))?;
Ok(Bytea { bytes })
}
}
// generate code for given graphql query
macro_rules! graphql_query {
($name:ident) => {
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/indexer-schema.json",
query_path = "res/indexer-queries.graphql"
)]
pub struct $name;
};
}
// repeat generation for multiple queries
macro_rules! graphql_query_for {
( $($Name:ident),+ ) => {
$( graphql_query!($Name); )+
};
}
// generate code for all queries in indexer-queries.graphql
graphql_query_for!(
IdentityNameByIndex,
IdentityInfo,
IdentityNameByPubkey,
WasIdentityNameByPubkey,
LatestBlock,
BlockByNumber,
GenesisHash,
NamesByIndexes
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment