Skip to content

Commit

Permalink
add crate eth sandbox (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdelabro authored Jan 2, 2024
1 parent e2735f2 commit 998f5e0
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 65 deletions.
45 changes: 23 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"crates/starknet-core-contract-client",
"crates/sandbox",
]

[workspace.package]
Expand All @@ -11,11 +12,14 @@ repository = "https://github.com/keep-starknet-strange/zaun/"
version = "0.1.0"

[workspace.dependencies]
ethers = "2.0.7"
ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" }
log = "0.4.20"
thiserror = "1.0.51"
num-traits = "0.2.17"
async-trait = "0.1.74"
dirs = "5.0.1"
serde_json = "1.0.108"
hex = "0.4.3"



13 changes: 13 additions & 0 deletions crates/sandbox/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "sandbox"
edition.workspace = true
version.workspace = true
authors.workspace = true

[dependencies]
starknet-core-contract-client = { path = "../starknet-core-contract-client" }
ethers = { workspace = true }
dirs = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
hex = { workspace = true }
83 changes: 83 additions & 0 deletions crates/sandbox/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use ethers::abi::Tokenize;
use ethers::prelude::{ContractFactory, ContractInstance};
use ethers::types::{Address, Bytes};
use ethers::utils::hex::FromHex;
use ethers::utils::{Anvil, AnvilInstance};
use starknet_core_contract_client::clients::StarknetSovereignContractClient;
use starknet_core_contract_client::{LocalWalletSignerMiddleware, StarknetCoreContractClient};
use std::path::PathBuf;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
SerdeJson(#[from] serde_json::Error),
#[error("['bytecode']['object'] is not a string")]
BytecodeObject,
#[error(transparent)]
Hex(#[from] hex::FromHexError),
}

pub struct EthereumSandbox {
_anvil: AnvilInstance,
client: Arc<StarknetSovereignContractClient>,
}

impl EthereumSandbox {
pub fn new(
core_contract_address: Address,
ether_client: Arc<LocalWalletSignerMiddleware>,
anvil_path: Option<PathBuf>,
) -> Self {
let anvil_path: PathBuf = anvil_path
.or_else(|| std::env::var("ANVIL_PATH").map(Into::into).ok())
.unwrap_or_else(|| dirs::home_dir().unwrap().join(".foundry/bin/anvil"));

// Will panic if invalid path
let anvil = Anvil::at(anvil_path).spawn();

let client = StarknetSovereignContractClient::new(core_contract_address, ether_client);
Self {
_anvil: anvil,
client: Arc::new(client),
}
}

pub fn client(&self) -> Arc<StarknetSovereignContractClient> {
self.client.clone()
}

pub fn address(&self) -> Address {
self.client.address()
}

pub async fn deploy<T: Tokenize>(
&self,
contract_build_artifacts: &str,
contructor_args: T,
) -> Result<
ContractInstance<Arc<LocalWalletSignerMiddleware>, LocalWalletSignerMiddleware>,
Error,
> {
let (abi, bytecode) = {
let mut artifacts: serde_json::Value = serde_json::from_str(contract_build_artifacts)?;
let abi = serde_json::from_value(artifacts["abi"].take())?;
let bytecode = Bytes::from_hex(
artifacts["bytecode"]["object"]
.as_str()
.ok_or(Error::BytecodeObject)?,
)?;
(abi, bytecode)
};

let factory = ContractFactory::new(abi, bytecode, self.client.client().clone());

Ok(factory
.deploy(contructor_args)
.expect("Failed to deploy contract")
.send()
.await
.expect("Ethereum polling error"))
}
}
5 changes: 0 additions & 5 deletions crates/starknet-core-contract-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,3 @@ log = { workspace = true }
thiserror = { workspace = true }
num-traits = { workspace = true }
async-trait = { workspace = true }





59 changes: 37 additions & 22 deletions crates/starknet-core-contract-client/src/clients/sovereign.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,76 @@
use std::sync::Arc;

use crate::{
interfaces::{Operator, ProxySupport, StarknetMessaging, StarknetSovereignContract, StarknetGovernance, GovernedFinalizable},
LocalMiddleware,
interfaces::{
GovernedFinalizable, Operator, ProxySupport, StarknetGovernance, StarknetMessaging,
StarknetSovereignContract,
},
LocalWalletSignerMiddleware, StarknetCoreContractClient,
};
use ethers::types::Address;

/// Client to interact with a Starknet core contract running in `Sovereign` mode
pub struct StarknetSovereignContractClient {
core_contract: StarknetSovereignContract<LocalMiddleware>,
messaging: StarknetMessaging<LocalMiddleware>,
operator: Operator<LocalMiddleware>,
proxy_support: ProxySupport<LocalMiddleware>,
governance: StarknetGovernance<LocalMiddleware>,
governed_finalizable: GovernedFinalizable<LocalMiddleware>
core_contract: StarknetSovereignContract<LocalWalletSignerMiddleware>,
messaging: StarknetMessaging<LocalWalletSignerMiddleware>,
operator: Operator<LocalWalletSignerMiddleware>,
proxy_support: ProxySupport<LocalWalletSignerMiddleware>,
governance: StarknetGovernance<LocalWalletSignerMiddleware>,
governed_finalizable: GovernedFinalizable<LocalWalletSignerMiddleware>,
}

impl StarknetSovereignContractClient {
pub fn new(address: Address, client: Arc<LocalMiddleware>) -> Self {
pub fn new(address: Address, client: Arc<LocalWalletSignerMiddleware>) -> Self {
Self {
core_contract: StarknetSovereignContract::new(address, client.clone()),
messaging: StarknetMessaging::new(address, client.clone()),
operator: Operator::new(address, client.clone()),
proxy_support: ProxySupport::new(address, client.clone()),
governance: StarknetGovernance::new(address, client.clone()),
governed_finalizable: GovernedFinalizable::new(address, client.clone())
governed_finalizable: GovernedFinalizable::new(address, client.clone()),
}
}
}

impl AsRef<StarknetSovereignContract<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &StarknetSovereignContract<LocalMiddleware> {
impl AsRef<StarknetSovereignContract<LocalWalletSignerMiddleware>>
for StarknetSovereignContractClient
{
fn as_ref(&self) -> &StarknetSovereignContract<LocalWalletSignerMiddleware> {
&self.core_contract
}
}
impl AsRef<StarknetMessaging<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &StarknetMessaging<LocalMiddleware> {
impl AsRef<StarknetMessaging<LocalWalletSignerMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &StarknetMessaging<LocalWalletSignerMiddleware> {
&self.messaging
}
}
impl AsRef<ProxySupport<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &ProxySupport<LocalMiddleware> {
impl AsRef<ProxySupport<LocalWalletSignerMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &ProxySupport<LocalWalletSignerMiddleware> {
&self.proxy_support
}
}
impl AsRef<Operator<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &Operator<LocalMiddleware> {
impl AsRef<Operator<LocalWalletSignerMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &Operator<LocalWalletSignerMiddleware> {
&self.operator
}
}
impl AsRef<StarknetGovernance<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &StarknetGovernance<LocalMiddleware> {
impl AsRef<StarknetGovernance<LocalWalletSignerMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &StarknetGovernance<LocalWalletSignerMiddleware> {
&self.governance
}
}
impl AsRef<GovernedFinalizable<LocalMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &GovernedFinalizable<LocalMiddleware> {
impl AsRef<GovernedFinalizable<LocalWalletSignerMiddleware>> for StarknetSovereignContractClient {
fn as_ref(&self) -> &GovernedFinalizable<LocalWalletSignerMiddleware> {
&self.governed_finalizable
}
}

impl StarknetCoreContractClient for StarknetSovereignContractClient {
fn address(&self) -> Address {
self.core_contract.address()
}

fn client(&self) -> Arc<LocalWalletSignerMiddleware> {
self.core_contract.client()
}
}
Loading

0 comments on commit 998f5e0

Please sign in to comment.