Skip to content

Commit b5ff77a

Browse files
committed
feat: add dips graphql
1 parent c72b379 commit b5ff77a

File tree

5 files changed

+201
-4
lines changed

5 files changed

+201
-4
lines changed

service/src/database/dips.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::collections::HashMap;
5+
6+
use axum::async_trait;
7+
8+
use crate::routes::dips::Agreement;
9+
10+
#[async_trait]
11+
pub trait AgreementStore: Sync + Send {
12+
async fn get_by_signature(&self, signature: String) -> anyhow::Result<Option<Agreement>>;
13+
async fn create_agreement(
14+
&self,
15+
signature: String,
16+
data: Agreement,
17+
) -> anyhow::Result<Agreement>;
18+
async fn cancel_agreement(&self, signature: String) -> anyhow::Result<String>;
19+
}
20+
21+
pub struct InMemoryAgreementStore {
22+
pub data: tokio::sync::RwLock<HashMap<String, Agreement>>,
23+
}
24+
25+
#[async_trait]
26+
impl AgreementStore for InMemoryAgreementStore {
27+
async fn get_by_signature(&self, signature: String) -> anyhow::Result<Option<Agreement>> {
28+
Ok(self.data.try_read()?.get(&signature).cloned())
29+
}
30+
async fn create_agreement(
31+
&self,
32+
signature: String,
33+
agreement: Agreement,
34+
) -> anyhow::Result<Agreement> {
35+
self.data.try_write()?.insert(signature, agreement.clone());
36+
37+
Ok(agreement)
38+
}
39+
async fn cancel_agreement(&self, signature: String) -> anyhow::Result<String> {
40+
self.data.try_write()?.remove(&signature);
41+
42+
Ok(signature.clone())
43+
}
44+
}

service/src/database.rs renamed to service/src/database/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
pub mod dips;
5+
46
use std::time::Duration;
57
use std::{collections::HashSet, str::FromStr};
68

service/src/routes/dips.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::{str::FromStr, sync::Arc};
5+
6+
use anyhow::bail;
7+
use async_graphql::{Context, FieldResult, Object, SimpleObject};
8+
9+
use crate::database::dips::AgreementStore;
10+
11+
pub enum NetworkProtocol {
12+
ArbitrumMainnet,
13+
}
14+
15+
impl FromStr for NetworkProtocol {
16+
type Err = anyhow::Error;
17+
18+
fn from_str(s: &str) -> Result<Self, Self::Err> {
19+
let p = match s {
20+
"arbitrum-mainnet" => NetworkProtocol::ArbitrumMainnet,
21+
_ => bail!("unknown network protocol"),
22+
};
23+
24+
Ok(p)
25+
}
26+
}
27+
28+
#[derive(SimpleObject, Debug, Clone)]
29+
pub struct Agreement {
30+
signature: String,
31+
data: String,
32+
protocol_network: String,
33+
}
34+
35+
#[derive(SimpleObject, Debug, Clone)]
36+
pub struct Price {
37+
price_per_block: String,
38+
chain_id: String,
39+
protocol_network: String,
40+
}
41+
42+
#[derive(Debug)]
43+
pub struct AgreementQuery {}
44+
45+
#[Object]
46+
impl AgreementQuery {
47+
pub async fn get_agreement<'a>(
48+
&self,
49+
ctx: &'a Context<'_>,
50+
signature: String,
51+
) -> FieldResult<Option<Agreement>> {
52+
let store: &Arc<dyn AgreementStore> = ctx.data()?;
53+
54+
store
55+
.get_by_signature(signature)
56+
.await
57+
.map_err(async_graphql::Error::from)
58+
}
59+
60+
pub async fn get_price<'a>(
61+
&self,
62+
ctx: &'a Context<'_>,
63+
protocol_network: String,
64+
chain_id: String,
65+
) -> FieldResult<Option<Price>> {
66+
let prices: &Vec<Price> = ctx.data()?;
67+
68+
let p = prices
69+
.iter()
70+
.find(|p| p.protocol_network.eq(&protocol_network) && p.chain_id.eq(&chain_id));
71+
72+
Ok(p.cloned())
73+
}
74+
75+
pub async fn get_all_prices<'a>(&self, ctx: &'a Context<'_>) -> FieldResult<Vec<Price>> {
76+
let prices: &Vec<Price> = ctx.data()?;
77+
78+
Ok(prices.clone())
79+
}
80+
}
81+
82+
#[derive(Debug)]
83+
pub struct AgreementMutation {}
84+
85+
#[Object]
86+
impl AgreementMutation {
87+
pub async fn create_agreement<'a>(
88+
&self,
89+
ctx: &'a Context<'_>,
90+
signature: String,
91+
data: String,
92+
protocol_network: String,
93+
) -> FieldResult<Agreement> {
94+
let store: &Arc<dyn AgreementStore> = ctx.data()?;
95+
96+
store
97+
.create_agreement(
98+
signature.clone(),
99+
Agreement {
100+
signature,
101+
data,
102+
protocol_network,
103+
},
104+
)
105+
.await
106+
.map_err(async_graphql::Error::from)
107+
}
108+
109+
pub async fn cancel_agreement<'a>(
110+
&self,
111+
ctx: &'a Context<'_>,
112+
signature: String,
113+
) -> FieldResult<String> {
114+
let store: &Arc<dyn AgreementStore> = ctx.data()?;
115+
116+
store
117+
.cancel_agreement(signature)
118+
.await
119+
.map_err(async_graphql::Error::from)
120+
}
121+
}

