Skip to content
This repository was archived by the owner on Mar 13, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ cairo-felt = "0.8.0"
serde_with = "3.0.0"
starknet-core = "0.8.0"
tokio = { version = "1.5.0", features = ["sync", "rt", "macros"] }

starknet_in_rust = { git = "https://github.com/lambdaclass/starknet_in_rust" }
1 change: 1 addition & 0 deletions src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use starknet_core::types::{
// pub struct Felt(#[serde_as(as = "UfeHex")] pub Felt252);
pub mod serializable_types;
pub mod starknet_backend;
pub mod transactions;

use self::serializable_types::FeltParam;

Expand Down
57 changes: 45 additions & 12 deletions src/rpc/starknet_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,39 @@ use crate::rpc::{
BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction,
ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilterWithPage,
EventsPage, FeeEstimate, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes,
MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, StateUpdate,
SyncStatusType, Transaction,
MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, StateUpdate, SyncStatusType,
Transaction,
};
use cairo_felt::Felt252;
use jsonrpsee::
core::{async_trait, RpcResult};
use starknet_core::types::{TransactionStatus, SimulatedTransaction, SimulationFlag};
use jsonrpsee::{
core::{async_trait, RpcResult},
types::{error::ErrorCode, ErrorObject},
};
use starknet_core::types::{SimulatedTransaction, SimulationFlag, TransactionStatus};
use starknet_in_rust::{
services::api::contract_classes::compiled_class::CompiledClass,
state::{
cached_state::CachedState, contract_class_cache::PermanentContractClassCache,
in_memory_state_reader::InMemoryStateReader, state_api::StateReader,
},
utils::Address,
};

use super::StarknetRpcApiServer;

type StarknetState = CachedState<InMemoryStateReader, PermanentContractClassCache>;

pub struct StarknetBackend {
// mempool_handler: Mempool,
// store: Store,
state: StarknetState,
}

impl StarknetBackend {
pub fn new() -> StarknetBackend {
StarknetBackend {}
StarknetBackend {
state: Default::default(),
}
}
}

Expand All @@ -35,7 +50,6 @@ impl StarknetRpcApiServer for StarknetBackend {
unimplemented!()
}


/// Returns the execution trace of a transaction by simulating it in the runtime.
async fn simulate_transactions(
&self,
Expand Down Expand Up @@ -75,9 +89,12 @@ impl StarknetRpcApiServer for StarknetBackend {
&self,
contract_address: FeltParam,
key: FeltParam,
block_id: BlockId,
_block_id: BlockId,
) -> RpcResult<Felt252> {
unimplemented!();
let address = Address(contract_address.0);
self.state
.get_storage_at(&(address, key.0.to_be_bytes()))
.map_err(|_| ErrorObject::from(ErrorCode::InternalError))
}

fn call(&self, request: FunctionCall, block_id: BlockId) -> RpcResult<Vec<String>> {
Expand All @@ -87,10 +104,26 @@ impl StarknetRpcApiServer for StarknetBackend {
/// Get the contract class at a given contract address for a given block id
fn get_class_at(
&self,
block_id: BlockId,
_block_id: BlockId,
contract_address: FeltParam,
) -> RpcResult<ContractClass> {
unimplemented!();
let address = Address(contract_address.0);
let classhash = self
.state
.get_class_hash_at(&address)
.map_err(|_| ErrorObject::from(ErrorCode::InternalError))?;
let contract_class = self
.state
.get_contract_class(&classhash)
.map_err(|_| ErrorObject::from(ErrorCode::InternalError))?;

match contract_class {
CompiledClass::Deprecated(_) => {
todo!()
}
CompiledClass::Casm(_) => todo!(),
CompiledClass::Sierra(_) => todo!(),
}
}

/// Get the contract class hash in the given block for the contract deployed at the given
Expand Down Expand Up @@ -182,7 +215,7 @@ impl StarknetRpcApiServer for StarknetBackend {
async fn get_events(&self, filter: EventFilterWithPage) -> RpcResult<EventsPage> {
unimplemented!();
}
/// Add an Invoke Transaction to invoke a contract function
/// Add an Invoke Transaction to invoke a contract function
///
/// # Arguments
///
Expand Down
90 changes: 90 additions & 0 deletions src/rpc/transactions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::rpc::{BroadcastedTransaction, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction};
use starknet_in_rust::{
transaction::{DeployAccount, InvokeFunction, Transaction, Declare, DeclareV2},
utils::{Address, ClassHash},
Felt252,
};

// This must be removed when merged to "Added primitive store" PR
use starknet_core::types::FieldElement;

pub fn to_felt252(field_element: FieldElement) -> Felt252 {
Felt252::from_bytes_be(&field_element.to_bytes_be())
}

fn convert_to_invoke_transaction(invoke: BroadcastedInvokeTransaction) -> Transaction {
Transaction::InvokeFunction(InvokeFunction::new(
Address(to_felt252(invoke.calldata
.first()
.expect("Invoke does not contain contract address")
.clone())),
to_felt252(invoke.calldata
.get(1)
.expect("Invoke does not contain function selector")
.clone()),
invoke.max_fee.try_into().unwrap(),
Felt252::ZERO,
invoke.calldata[2..]
.iter()
.map(|&e| to_felt252(e))
.collect::<Vec<_>>(),
invoke.signature.iter().map(|&e| to_felt252(e)).collect::<Vec<_>>(),
Felt252::ZERO,
Some(to_felt252(invoke.nonce)),
)
.unwrap())
}

fn convert_deploy_transaction(deploy: BroadcastedDeployAccountTransaction) -> Transaction {
Transaction::DeployAccount(DeployAccount::new(
ClassHash::from(to_felt252(deploy.class_hash)),
deploy.max_fee.try_into().unwrap(),
Felt252::ZERO,
to_felt252(deploy.nonce),
deploy.constructor_calldata
.iter()
.map(|&e| to_felt252(e))
.collect::<Vec<_>>(),
deploy.signature.iter().map(|&e| to_felt252(e)).collect::<Vec<_>>(),
to_felt252(deploy.contract_address_salt),
Felt252::ZERO,
)
.unwrap())
}

fn convert_declare_transaction(declare: BroadcastedDeclareTransaction) -> Transaction {
match declare {
BroadcastedDeclareTransaction::V1(declare) => Transaction::Declare(Declare::new(
declare.contract_class,
Felt252::ZERO,
Address(to_felt252(declare.sender_address)),
declare.max_fee.try_into().unwrap(),
Felt252::ONE,
declare.signature.iter().map(|&e| to_felt252(e)).collect::<Vec<_>>(),
to_felt252(declare.nonce),
)
.unwrap()),
BroadcastedDeclareTransaction::V2(declare) => Transaction::DeclareV2(Box::new(
DeclareV2::new(
declare.contract_class,
casm_contract_class,
to_felt252(declare.compiled_class_hash),
Felt252::ZERO,
Address(to_felt252(declare.sender_address)),
declare.max_fee.try_into().unwrap(),
Felt252::TWO,
declare.signature.iter().map(|&e| to_felt252(e)).collect::<Vec<_>>(),
to_felt252(declare.nonce),
)
.unwrap(),
)),
}
}

pub fn convert_to_transaction(broadcasted_tx: BroadcastedTransaction) -> Transaction {
match broadcasted_tx {
BroadcastedTransaction::Invoke(invoke) => convert_to_invoke_transaction(invoke),
BroadcastedTransaction::DeployAccount(deploy) => convert_deploy_transaction(deploy),
BroadcastedTransaction::Declare(declare) => convert_declare_transaction(declare),
}
}