Skip to content

Commit

Permalink
feature: working on possibility of checking attestation
Browse files Browse the repository at this point in the history
  • Loading branch information
scx1332 committed Apr 30, 2024
1 parent 1d10a10 commit fcaa5c3
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 104 deletions.
14 changes: 5 additions & 9 deletions crates/erc20_payment_lib/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use crate::error::PaymentError;
use std::str::FromStr;
use web3::contract::tokens::Tokenize;
use web3::contract::Contract;
use web3::ethabi::{FixedBytes, Hash};
use web3::transports::Http;
use web3::types::{Address, H256, U256};
use web3::{ethabi, Transport, Web3};
use web3::ethabi::{FixedBytes, Hash};

// todo remove DUMMY_RPC_PROVIDER and use ABI instead
// todo change to once_cell
Expand Down Expand Up @@ -61,16 +61,12 @@ where
.and_then(|function| function.encode_input(&params.into_tokens()))
}

pub fn encode_get_attestation(
uid: H256,
) -> Result<Vec<u8>, web3::ethabi::Error> {
contract_encode(&EAS_CONTRACT_TEMPLATE, "getAttestation", (uid, ))
pub fn encode_get_attestation(uid: H256) -> Result<Vec<u8>, web3::ethabi::Error> {
contract_encode(&EAS_CONTRACT_TEMPLATE, "getAttestation", (uid,))
}

pub fn encode_get_schema(
uid: H256,
) -> Result<Vec<u8>, web3::ethabi::Error> {
contract_encode(&SCHEMA_REGISTRY_TEMPLATE, "getSchema", (uid, ))
pub fn encode_get_schema(uid: H256) -> Result<Vec<u8>, web3::ethabi::Error> {
contract_encode(&SCHEMA_REGISTRY_TEMPLATE, "getSchema", (uid,))
}

pub fn encode_erc20_balance_of(address: Address) -> Result<Vec<u8>, web3::ethabi::Error> {
Expand Down
21 changes: 13 additions & 8 deletions crates/erc20_payment_lib/src/eth.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use crate::contracts::{encode_erc20_allowance, encode_erc20_balance_of, encode_get_attestation, encode_get_deposit_details, encode_get_schema};
use crate::contracts::{
encode_erc20_allowance, encode_erc20_balance_of, encode_get_attestation,
encode_get_deposit_details, encode_get_schema,
};
use crate::error::*;
use crate::{err_create, err_custom_create, err_from};
use erc20_payment_lib_common::utils::{datetime_from_u256_timestamp, datetime_from_u256_with_option, U256ConvExt};
use chrono::{DateTime, Utc};
use erc20_payment_lib_common::utils::{
datetime_from_u256_timestamp, datetime_from_u256_with_option, U256ConvExt,
};
use erc20_rpc_pool::Web3RpcPool;
use secp256k1::{PublicKey, SecretKey};
use serde::{Deserialize, Serialize};
use sha3::Digest;
use sha3::Keccak256;
use std::sync::Arc;
use chrono::{DateTime, Utc};
use web3::ethabi;
use web3::types::{Address, BlockId, BlockNumber, Bytes, CallRequest, H256, U256, U64};

Expand Down Expand Up @@ -148,7 +153,7 @@ pub async fn get_schema_details(
uid: H256::from_slice(decoded[0].clone().into_fixed_bytes().unwrap().as_slice()),
resolver: decoded[1].clone().into_address().unwrap(),
revocable: decoded[2].clone().into_bool().unwrap(),
schema: decoded[3].clone().into_string().unwrap()
schema: decoded[3].clone().into_string().unwrap(),
};

Ok(schema)
Expand All @@ -165,7 +170,7 @@ pub struct Attestation {
pub recipient: Address,
pub attester: Address,
pub revocable: bool,
pub data: Bytes
pub data: Bytes,
}

pub async fn get_attestation_details(
Expand All @@ -185,7 +190,6 @@ pub async fn get_attestation_details(
.await
.map_err(err_from!())?;


let decoded = ethabi::decode(
&[
ethabi::ParamType::Tuple(
Expand Down Expand Up @@ -214,14 +218,15 @@ pub async fn get_attestation_details(
let attestation = Attestation {
uid: H256::from_slice(decoded[0].clone().into_fixed_bytes().unwrap().as_slice()),
schema: H256::from_slice(decoded[1].clone().into_fixed_bytes().unwrap().as_slice()),
time: datetime_from_u256_with_option(decoded[2].clone().into_uint().unwrap()).ok_or(err_custom_create!("Attestation timestamp out of range"))?,
time: datetime_from_u256_with_option(decoded[2].clone().into_uint().unwrap())
.ok_or(err_custom_create!("Attestation timestamp out of range"))?,
expiration_time: datetime_from_u256_with_option(decoded[3].clone().into_uint().unwrap()),
revocation_time: datetime_from_u256_with_option(decoded[4].clone().into_uint().unwrap()),
refUID: H256::from_slice(decoded[5].clone().into_fixed_bytes().unwrap().as_slice()),
recipient: decoded[6].clone().into_address().unwrap(),
attester: decoded[7].clone().into_address().unwrap(),
revocable: decoded[8].clone().into_bool().unwrap(),
data: Bytes::from(decoded[9].clone().into_bytes().unwrap())
data: Bytes::from(decoded[9].clone().into_bytes().unwrap()),
};

Ok(attestation)
Expand Down
155 changes: 84 additions & 71 deletions crates/erc20_payment_lib/src/server/web.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::eth::{Attestation, AttestationSchema, get_attestation_details, get_balance, get_schema_details};
use crate::eth::{
get_attestation_details, get_balance, get_schema_details, Attestation, AttestationSchema,
};
use crate::runtime::{PaymentRuntime, SharedState, TransferArgs, TransferType};
use crate::server::ws::event_stream_websocket_endpoint;
use crate::setup::{ChainSetup, PaymentSetup};
use crate::transaction::create_token_transfer;
use actix_files::NamedFile;
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::error::ErrorBadRequest;
use actix_web::http::header::HeaderValue;
use actix_web::http::{header, StatusCode};
use actix_web::web::Data;
Expand All @@ -22,7 +25,6 @@ use std::collections::BTreeMap;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use actix_web::error::ErrorBadRequest;
use tokio::sync::Mutex;
use web3::ethabi;
use web3::types::{Address, BlockId, BlockNumber, H256, U256};
Expand Down Expand Up @@ -1240,27 +1242,29 @@ struct AttestationCheckResult {
params: Vec<AttestationItemInfo>,
}

pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) -> actix_web::Result<web::Json<AttestationCheckResult>>
{
pub async fn check_attestation(
data: Data<Box<ServerData>>,
req: HttpRequest,
) -> actix_web::Result<web::Json<AttestationCheckResult>> {
let my_data = data.shared_state.lock().unwrap();


let attestation_uid = req.match_info().get("uid").unwrap_or("");
let chain_name = req.match_info().get("chain").unwrap_or("");
let chain: &ChainSetup = data
.payment_setup
.chain_setup
.iter().find(
|(_, chain)| chain.network == chain_name
).ok_or(
actix_web::error::ErrorBadRequest(format!("No config found for network {}", chain_name))
)?.1;

let web3 = data.payment_setup.get_provider(
chain.chain_id
).map_err(
|e| ErrorBadRequest(format!("Failed to get provider: {}", e))
)?;
.payment_setup
.chain_setup
.iter()
.find(|(_, chain)| chain.network == chain_name)
.ok_or(actix_web::error::ErrorBadRequest(format!(
"No config found for network {}",
chain_name
)))?
.1;

let web3 = data
.payment_setup
.get_provider(chain.chain_id)
.map_err(|e| ErrorBadRequest(format!("Failed to get provider: {}", e)))?;

let decoded_bytes = match hex::decode(attestation_uid.replace("0x", "")) {
Ok(bytes) => bytes,
Expand All @@ -1272,13 +1276,21 @@ pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) ->
}
};

let contract = chain.eas_contract_settings.clone().ok_or(
ErrorBadRequest(format!("No contract settings found for chain {}", chain_name))
)?;
let contract = chain
.eas_contract_settings
.clone()
.ok_or(ErrorBadRequest(format!(
"No contract settings found for chain {}",
chain_name
)))?;

let schema_contract = chain.eas_schema_registry_settings.clone().ok_or(
ErrorBadRequest(format!("No schema contract settings found for chain {}", chain_name))
)?;
let schema_contract = chain
.eas_schema_registry_settings
.clone()
.ok_or(ErrorBadRequest(format!(
"No schema contract settings found for chain {}",
chain_name
)))?;

let uid = ethabi::Bytes::from(decoded_bytes);

Expand All @@ -1292,33 +1304,8 @@ pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) ->
};
log::info!("Querying attestation contract: {:#x}", contract.address);



let attestation = match get_attestation_details(
web3.clone(),
uid,
contract.address,
).await {
Ok(attestation) => {
attestation
}
Err(e) => {
log::error!("Failed to get attestation details: {}", e);
return Err(ErrorBadRequest(format!(
"Failed to get attestation details: {}",
e
)));
}
};

let attestation_schema = match get_schema_details(
web3,
attestation.schema,
schema_contract.address,
).await {
Ok(attestation_schema) => {
attestation_schema
}
let attestation = match get_attestation_details(web3.clone(), uid, contract.address).await {
Ok(attestation) => attestation,
Err(e) => {
log::error!("Failed to get attestation details: {}", e);
return Err(ErrorBadRequest(format!(
Expand All @@ -1328,19 +1315,41 @@ pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) ->
}
};

let attestation_schema =
match get_schema_details(web3, attestation.schema, schema_contract.address).await {
Ok(attestation_schema) => attestation_schema,
Err(e) => {
log::error!("Failed to get attestation details: {}", e);
return Err(ErrorBadRequest(format!(
"Failed to get attestation details: {}",
e
)));
}
};

log::info!("Querying schema contract: {:#x}", schema_contract.address);


println!("attestation: {}", serde_json::to_string_pretty(&attestation).map_err(
|e| ErrorBadRequest(format!("Failed to serialize attestation details: {}", e))
)?);

println!("schema: {}", serde_json::to_string_pretty(&attestation_schema).map_err(
|e| ErrorBadRequest(format!("Failed to serialize attestation details: {}", e))
)?);

let items = attestation_schema.schema.split(",").into_iter().collect::<Vec<&str>>();
println!(
"attestation: {}",
serde_json::to_string_pretty(&attestation).map_err(|e| ErrorBadRequest(format!(
"Failed to serialize attestation details: {}",
e
)))?
);

println!(
"schema: {}",
serde_json::to_string_pretty(&attestation_schema).map_err(|e| ErrorBadRequest(format!(
"Failed to serialize attestation details: {}",
e
)))?
);

let items = attestation_schema
.schema
.split(",")
.into_iter()
.collect::<Vec<&str>>();
log::debug!("There are {} items in the schema", items.len());
let mut param_types = Vec::new();
let mut param_names = Vec::new();
Expand All @@ -1355,19 +1364,21 @@ pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) ->
let item_name = items2[1].trim();

log::debug!("Item name: {}, Item type: {}", item_name, item_type);
let param_type = ethabi::param_type::Reader::read(item_type).map_err(
|e| ErrorBadRequest(format!("Failed to read param type: {}", e))
)?;
let param_type = ethabi::param_type::Reader::read(item_type)
.map_err(|e| ErrorBadRequest(format!("Failed to read param type: {}", e)))?;
param_types.push(param_type);
param_names.push(item_name);
}

let decoded_tokens = ethabi::decode(&param_types, &attestation.data.0).map_err(
|e| ErrorBadRequest(format!("Failed to decode attestation data: {}", e))
)?;
let decoded_tokens = ethabi::decode(&param_types, &attestation.data.0)
.map_err(|e| ErrorBadRequest(format!("Failed to decode attestation data: {}", e)))?;

let mut decoded_items = Vec::new();
for ((token, token_name), token_type) in decoded_tokens.iter().zip(param_names.iter()).zip(param_types.iter()) {
for ((token, token_name), token_type) in decoded_tokens
.iter()
.zip(param_names.iter())
.zip(param_types.iter())
{
println!("Token {}: {}", token_name, token);
decoded_items.push(AttestationItemInfo {
name: token_name.to_string(),
Expand All @@ -1382,10 +1393,9 @@ pub async fn check_attestation(data: Data<Box<ServerData>>, req: HttpRequest) ->
attestation,
schema: attestation_schema,
params: decoded_items,
}))
}));
}


pub fn runtime_web_scope(
scope: Scope,
server_data: Data<Box<ServerData>>,
Expand All @@ -1397,7 +1407,10 @@ pub fn runtime_web_scope(
let api_scope = Scope::new("/api");
let mut api_scope = api_scope
.app_data(server_data)
.route("/attestation/{chain}/{uid}", web::get().to(check_attestation))
.route(
"/attestation/{chain}/{uid}",
web::get().to(check_attestation),
)
.route("/allowances", web::get().to(allowances))
.route("/balance/{account}/{chain}", web::get().to(account_balance))
.route("/rpc_pool", web::get().to(rpc_pool))
Expand Down
20 changes: 10 additions & 10 deletions crates/erc20_payment_lib/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,16 +309,16 @@ impl PaymentSetup {
.distributor_contract
.clone()
.map(|m| m.address),
eas_contract_settings: chain_config.1.attestation_contract.clone().map(|m| {
EasContractSettings {
address: m.address,
}
}),
eas_schema_registry_settings: chain_config.1.schema_registry_contract.clone().map(
|m| EasSchemaRegistrySettings {
address: m.address,
},
),
eas_contract_settings: chain_config
.1
.attestation_contract
.clone()
.map(|m| EasContractSettings { address: m.address }),
eas_schema_registry_settings: chain_config
.1
.schema_registry_contract
.clone()
.map(|m| EasSchemaRegistrySettings { address: m.address }),
faucet_setup,

transaction_timeout: chain_config.1.transaction_timeout,
Expand Down
2 changes: 1 addition & 1 deletion src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use rustc_hex::FromHexError;
use std::str::FromStr;
use web3::types::Address;

pub mod attestation;
pub mod check_rpc;
pub mod deposit;
pub mod scan_chain;
pub mod attestation;

pub fn check_address_name(n: &str) -> Result<Address, FromHexError> {
match n {
Expand Down
2 changes: 1 addition & 1 deletion src/actions/attestation.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod check;
pub mod check;
Loading

0 comments on commit fcaa5c3

Please sign in to comment.