service/src/routes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
pub mod cost;
5+
pub mod dips;
56
mod status;
67

78
pub use status::status;

service/src/service.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::sync::Arc;
54
use std::time::Duration;
5+
use std::{collections::HashMap, sync::Arc};
66

77
use super::{config::Config, error::SubgraphServiceError, routes};
88
use anyhow::anyhow;
9-
use axum::{async_trait, routing::post, Json, Router};
9+
use async_graphql::{EmptySubscription, Schema};
10+
use async_graphql_axum::GraphQL;
11+
use axum::{
12+
async_trait,
13+
routing::{post, post_service},
14+
Json, Router,
15+
};
1016
use indexer_common::indexer_service::http::{
1117
AttestationOutput, IndexerServiceImpl, IndexerServiceResponse,
1218
};
@@ -15,8 +21,16 @@ use reqwest::Url;
1521
use serde_json::{json, Value};
1622
use sqlx::PgPool;
1723
use thegraph_core::DeploymentId;
18-
19-
use crate::{cli::Cli, database};
24+
use tokio::sync::RwLock;
25+
26+
use crate::{
27+
cli::Cli,
28+
database::{
29+
self,
30+
dips::{AgreementStore, InMemoryAgreementStore},
31+
},
32+
routes::dips::Price,
33+
};
2034

2135
use clap::Parser;
2236
use indexer_common::indexer_service::http::{
@@ -174,6 +188,20 @@ pub async fn run() -> anyhow::Result<()> {
174188
.clone(),
175189
});
176190

191+
let agreement_store: Arc<dyn AgreementStore> = Arc::new(InMemoryAgreementStore {
192+
data: RwLock::new(HashMap::new()),
193+
});
194+
let prices: Vec<Price> = vec![];
195+
196+
let schema = Schema::build(
197+
routes::dips::AgreementQuery {},
198+
routes::dips::AgreementMutation {},
199+
EmptySubscription,
200+
)
201+
.data(agreement_store)
202+
.data(prices)
203+
.finish();
204+
177205
IndexerService::run(IndexerServiceOptions {
178206
release,
179207
config: config.0.clone(),
@@ -182,6 +210,7 @@ pub async fn run() -> anyhow::Result<()> {
182210
extra_routes: Router::new()
183211
.route("/cost", post(routes::cost::cost))
184212
.route("/status", post(routes::status))
213+
.route("/dips", post_service(GraphQL::new(schema)))
185214
.with_state(state),
186215
})
187216
.await

0 commit comments

Comments
 (0)