Skip to content

Commit

Permalink
feat: support new APIs from StarkNet v0.8.0 (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI committed Mar 23, 2022
1 parent 33b903b commit b4e48ec
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

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

13 changes: 13 additions & 0 deletions starknet-core/src/types/fee.rs
@@ -0,0 +1,13 @@
use serde::Deserialize;

#[derive(Debug, Deserialize)]
pub struct FeeEstimate {
pub amount: u64,
pub unit: FeeUnit,
}

#[derive(Debug, Deserialize)]
pub enum FeeUnit {
#[serde(rename = "wei")]
Wei,
}
6 changes: 6 additions & 0 deletions starknet-core/src/types/mod.rs
Expand Up @@ -45,3 +45,9 @@ pub use state_update::StateUpdate;

pub mod contract_artifact;
pub use contract_artifact::ContractArtifact;

mod fee;
pub use fee::{FeeEstimate, FeeUnit};

pub mod trace;
pub use trace::TransactionTrace;
79 changes: 79 additions & 0 deletions starknet-core/src/types/trace.rs
@@ -0,0 +1,79 @@
use super::{super::serde::unsigned_field_element::UfeHex, EntryPointType, ExecutionResources};

use ethereum_types::Address;
use serde::Deserialize;
use serde_with::serde_as;
use starknet_crypto::FieldElement;

/// Represents the trace of a StarkNet transaction execution, including internal calls.
#[derive(Debug, Deserialize)]
pub struct TransactionTrace {
/// An object describing the invocation of a specific function.
pub function_invocation: FunctionInvocation,
pub signature: Vec<FieldElement>,
}

/// A lean version of CallInfo class, containing merely the information relevant for the user.
#[serde_as]
#[derive(Debug, Deserialize)]
pub struct FunctionInvocation {
#[serde_as(as = "UfeHex")]
pub caller_address: FieldElement,
#[serde_as(as = "UfeHex")]
pub contract_address: FieldElement,
#[serde_as(as = "Option<UfeHex>")]
pub code_address: Option<FieldElement>,
#[serde_as(as = "Option<UfeHex>")]
pub selector: Option<FieldElement>,
pub entry_point_type: Option<EntryPointType>,
#[serde_as(as = "Vec<UfeHex>")]
pub calldata: Vec<FieldElement>,
#[serde_as(as = "Vec<UfeHex>")]
pub result: Vec<FieldElement>,
pub execution_resources: ExecutionResources,
pub internal_calls: Vec<FunctionInvocation>,
pub events: Vec<OrderedEventResponse>,
pub messages: Vec<OrderedL2ToL1MessageResponse>,
}

#[serde_as]
#[derive(Debug, Deserialize)]
pub struct OrderedEventResponse {
pub order: u64,
#[serde_as(as = "Vec<UfeHex>")]
pub keys: Vec<FieldElement>,
#[serde_as(as = "Vec<UfeHex>")]
pub data: Vec<FieldElement>,
}

#[serde_as]
#[derive(Debug, Deserialize)]
pub struct OrderedL2ToL1MessageResponse {
pub order: u64,
pub to_address: Address,
#[serde_as(as = "Vec<UfeHex>")]
pub payload: Vec<FieldElement>,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn test_trace_deser_with_messages() {
serde_json::from_str::<TransactionTrace>(include_str!(
"../../test-data/raw_gateway_responses/get_transaction_trace/1_with_messages.txt"
))
.unwrap();
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn test_trace_deser_with_events() {
serde_json::from_str::<TransactionTrace>(include_str!(
"../../test-data/raw_gateway_responses/get_transaction_trace/2_with_events.txt"
))
.unwrap();
}
}
@@ -0,0 +1 @@
{"amount": 1630000000000, "unit": "wei"}
Expand Up @@ -63,3 +63,24 @@ curl -o ./get_full_contract/1_code.txt "https://alpha4.starknet.io/feeder_gatewa

# ./get_full_contract/2_all_abi_types.txt
curl -o ./get_full_contract/2_all_abi_types.txt "https://alpha4.starknet.io/feeder_gateway/get_full_contract?contractAddress=0x06ef97a90be1c0458f6e7bd1faf05021f2d81211f658155df0c5c97a39eb2d12"

# ./get_transaction_trace/1_with_messages.txt
curl -o ./get_transaction_trace/1_with_messages.txt "https://alpha4.starknet.io/feeder_gateway/get_transaction_trace?transactionHash=0x24052dd62bf28d6dfa7056fcc7208b27f7260099572bac42d716bf629f46991"

# ./get_transaction_trace/2_with_events.txt
curl -o ./get_transaction_trace/2_with_events.txt "https://alpha4.starknet.io/feeder_gateway/get_transaction_trace?transactionHash=0x688e434a1636c30d0c161f766b99b4bfb143208d859149859941905e94cb022"

# ./estimate_fee/1_success.txt
curl -o ./estimate_fee/1_success.txt "https://alpha4.starknet.io/feeder_gateway/estimate_fee" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"contract_address": "0x07394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10",
"entry_point_selector": "0x02f0b3c5710379609eb5495f1ecd348cb28167711b73609fe565a72734550354",
"calldata": [
"2536338608804621486891098924999890751656158566880912297504415061810375427475",
"1000000000000000000000",
"0"
],
"signature": []
}'
@@ -0,0 +1 @@
{"function_invocation": {"caller_address": "0x0", "contract_address": "0x40498ecb5a86ae60195db96c9b52166751ede5c20c6fa6523303d459429e438", "code_address": "0x40498ecb5a86ae60195db96c9b52166751ede5c20c6fa6523303d459429e438", "selector": "0x12ead94ae9d3f9d2bdb6b847cf255f1f398193a1f88884a0ae8e18f24a037b6", "entry_point_type": "EXTERNAL", "calldata": ["0xcbf9b25c0f4cb0b741ac4b2eab6be2cc2b3f1d76"], "result": [], "execution_resources": {"n_steps": 31, "builtin_instance_counter": {"pedersen_builtin": 0, "range_check_builtin": 0, "output_builtin": 0, "ecdsa_builtin": 0, "bitwise_builtin": 0, "ec_op_builtin": 0}, "n_memory_holes": 0}, "internal_calls": [], "events": [], "messages": [{"order": 0, "to_address": "0xcBf9B25c0f4cb0b741AC4B2eAB6BE2CC2B3F1d76", "payload": ["0xc", "0x22"]}]}, "signature": []}
@@ -0,0 +1 @@
{"function_invocation": {"caller_address": "0x0", "contract_address": "0x449c8f694001f99cea9302f2b1f6056879c48247fd1b27814c426ba3670740e", "code_address": "0x449c8f694001f99cea9302f2b1f6056879c48247fd1b27814c426ba3670740e", "selector": "0x240060cdb34fcc260f41eac7474ee1d7c80b7e3607daff9ac67c7ea2ebb1c44", "entry_point_type": "EXTERNAL", "calldata": ["0x47cfd9582fc4c7543d55d6853e8edee02ff72e233b4b2d4d42568ed4a68f9c0", "0x2f9bf85b08843c458690450fd7b221d0f793fa42db7245bbd08c0c12f85b60f", "0x1", "0x7394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10", "0x77"], "result": ["0x0"], "execution_resources": {"n_steps": 861, "builtin_instance_counter": {"pedersen_builtin": 12, "range_check_builtin": 13, "ecdsa_builtin": 1, "output_builtin": 0, "bitwise_builtin": 0, "ec_op_builtin": 0}, "n_memory_holes": 30}, "internal_calls": [{"caller_address": "0x449c8f694001f99cea9302f2b1f6056879c48247fd1b27814c426ba3670740e", "contract_address": "0x47cfd9582fc4c7543d55d6853e8edee02ff72e233b4b2d4d42568ed4a68f9c0", "code_address": "0x47cfd9582fc4c7543d55d6853e8edee02ff72e233b4b2d4d42568ed4a68f9c0", "selector": "0x2f9bf85b08843c458690450fd7b221d0f793fa42db7245bbd08c0c12f85b60f", "entry_point_type": "EXTERNAL", "calldata": ["0x7394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10"], "result": [], "execution_resources": {"n_steps": 427, "builtin_instance_counter": {"pedersen_builtin": 4, "range_check_builtin": 11, "ecdsa_builtin": 0, "output_builtin": 0, "bitwise_builtin": 0, "ec_op_builtin": 0}, "n_memory_holes": 30}, "internal_calls": [], "events": [{"order": 0, "keys": ["0x2d1d3dcc4fe9f25587df82853d883029e1453436eb63810ba4f444e76d7aa4a"], "data": ["0x7394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10", "0x61e7b372"]}], "messages": []}], "events": [], "messages": []}, "signature": ["220134563884515005302105515860459019567739214287456771965489940677218361665", "3370972961224919564221792417554667287706831396645945832805232310863238883193"]}
18 changes: 16 additions & 2 deletions starknet-providers/src/provider.rs
@@ -1,8 +1,9 @@
use async_trait::async_trait;
use starknet_core::types::{
AddTransactionResult, Block, BlockId, CallContractResult, ContractAddresses, ContractArtifact,
ContractCode, FieldElement, InvokeFunctionTransactionRequest, StateUpdate, TransactionInfo,
TransactionReceipt, TransactionRequest, TransactionStatusInfo,
ContractCode, FeeEstimate, FieldElement, InvokeFunctionTransactionRequest, StateUpdate,
TransactionInfo, TransactionReceipt, TransactionRequest, TransactionStatusInfo,
TransactionTrace,
};
use std::error::Error;

Expand All @@ -24,6 +25,12 @@ pub trait Provider {
block_identifier: BlockId,
) -> Result<CallContractResult, Self::Error>;

async fn estimate_fee(
&self,
invoke_tx: InvokeFunctionTransactionRequest,
block_identifier: BlockId,
) -> Result<FeeEstimate, Self::Error>;

async fn get_block(&self, block_identifier: BlockId) -> Result<Block, Self::Error>;

async fn get_state_update(&self, block_identifier: BlockId)
Expand Down Expand Up @@ -63,6 +70,11 @@ pub trait Provider {
transaction_hash: FieldElement,
) -> Result<TransactionReceipt, Self::Error>;

async fn get_transaction_trace(
&self,
transaction_hash: FieldElement,
) -> Result<TransactionTrace, Self::Error>;

async fn get_block_hash_by_id(&self, block_number: u64) -> Result<FieldElement, Self::Error>;

async fn get_block_id_by_hash(&self, block_hash: FieldElement) -> Result<u64, Self::Error>;
Expand All @@ -78,4 +90,6 @@ pub trait Provider {
) -> Result<u64, Self::Error>;

async fn get_last_batch_id(&self) -> Result<u64, Self::Error>;

async fn get_l1_blockchain_id(&self) -> Result<u64, Self::Error>;
}
67 changes: 64 additions & 3 deletions starknet-providers/src/sequencer_gateway.rs
Expand Up @@ -9,9 +9,9 @@ use starknet_core::{
serde::unsigned_field_element::UfeHex,
types::{
AddTransactionResult, Block, BlockId, CallContractResult, ContractAddresses,
ContractArtifact, ContractCode, FieldElement, InvokeFunctionTransactionRequest,
StarknetError, StateUpdate, TransactionInfo, TransactionReceipt, TransactionRequest,
TransactionStatusInfo,
ContractArtifact, ContractCode, FeeEstimate, FieldElement,
InvokeFunctionTransactionRequest, StarknetError, StateUpdate, TransactionInfo,
TransactionReceipt, TransactionRequest, TransactionStatusInfo, TransactionTrace,
},
};
use thiserror::Error;
Expand Down Expand Up @@ -188,6 +188,22 @@ impl Provider for SequencerGatewayProvider {
}
}

