Skip to content

Commit

Permalink
Appchain client (#24)
Browse files Browse the repository at this point in the history
* fix manifest issue

* fix build issue and tooling bump

* ran formatter
  • Loading branch information
byteZorvin authored Sep 16, 2024
1 parent dab8928 commit f6c35c3
Show file tree
Hide file tree
Showing 8 changed files with 1,118 additions and 541 deletions.
1,528 changes: 1,053 additions & 475 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
"crates/l2/starknet-erc20-client",
"crates/l2/starkgate-registry-client",
"crates/l2/starknet-proxy-client",
"crates/l3/appchain-core-contract-client",
]

[workspace.package]
Expand All @@ -27,3 +28,16 @@ async-trait = "0.1.74"
dirs = "5.0.1"
serde_json = "1.0.108"
hex = "0.4.3"
color-eyre = "0.6.3"

# Starknet crates
starknet = "0.11.0"
starknet-ff = "0.3.7"
starknet-core = "0.11.0"
starknet-providers = "0.11.0"
starknet-contract = "0.10.0"
starknet-signers = "0.9.0"
starknet-accounts = "0.10.0"


url = "2.5.2"
7 changes: 0 additions & 7 deletions crates/l3/appchain-core-contract-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ num-traits = { workspace = true }
serde_json = { workspace = true }
starknet = { workspace = true }
starknet-accounts = { workspace = true }
starknet-contract = { workspace = true }
starknet-core = { workspace = true }
starknet-crypto = { workspace = true }
starknet-ff = { workspace = true }
starknet-instance = { path = "../starknet-instance" }
starknet-providers = { workspace = true }
starknet-signers = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
url = { workspace = true }
4 changes: 2 additions & 2 deletions crates/l3/appchain-core-contract-client/src/clients/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::interfaces::core_contract::CoreContract;
use crate::interfaces::messaging::Messaging;
use crate::interfaces::operator::Operator;
use starknet_ff::FieldElement;
use starknet_core::types::Felt;

use appchain_utils::LocalWalletSignerMiddleware;

Expand All @@ -12,7 +12,7 @@ pub struct StarknetCoreContractClient<'a> {
}

