Skip to content
This repository was archived by the owner on Jan 2, 2023. It is now read-only.
480 changes: 279 additions & 201 deletions Cargo.lock

Large diffs are not rendered by default.

123 changes: 62 additions & 61 deletions enclave-runtime/Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion litentry/core/assertion-build/src/a3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn build(guild_id: ParameterString, handler: ParameterString) -> Result<()>
let mut client = DiscordLitentryClient::new();
match client.check_id_hubber(guild_id.into_inner(), handler.into_inner()) {
Err(e) => {
log::error!("error build assertion2: {:?}", e);
log::error!("error build assertion3: {:?}", e);
Err(Error::Assertion3Error(format!("{:?}", e)))
},
Ok(_response) => {
Expand Down
134 changes: 134 additions & 0 deletions litentry/core/assertion-build/src/a4_7_12.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright 2020-2022 Litentry Technologies GmbH.
// This file is part of Litentry.
//
// Litentry is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Litentry is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Litentry. If not, see <https://www.gnu.org/licenses/>.

#[cfg(all(feature = "std", feature = "sgx"))]
compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the same time");

#[cfg(all(not(feature = "std"), feature = "sgx"))]
extern crate sgx_tstd as std;

use crate::{Error, Result};
use std::{
str::from_utf8,
string::{String, ToString},
vec,
vec::Vec,
};

use lc_stf_task_sender::MaxIdentityLength;
use litentry_primitives::{
EvmNetwork, Identity, IdentityHandle, IdentityWebType, SubstrateNetwork, Web3Network,
};
use sp_runtime::BoundedVec;

use lc_data_providers::graphql::{
GraphQLClient, VerifiedCredentialsIsHodlerIn, VerifiedCredentialsNetwork,
};

// const LIT_TOKEN_ADDRESS: &str = "0xb59490aB09A0f526Cc7305822aC65f2Ab12f9723";

pub fn build(
identities: BoundedVec<Identity, MaxIdentityLength>,
from_date: String,
token_address: String,
mini_balance: f64,
) -> Result<()> {
let mut client = GraphQLClient::new();

let mut addresses: Vec<String> = vec![];
// let from_date = format!("{:?}", Utc::now());
let mut network = VerifiedCredentialsNetwork::Litentry;
// let token_address = LIT_TOKEN_ADDRESS.to_string();
// let mini_balance = 0f64;

for identity in identities {
if let IdentityWebType::Web3(web3_type) = identity.web_type {
match identity.handle {
IdentityHandle::Address20(addr) =>
addresses.push(from_utf8(&addr).unwrap().to_string()),
IdentityHandle::Address32(addr) =>
addresses.push(from_utf8(&addr).unwrap().to_string()),
IdentityHandle::String(addr) =>
addresses.push(from_utf8(&addr).unwrap().to_string()),
}

match web3_type {
Web3Network::Substrate(SubstrateNetwork::Polkadot) =>
network = VerifiedCredentialsNetwork::Polkadot,
Web3Network::Substrate(SubstrateNetwork::Kusama) =>
network = VerifiedCredentialsNetwork::Kusama,
Web3Network::Substrate(SubstrateNetwork::Litentry) =>
network = VerifiedCredentialsNetwork::Litentry,
Web3Network::Substrate(SubstrateNetwork::Litmus) =>
network = VerifiedCredentialsNetwork::Litmus,
Web3Network::Evm(EvmNetwork::Ethereum) =>
network = VerifiedCredentialsNetwork::Ethereum,
_ =>
return Err(Error::Assertion4_7_12Error(
"network type not implemented".to_string(),
)),
}
};
}

let credentials = VerifiedCredentialsIsHodlerIn {
addresses,
from_date,
network,
token_address,
mini_balance,
};

let is_hodler_out = client.verified_credentials_is_hodler(credentials);

if let Ok(hodler_out) = is_hodler_out {
let mut counter = 0;
for hodler in hodler_out.verified_credentials_is_hodler {
if hodler.is_hodler {
counter += 1;
}
}
if counter > 0 {
// TODO: generate VC
} else {
return Err(Error::Assertion4_7_12Error("no valid response".to_string()))
}
} else {
return Err(Error::Assertion4_7_12Error("no valid response".to_string()))
}

Ok(())
}

#[cfg(test)]
mod tests {
use crate::a4_7_12::build;
use frame_support::BoundedVec;
use log;

#[test]
fn assertion4_build_works() {
// let guildid: u64 = 919848390156767232;
// let guild_id_vec: Vec<u8> = format!("{}", guildid).as_bytes().to_vec();
// let handler_vec: Vec<u8> = "ericzhang.eth#0114".to_string().as_bytes().to_vec();

// let guild_id = BoundedVec::try_from(guild_id_vec).unwrap();
// let handler = BoundedVec::try_from(handler_vec).unwrap();

// let _ = build(guild_id, handler);
// log::info!("assertion3 test");
}
}
4 changes: 4 additions & 0 deletions litentry/core/assertion-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use std::{fmt::Debug, string::String};
pub mod a1;
pub mod a2;
pub mod a3;
pub mod a4_7_12;
pub mod a5;
pub mod a6;

Expand All @@ -53,6 +54,9 @@ pub enum Error {
#[error("Assertion3 error: {0}")]
Assertion3Error(String),

#[error("Assertion4/7/12 error: {0}")]
Assertion4_7_12Error(String),

#[error("Assertion5 error: {0}")]
Assertion5Error(String),

Expand Down
2 changes: 1 addition & 1 deletion litentry/core/data-providers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ litentry-primitives = { path = "../../primitives", default-features = false }
lc-mock-server = { path = "../mock-server" }
httpmock = "0.6"
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.29", default-features = false }

chrono = { version = "0.4.23" }

[features]
default = ["std"]
Expand Down
186 changes: 186 additions & 0 deletions litentry/core/data-providers/src/graphql.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright 2020-2022 Litentry Technologies GmbH.
// This file is part of Litentry.
//
// Litentry is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Litentry is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Litentry. If not, see <https://www.gnu.org/licenses/>.

#[cfg(all(not(feature = "std"), feature = "sgx"))]
use crate::sgx_reexport_prelude::*;

use crate::{
base_url::{GRAPHQL_AUTH_KEY, GRAPHQL_URL},
build_client, Error, HttpError,
};
use http::header::{AUTHORIZATION, CONNECTION};
use http_req::response::Headers;
use itc_rest_client::{
http_client::{DefaultSend, HttpClient},
rest_client::RestClient,
RestGet, RestPath,
};
use serde::{Deserialize, Serialize};
use std::{
default::Default,
format, str,
string::{String, ToString},
vec,
vec::Vec,
};

pub struct GraphQLClient {
client: RestClient<HttpClient<DefaultSend>>,
}

impl Default for GraphQLClient {
fn default() -> Self {
Self::new()
}
}

pub enum VerifiedCredentialsNetwork {
Litentry,
Litmus,
Polkadot,
Kusama,
Khala,
Ethereum,
}
pub struct VerifiedCredentialsIsHodlerIn {
pub addresses: Vec<String>,
pub from_date: String,
pub network: VerifiedCredentialsNetwork,
pub token_address: String,
pub mini_balance: f64,
}

impl VerifiedCredentialsIsHodlerIn {
pub fn new(
addresses: Vec<String>,
from_date: String,
network: VerifiedCredentialsNetwork,
token_address: String,
mini_balance: f64,
) -> Self {
VerifiedCredentialsIsHodlerIn { addresses, from_date, network, token_address, mini_balance }
}

pub fn conv_to_string(&self) -> String {
let mut flat = "addresses:[".to_string();
for addr in self.addresses.iter() {
flat += &format!("\"{}\",", addr);
}
flat += "],";
flat += &format!("fromDate:\"{}\",", self.from_date.clone());
match &self.network {
VerifiedCredentialsNetwork::Litentry => flat += "network:litentry",
VerifiedCredentialsNetwork::Litmus => flat += "network:litmus",
VerifiedCredentialsNetwork::Polkadot => flat += "network:polkadot",
VerifiedCredentialsNetwork::Kusama => flat += "network:kusama",
VerifiedCredentialsNetwork::Khala => flat += "network:khala",
VerifiedCredentialsNetwork::Ethereum => flat += "network:ethereum",
}
flat += &format!(",tokenAddress:\"{}\"", &self.token_address.clone());
flat += &format!(",minimumBalance:{:?}", self.mini_balance.clone());
flat
}
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct QLResponse {
#[serde(flatten)]
// data: HashMap<String, serde_json::Value>,
data: serde_json::Value,
}
impl RestPath<String> for QLResponse {
fn get_path(path: String) -> core::result::Result<String, HttpError> {
Ok(path)
}
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct IsHodlerOut {
pub verified_credentials_is_hodler: Vec<IsHodlerOutStruct>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct IsHodlerOutStruct {
pub address: String,
pub is_hodler: bool,
}

impl GraphQLClient {
pub fn new() -> Self {
let mut headers = Headers::new();
headers.insert(CONNECTION.as_str(), "close");
headers.insert(AUTHORIZATION.as_str(), GRAPHQL_AUTH_KEY);
let client = build_client(GRAPHQL_URL, headers);
GraphQLClient { client }
}

pub fn verified_credentials_is_hodler(
&mut self,
credentials: VerifiedCredentialsIsHodlerIn,
) -> Result<IsHodlerOut, Error> {
// FIXME: for the moment, the `path` is partially hard-code here.
let path = "latest/graphql?query=query{VerifiedCredentialsIsHodler(".to_string()
+ &credentials.conv_to_string()
+ "){isHodler, address}}";

let response = self
.client
.get_with::<String, QLResponse>(path, vec![].as_slice())
.map_err(|e| Error::RequestError(format!("{:?}", e)))?;

if let Some(value) = response.data.get("data") {
let is_hodler_out: IsHodlerOut = serde_json::from_value(value.clone()).unwrap();
Ok(is_hodler_out)
} else {
Err(Error::GraphQLError("Invalid GraphQL response".to_string()))
}
}
}

#[cfg(test)]
mod tests {
use crate::graphql::{
GraphQLClient, VerifiedCredentialsIsHodlerIn, VerifiedCredentialsNetwork,
};

const ACCOUNT_ADDRESS1: &str = "0x61f2270153bb68dc0ddb3bc4e4c1bd7522e918ad";
const ACCOUNT_ADDRESS2: &str = "0x3394caf8e5ccaffb936e6407599543af46525e0b";
const LIT_TOKEN_ADDRESS: &str = "0xb59490aB09A0f526Cc7305822aC65f2Ab12f9723";

#[test]
fn verified_credentials_is_hodler_work() {
let mut client = GraphQLClient::new();

let credentials = VerifiedCredentialsIsHodlerIn {
addresses: vec![ACCOUNT_ADDRESS1.to_string(), ACCOUNT_ADDRESS2.to_string()],
// from_date: format!("{:?}", Utc::now()),
from_date: "2022-10-16T00:00:00Z".to_string(),
network: VerifiedCredentialsNetwork::Ethereum,
token_address: LIT_TOKEN_ADDRESS.to_string(),
mini_balance: 0.00000056,
};
let response = client.verified_credentials_is_hodler(credentials);

if let Ok(is_hodler_out) = response {
assert_eq!(is_hodler_out.verified_credentials_is_hodler[0].is_hodler, true);
assert_eq!(is_hodler_out.verified_credentials_is_hodler[1].is_hodler, false);
} else {
assert!(false);
}
}
}
8 changes: 8 additions & 0 deletions litentry/core/data-providers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub mod discord_official;
pub mod twitter_litentry;
pub mod twitter_official;

pub mod graphql;

const TIMEOUT: Duration = Duration::from_secs(3u64);

#[cfg(all(not(test), not(feature = "mockserver")))]
Expand All @@ -62,6 +64,9 @@ pub mod base_url {

pub(crate) const DISCORD_OFFICIAL: &str = "https://discordapp.com";
pub(crate) const DISCORD_LITENTRY: &str = "http://47.57.13.126:8080";

pub(crate) const GRAPHQL_URL: &str = "https://graph.tdf-labs.io/";
pub(crate) const GRAPHQL_AUTH_KEY: &str = "ac2115ec-e327-4862-84c5-f25b6b7d4533";
}

// #[cfg(test)]
Expand All @@ -80,6 +85,9 @@ pub enum Error {

#[error("UTF8 error: {0}")]
Utf8Error(String),

#[error("GraphQL error: {0}")]
GraphQLError(String),
}

pub trait UserInfo {
Expand Down
Loading