async fn estimate_fee(
&self,
invoke_tx: InvokeFunctionTransactionRequest,
block_identifier: BlockId,
) -> Result<FeeEstimate, Self::Error> {
let mut request_url = self.extend_feeder_gateway_url("estimate_fee");
append_block_id(&mut request_url, block_identifier);

match self.send_post_request(request_url, &invoke_tx).await? {
GatewayResponse::Data(data) => Ok(data),
GatewayResponse::StarknetError(starknet_err) => {
Err(ProviderError::StarknetError(starknet_err))
}
}
}

async fn get_block(&self, block_identifier: BlockId) -> Result<Block, Self::Error> {
let mut request_url = self.extend_feeder_gateway_url("get_block");
append_block_id(&mut request_url, block_identifier);
Expand Down Expand Up @@ -353,6 +369,23 @@ impl Provider for SequencerGatewayProvider {
}
}

async fn get_transaction_trace(
&self,
transaction_hash: FieldElement,
) -> Result<TransactionTrace, Self::Error> {
let mut request_url = self.extend_feeder_gateway_url("get_transaction_trace");
request_url
.query_pairs_mut()
.append_pair("transactionHash", &format!("{:#x}", transaction_hash));

match self.send_get_request(request_url).await? {
GatewayResponse::Data(trace) => Ok(trace),
GatewayResponse::StarknetError(starknet_err) => {
Err(ProviderError::StarknetError(starknet_err))
}
}
}