impl<'a> StarknetCoreContractClient<'a> {
pub fn new(address: FieldElement, signer: &'a LocalWalletSignerMiddleware) -> Self {
pub fn new(address: Felt, signer: &'a LocalWalletSignerMiddleware) -> Self {
Self {
operator: Operator::new(address, signer),
messaging: Messaging::new(address, signer),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use appchain_utils::invoke_contract;
use appchain_utils::LocalWalletSignerMiddleware;
use color_eyre::Result;
use starknet_core::types::{FieldElement, InvokeTransactionResult};
use starknet_core::types::{Felt, InvokeTransactionResult};

pub struct CoreContract<'a> {
signer: &'a LocalWalletSignerMiddleware,
address: FieldElement,
address: Felt,
}

impl<'a> CoreContract<'a> {
pub fn new(address: FieldElement, signer: &'a LocalWalletSignerMiddleware) -> Self {
pub fn new(address: Felt, signer: &'a LocalWalletSignerMiddleware) -> Self {
Self { signer, address }
}

pub async fn update_state(
&self,
program_output: Vec<FieldElement>,
onchain_data_hash: FieldElement,
onchain_data_size: FieldElement,
program_output: Vec<Felt>,
onchain_data_hash: Felt,
onchain_data_size: Felt,
) -> Result<InvokeTransactionResult> {
let mut calldata = Vec::with_capacity(program_output.len() + 2);
calldata.extend(program_output);
Expand Down
32 changes: 16 additions & 16 deletions crates/l3/appchain-core-contract-client/src/interfaces/messaging.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use appchain_utils::invoke_contract;
use appchain_utils::LocalWalletSignerMiddleware;
use color_eyre::Result;
use starknet_core::types::{FieldElement, InvokeTransactionResult};
use starknet_core::types::{Felt, InvokeTransactionResult};

pub struct Messaging<'a> {
signer: &'a LocalWalletSignerMiddleware,
address: FieldElement,
address: Felt,
}

impl<'a> Messaging<'a> {
pub fn new(address: FieldElement, signer: &'a LocalWalletSignerMiddleware) -> Self {
pub fn new(address: Felt, signer: &'a LocalWalletSignerMiddleware) -> Self {
Self { signer, address }
}

pub async fn send_message_to_appchain(
&self,
to_address: FieldElement,
selector: FieldElement,
payload: Vec<FieldElement>,
to_address: Felt,
selector: Felt,
payload: Vec<Felt>,
) -> Result<InvokeTransactionResult> {
let mut calldata = Vec::with_capacity(payload.len() + 2);
calldata.push(to_address);
Expand All @@ -35,8 +35,8 @@ impl<'a> Messaging<'a> {

pub async fn consume_message_from_appchain(
&self,
from_address: FieldElement,
payload: Vec<FieldElement>,
from_address: Felt,
payload: Vec<Felt>,
) -> Result<InvokeTransactionResult> {
let mut calldata = Vec::with_capacity(payload.len() + 1);
calldata.push(from_address);
Expand All @@ -53,10 +53,10 @@ impl<'a> Messaging<'a> {

pub async fn start_message_cancellation(
&self,
to_address: FieldElement,
selector: FieldElement,
nonce: FieldElement,
payload: Vec<FieldElement>,
to_address: Felt,
selector: Felt,
nonce: Felt,
payload: Vec<Felt>,
) -> Result<InvokeTransactionResult> {
let mut calldata = Vec::with_capacity(payload.len() + 3);
calldata.push(to_address);
Expand All @@ -75,10 +75,10 @@ impl<'a> Messaging<'a> {

pub async fn cancel_message(
&self,
to_address: FieldElement,
selector: FieldElement,
nonce: FieldElement,
payload: Vec<FieldElement>,
to_address: Felt,
selector: Felt,
nonce: Felt,
payload: Vec<Felt>,
) -> Result<InvokeTransactionResult> {
let mut calldata = Vec::with_capacity(payload.len() + 3);
calldata.push(to_address);
Expand Down
27 changes: 12 additions & 15 deletions crates/l3/appchain-core-contract-client/src/interfaces/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@ use appchain_utils::LocalWalletSignerMiddleware;
use appchain_utils::{call_contract, invoke_contract};
use color_eyre::{eyre::eyre, Result};
use starknet_accounts::ConnectedAccount;
use starknet_core::types::{FieldElement, InvokeTransactionResult};
use starknet_core::types::{Felt, InvokeTransactionResult};
use starknet_providers::jsonrpc::{HttpTransport, JsonRpcClient};

pub struct Operator<'a> {
signer: &'a LocalWalletSignerMiddleware,
address: FieldElement,
address: Felt,
}

impl<'a> Operator<'a> {
pub fn new(address: FieldElement, signer: &'a LocalWalletSignerMiddleware) -> Self {
pub fn new(address: Felt, signer: &'a LocalWalletSignerMiddleware) -> Self {
Self { signer, address }
}

fn provider(&self) -> &JsonRpcClient<HttpTransport> {
self.signer.provider()
}

pub async fn register_operator(
&self,
new_operator: FieldElement,
) -> Result<InvokeTransactionResult> {
pub async fn register_operator(&self, new_operator: Felt) -> Result<InvokeTransactionResult> {
invoke_contract(
self.signer,
self.address,
Expand All @@ -34,7 +31,7 @@ impl<'a> Operator<'a> {

pub async fn unregister_operator(
&self,
removed_operator: FieldElement,
removed_operator: Felt,
) -> Result<InvokeTransactionResult> {
invoke_contract(
self.signer,
Expand All @@ -45,20 +42,20 @@ impl<'a> Operator<'a> {
.await
}

pub async fn is_operator(&self, operator: FieldElement) -> Result<bool> {
pub async fn is_operator(&self, operator: Felt) -> Result<bool> {
let provider = self.provider();
let values = call_contract(provider, self.address, "is_operator", vec![operator]).await?;

values
.first()
.map(|value| *value != FieldElement::ZERO)
.map(|value| *value != Felt::ZERO)
.ok_or_else(|| eyre!("Contract error: expected at least one return value"))
}

pub async fn set_program_info(
&self,
program_hash: FieldElement,
config_hash: FieldElement,
program_hash: Felt,
config_hash: Felt,
) -> Result<InvokeTransactionResult> {
invoke_contract(
self.signer,
Expand All @@ -69,7 +66,7 @@ impl<'a> Operator<'a> {
.await
}

pub async fn get_program_info(&self) -> Result<(FieldElement, FieldElement)> {
pub async fn get_program_info(&self) -> Result<(Felt, Felt)> {
let provider = self.provider();
let values = call_contract(provider, self.address, "get_program_info", vec![]).await?;

Expand All @@ -81,7 +78,7 @@ impl<'a> Operator<'a> {

pub async fn set_facts_registry(
&self,
facts_registry: FieldElement,
facts_registry: Felt,
) -> Result<InvokeTransactionResult> {
invoke_contract(
self.signer,
Expand All @@ -92,7 +89,7 @@ impl<'a> Operator<'a> {
.await
}

pub async fn get_facts_registry(&self) -> Result<FieldElement> {
pub async fn get_facts_registry(&self) -> Result<Felt> {
let provider = self.provider();
let values = call_contract(provider, self.address, "get_facts_registry", vec![]).await?;

Expand Down
35 changes: 15 additions & 20 deletions crates/l3/appchain-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pub mod errors;

use color_eyre::{eyre::eyre, Result};
use starknet_accounts::{Account, Call, Execution, SingleOwnerAccount};
use starknet_accounts::{Account, Call, ExecutionV1, SingleOwnerAccount};
use starknet_contract::ContractFactory;
use starknet_core::types::contract::{CompiledClass, SierraClass};
use starknet_core::types::{BlockId, BlockTag, FunctionCall, InvokeTransactionResult};
use starknet_core::types::{BlockId, BlockTag, Felt, FunctionCall, InvokeTransactionResult};
use starknet_core::utils::get_selector_from_name;
use starknet_ff::FieldElement;
use starknet_providers::jsonrpc::{HttpTransport, JsonRpcClient};
Expand All @@ -16,17 +16,12 @@ pub type LocalWalletSignerMiddleware =
SingleOwnerAccount<JsonRpcClient<HttpTransport>, LocalWallet>;

type RpcAccount<'a> = SingleOwnerAccount<&'a JsonRpcClient<HttpTransport>, LocalWallet>;
pub type TransactionExecution<'a> = Execution<'a, RpcAccount<'a>>;
pub type TransactionExecution<'a> = ExecutionV1<'a, RpcAccount<'a>>;

pub const NO_CONSTRUCTOR_ARG: Vec<FieldElement> = Vec::new();
pub const NO_CONSTRUCTOR_ARG: Vec<Felt> = Vec::new();

// Montgomery representation for value 0x1000000000000
pub const MAX_FEE: FieldElement = FieldElement::from_mont([
18437736874454810625,
18446744073709551615,
18446744073709551615,
423338364972826640,
]);
pub const MAX_FEE: Felt = Felt::from_hex_unchecked("0x1000000000");

pub trait StarknetContractClient {
fn address(&self) -> FieldElement;
Expand All @@ -35,9 +30,9 @@ pub trait StarknetContractClient {

pub async fn invoke_contract(
signer: &LocalWalletSignerMiddleware,
address: FieldElement,
address: Felt,
method: &str,
calldata: Vec<FieldElement>,
calldata: Vec<Felt>,
) -> Result<InvokeTransactionResult> {
let selector = get_selector_from_name(method)
.map_err(|e| eyre!("Invalid selector for {}: {}", method, e))?;
Expand All @@ -47,7 +42,7 @@ pub async fn invoke_contract(
calldata,
};
signer
.execute(vec![call])
.execute_v1(vec![call])
.max_fee(MAX_FEE)
.send()
.await
Expand All @@ -56,10 +51,10 @@ pub async fn invoke_contract(

pub async fn call_contract(
provider: &JsonRpcClient<HttpTransport>,
address: FieldElement,
address: Felt,
method: &str,
calldata: Vec<FieldElement>,
) -> Result<Vec<FieldElement>> {
calldata: Vec<Felt>,
) -> Result<Vec<Felt>> {
let entry_point_selector = get_selector_from_name(method)
.map_err(|e| eyre!("Invalid selector for {}: {}", method, e))?;
let function_call = FunctionCall {
Expand All @@ -77,8 +72,8 @@ pub async fn deploy_contract<'a>(
signer: &'a LocalWalletSignerMiddleware,
path_to_sierra: &Path,
path_to_casm: &Path,
constructor_args: Vec<FieldElement>,
) -> Result<FieldElement> {
constructor_args: Vec<Felt>,
) -> Result<Felt> {
let sierra: SierraClass = {
let sierra_file = std::fs::File::open(path_to_sierra)
.map_err(|e| eyre!("Failed to open Sierra file: {}", e))?;
Expand All @@ -92,7 +87,7 @@ pub async fn deploy_contract<'a>(
let compiled_class_hash = casm
.class_hash()
.map_err(|e| eyre!("Failed to get class hash from CASM: {}", e))?;
let declare_tx = signer.declare(
let declare_tx = signer.declare_v2(
sierra
.clone()
.flatten()
Expand All @@ -110,7 +105,7 @@ pub async fn deploy_contract<'a>(

let contract_factory = ContractFactory::new(class_hash, signer);

let deploy_tx = contract_factory.deploy(constructor_args, FieldElement::ZERO, true);
let deploy_tx = contract_factory.deploy_v1(constructor_args, Felt::ZERO, true);

let deployed_address = deploy_tx.deployed_address();
deploy_tx
Expand Down

0 comments on commit f6c35c3

Please sign in to comment.