Skip to content

Commit

Permalink
adding components for contract functions and events
Browse files Browse the repository at this point in the history
  • Loading branch information
DrHongos committed Jan 16, 2024
1 parent ecb52be commit 9c91b90
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 63 deletions.
43 changes: 41 additions & 2 deletions index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ main {
font-weight: 800;
background-color: gold;
}
.execute-button {
padding: 10px;
border: 1px solid black;
border-radius: 5px;
background-color: darkorchid;
color: black;
font-weight: 750;
transition: all 0.25s;
cursor: pointer;
}

.button-event {
padding: 10px;
border: 1px solid black;
border-radius: 5px;
background-color: darkgreen;
color: white;
font-weight: 750;
transition: all 0.25s;
cursor: pointer;
}


.burn:after {
content: "🔥";
Expand Down Expand Up @@ -265,7 +287,24 @@ h1 + .subtitle {
display: flex;
border: 1px solid white;
padding: 5px;
border:1px solid black;
}
.contract-function button {
max-width: 10%;

.contract-event {
display: flex;
border: 1px solid white;
padding: 5px;
border:1px solid black;
}
.function-table {
width: 100%;
color: black;
background-color: whitesmoke;
font-size: small;
border-collapse:collapse;
border:1px solid black;
}

.functions-table table td, tr {
border:1px solid black;
}
80 changes: 80 additions & 0 deletions src/components/event_component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use yew::prelude::*;
use alloy_primitives::Address;
use alloy_json_abi::Event;
use std::{
ops::BitXorAssign,
};
/*
Create filter with event
Decode responses
how to make the component generic to inputs/outputs
*/
#[derive(Properties, PartialEq)]
pub struct Props {
pub address: Address,
pub event: Event,
// pub placeholder: String,
}

#[function_component(EventComponent)]
pub fn event_component(props: &Props) -> Html {
let open = use_state(|| false);
let error_msg = use_state(|| None as Option<String>);

let toggle_comp = {
let o = open.clone();
let rv = (*o).clone();
Callback::from(move |_e: MouseEvent| {
let mut rvv = rv.clone();
let _ = rvv.bitxor_assign(true);
o.set(rvv);
})
};
let button_label = match (*open).clone() {
true => format!("Close {}", props.event.name),
false => format!("{}",props.event.name),
};

let inputs_list = props.event.inputs
.clone()
.into_iter()
.map(|v| {
html!(
<table class={"function-table"}>
<tr>
<td>{format!("{} [{}]",v.name, v.ty)}</td>
//<td>{v.ty}</td>
</tr>
</table>
)
}
).collect::<Html>();

html! {
<div>
<button onclick={toggle_comp} class={"button-event"}>
{button_label}
</button>
if (*open).clone() {
<div class="contract_event">
<table class={"function-table"}>
<tr>
<td>{"Name"}</td>
<td>{&props.event.name}</td>
</tr>
<tr>
<td>{"Inputs"}</td>
// <td>{format!("{:?}", props.event.inputs)}</td>
{inputs_list}
</tr>
</table>
</div>
if let Some(error) = (*error_msg).clone() {
<hr />
<small>{error}</small>
}
}
</div>
}
}
153 changes: 153 additions & 0 deletions src/components/function_component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use yew::prelude::*;
use alloy_primitives::{Address, Bytes};
use alloy_json_abi::{Function, StateMutability};
use wasm_bindgen_futures::spawn_local;
use web_sys::HtmlButtonElement;
use crate::contexts::ethereum::UseEthereum;
use std::{
ops::BitXorAssign,
str::FromStr,
};
use alloy_rpc_types::{CallRequest, CallInput};
/*
Add inputs to call
Decode responses
Store last response timestamped (type is function dependent)
how to make the component generic to inputs/outputs
*/
#[derive(Properties, PartialEq)]
pub struct Props {
pub address: Address,
pub function: Function,
// pub placeholder: String,
}

#[function_component(FunctionComponent)]
pub fn function_component(props: &Props) -> Html {
let open = use_state(|| false);
let error_msg = use_state(|| None as Option<String>);

let ethereum = use_context::<UseEthereum>().expect(
"No ethereum found. You must wrap your components in an <EthereumContextProvider />",
);
let provider = ethereum.provider.clone();

let toggle_comp = {
let o = open.clone();
let rv = (*o).clone();
Callback::from(move |_e: MouseEvent| {
let mut rvv = rv.clone();
let _ = rvv.bitxor_assign(true);
o.set(rvv);
})
};
let button_label = match (*open).clone() {
true => format!("Close {}", props.function.name),
false => format!("{}",props.function.name),
};

let call_function = {
let provider = provider.clone();
let address = props.address.clone();
Callback::from(move |e: MouseEvent| {
let t: HtmlButtonElement = e.target_unchecked_into();
let fn_selector = t.value();
let tx = CallRequest {
to: Some(address),
input: CallInput::new(Bytes::from_str(&fn_selector).expect("Error parsing bytes")),
from: None,
gas_price: None,
max_fee_per_gas: None,
max_priority_fee_per_gas: None,
gas: None,
value: None,
nonce: None,
chain_id: None,
access_list: None,
max_fee_per_blob_gas: None,
blob_versioned_hashes: None,
transaction_type: None,
};
let provider = provider.clone();
spawn_local(async move {
crate::helpers::log(format!("tx is {:#?}", tx).as_str());
if let Some(provider) = (*provider).clone() {
let c = provider.call(tx, None);
match c.await {
Ok(bn) => crate::helpers::log(format!("Call result: {}", bn).as_str()),
Err(rv) => crate::helpers::log(format!("Error: {:#?}", rv).as_str())
}
}
})
})
};

let inputs_list = props.function.inputs
.clone()
.into_iter()
.map(|v| {
html!(
<table class={"function-table"}>
<tr>
<td>{format!("{} [{}]",v.name, v.ty)}</td>
//<td>{v.ty}</td>
</tr>
</table>
)
}
).collect::<Html>();

let outputs_list = props.function.outputs
.clone()
.into_iter()
.map(|v| {
html!(
<table class={"function-table"}>
<tr>
<td>{v.name}</td>
<td>{v.ty}</td>
// input?
</tr>
</table>
)
}
).collect::<Html>();

html! {
<div>
<button onclick={toggle_comp} class={"button"}>
{button_label}
</button>
if (*open).clone() {
<div class="contract_function">
<table class={"function-table"}>
<tr>
<td>{"Name"}</td>
<td>{&props.function.name}</td>
</tr>
<tr>
<td>{"State Mutability"}</td>
<td>{format!("{:?}", props.function.state_mutability)}</td>
</tr>
<tr>
<td>{"Inputs"}</td>
{inputs_list}
</tr>
<tr>
<td>{"Outputs"}</td>
{outputs_list}
</tr>
</table>
if props.function.inputs.len() == 0 && props.function.state_mutability != StateMutability::Payable {
<button onclick={call_function} value={props.function.selector().to_string()} class={"execute-button"}>{"Call"}</button>
}
</div>
if let Some(error) = (*error_msg).clone() {
<hr />
<small>{error}</small>
}
}
</div>
}
}
Loading

0 comments on commit 9c91b90

Please sign in to comment.