async fn get_block_hash_by_id(&self, block_number: u64) -> Result<FieldElement, Self::Error> {
let mut request_url = self.extend_feeder_gateway_url("get_block_hash_by_id");
request_url
Expand Down Expand Up @@ -440,6 +473,20 @@ impl Provider for SequencerGatewayProvider {
}
}
}

async fn get_l1_blockchain_id(&self) -> Result<u64, Self::Error> {
let request_url = self.extend_feeder_gateway_url("get_l1_blockchain_id");

match self
.send_get_request::<GatewayResponse<u64>>(request_url)
.await?
{
GatewayResponse::Data(network_id) => Ok(network_id),
GatewayResponse::StarknetError(starknet_err) => {
Err(ProviderError::StarknetError(starknet_err))
}
}
}
}

fn extend_url(url: &mut Url, segment: &str) {
Expand All @@ -464,3 +511,17 @@ fn append_block_id(url: &mut Url, block_identifier: BlockId) {
BlockId::Latest => (), // latest block is implicit
};
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn test_estimate_fee_deser() {
serde_json::from_str::<GatewayResponse<FeeEstimate>>(include_str!(
"../test-data/estimate_fee/1_success.txt"
))
.unwrap();
}
}
1 change: 1 addition & 0 deletions starknet-providers/test-data

0 comments on commit b4e48ec

Please sign in to comment.