Skip to content

Commit

Permalink
Refactored call, deploy and invoke command handlers
Browse files Browse the repository at this point in the history
commit-id:13b07d29
  • Loading branch information
integraledelebesgue committed Oct 11, 2024
1 parent 22c7f8b commit 4717204
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 78 deletions.
16 changes: 16 additions & 0 deletions crates/sncast/src/helpers/fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@ pub enum FeeSettings {
},
}

impl From<ScriptFeeSettings> for FeeSettings {
fn from(value: ScriptFeeSettings) -> Self {
match value {
ScriptFeeSettings::Eth { max_fee } => FeeSettings::Eth { max_fee },
ScriptFeeSettings::Strk {
max_gas,
max_gas_unit_price,
..
} => FeeSettings::Strk {
max_gas,
max_gas_unit_price,
},
}
}
}

pub trait PayableTransaction {
fn error_message(&self, token: &str, version: &str) -> String;
fn validate(&self) -> Result<()>;
Expand Down
13 changes: 13 additions & 0 deletions crates/sncast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,19 @@ pub async fn get_account<'a>(
Ok(account)
}

pub async fn get_contract_class(
class_hash: Felt,
provider: &JsonRpcClient<HttpTransport>,
) -> Result<ContractClass> {
provider
.get_class(BlockId::Tag(BlockTag::Latest), class_hash)
.await
.map_err(handle_rpc_error)
.context(format!(
"Couldn't retrieve contract class with hash: {class_hash:#x}"
))
}

async fn build_account(
account_data: AccountData,
chain_id: Felt,
Expand Down
88 changes: 71 additions & 17 deletions crates/sncast/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use sncast::{
chain_id_to_network_name, get_account, get_block_id, get_chain_id, get_default_state_file_name,
NumbersFormat, ValidatedWaitParams, WaitForTx,
};
use starknet::accounts::ConnectedAccount;
use starknet::core::utils::get_selector_from_name;
use starknet::providers::Provider;
use starknet_commands::account::list::print_account_list;
Expand Down Expand Up @@ -221,9 +222,19 @@ async fn run_async_command(
}

Commands::Deploy(deploy) => {
let provider = deploy.rpc.get_provider(&config).await?;

deploy.validate()?;

let fee_token = deploy.token_from_version();

let Deploy {
constructor_calldata,
fee_args,
rpc,
..
} = deploy;

let provider = rpc.get_provider(&config).await?;

let account = get_account(
&config.account,
&config.accounts_file,
Expand All @@ -232,9 +243,24 @@ async fn run_async_command(
)
.await?;

let result = starknet_commands::deploy::deploy(deploy, &account, wait_config)
.await
.map_err(handle_starknet_command_error);
let fee_settings = fee_args
.clone()
.fee_token(fee_token)
.try_into_fee_settings(&provider, account.block_id())
.await?;

let result = starknet_commands::deploy::deploy(
deploy.class_hash,
&constructor_calldata,
deploy.salt,
deploy.unique,
fee_settings,
deploy.nonce,
&account,
wait_config,
)
.await
.map_err(handle_starknet_command_error);

print_command_result("deploy", &result, numbers_format, output_format)?;
print_block_explorer_link_if_allowed(
Expand All @@ -247,16 +273,24 @@ async fn run_async_command(
Ok(())
}

Commands::Call(call) => {
let provider = call.rpc.get_provider(&config).await?;
Commands::Call(Call {
contract_address,
function,
calldata,
block_id,
rpc,
}) => {
let provider = rpc.get_provider(&config).await?;

let block_id = get_block_id(&block_id)?;

let block_id = get_block_id(&call.block_id)?;
let entry_point_selector = get_selector_from_name(&function)
.context("Failed to convert entry point selector to FieldElement")?;

let result = starknet_commands::call::call(
call.contract_address,
get_selector_from_name(&call.function)
.context("Failed to convert entry point selector to FieldElement")?,
call.calldata,
contract_address,
entry_point_selector,
calldata,
&provider,
block_id.as_ref(),
)
Expand All @@ -268,21 +302,41 @@ async fn run_async_command(
}

Commands::Invoke(invoke) => {
let provider = invoke.rpc.get_provider(&config).await?;

invoke.validate()?;

let fee_token = invoke.token_from_version();

let Invoke {
contract_address,
function,
calldata,
fee_args,
rpc,
nonce,
..
} = invoke;

let provider = rpc.get_provider(&config).await?;

let account = get_account(
&config.account,
&config.accounts_file,
&provider,
config.keystore,
)
.await?;

let fee_args = fee_args.fee_token(fee_token);

let selector = get_selector_from_name(&function)
.context("Failed to convert entry point selector to FieldElement")?;

let result = starknet_commands::invoke::invoke(
invoke.clone(),
get_selector_from_name(&invoke.function)
.context("Failed to convert entry point selector to FieldElement")?,
contract_address,
calldata,
nonce,
fee_args,
selector,
&account,
wait_config,
)
Expand Down
17 changes: 13 additions & 4 deletions crates/sncast/src/starknet_commands/account/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use crate::starknet_commands::account::{
use anyhow::{ensure, Context, Result};
use camino::Utf8PathBuf;
use clap::Args;
use sncast::check_if_legacy_contract;
use sncast::helpers::configuration::CastConfig;
use sncast::helpers::rpc::RpcArgs;
use sncast::response::structs::AccountAddResponse;
use sncast::{check_class_hash_exists, get_chain_id};
use sncast::{check_if_legacy_contract, get_class_hash_by_address};
use starknet::core::types::Felt;
use sncast::{check_class_hash_exists, get_chain_id, handle_rpc_error};
use starknet::core::types::{BlockId, BlockTag, Felt, StarknetError};
use starknet::providers::jsonrpc::{HttpTransport, JsonRpcClient};
use starknet::providers::{Provider, ProviderError};
use starknet::signers::SigningKey;

#[derive(Args, Debug)]
Expand Down Expand Up @@ -79,7 +80,15 @@ pub async fn add(
);
}

let fetched_class_hash = get_class_hash_by_address(provider, add.address).await?;
let fetched_class_hash = match provider
.get_class_hash_at(BlockId::Tag(BlockTag::Pending), add.address)
.await
{
Ok(class_hash) => Ok(Some(class_hash)),
Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => Ok(None),
Err(err) => Err(handle_rpc_error(err)),
}?;

let deployed = fetched_class_hash.is_some();
let class_hash = match (fetched_class_hash, add.class_hash) {
(Some(from_provider), Some(from_user)) => {
Expand Down
35 changes: 16 additions & 19 deletions crates/sncast/src/starknet_commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,27 @@ impl_payable_transaction!(Deploy, token_not_supported_for_deployment,
DeployVersion::V3 => FeeToken::Strk
);

#[allow(clippy::ptr_arg, clippy::too_many_arguments)]
pub async fn deploy(
deploy: Deploy,
class_hash: Felt,
calldata: &Vec<Felt>,
salt: Option<Felt>,
unique: bool,
fee_settings: FeeSettings,
nonce: Option<Felt>,
account: &SingleOwnerAccount<&JsonRpcClient<HttpTransport>, LocalWallet>,
wait_config: WaitForTx,
) -> Result<DeployResponse, StarknetCommandError> {
let fee_settings = deploy
.fee_args
.clone()
.fee_token(deploy.token_from_version())
.try_into_fee_settings(account.provider(), account.block_id())
.await?;

let salt = extract_or_generate_salt(deploy.salt);
let factory = ContractFactory::new(deploy.class_hash, account);
let salt = extract_or_generate_salt(salt);
let factory = ContractFactory::new(class_hash, account);
let result = match fee_settings {
FeeSettings::Eth { max_fee } => {
let execution =
factory.deploy_v1(deploy.constructor_calldata.clone(), salt, deploy.unique);
let execution = factory.deploy_v1(calldata.clone(), salt, unique);
let execution = match max_fee {
None => execution,
Some(max_fee) => execution.max_fee(max_fee),
};
let execution = match deploy.nonce {
let execution = match nonce {
None => execution,
Some(nonce) => execution.nonce(nonce),
};
Expand All @@ -93,8 +91,7 @@ pub async fn deploy(
max_gas,
max_gas_unit_price,
} => {
let execution =
factory.deploy_v3(deploy.constructor_calldata.clone(), salt, deploy.unique);
let execution = factory.deploy_v3(calldata.clone(), salt, unique);

let execution = match max_gas {
None => execution,
Expand All @@ -104,7 +101,7 @@ pub async fn deploy(
None => execution,
Some(max_gas_unit_price) => execution.gas_price(max_gas_unit_price),
};
let execution = match deploy.nonce {
let execution = match nonce {
None => execution,
Some(nonce) => execution.nonce(nonce),
};
Expand All @@ -119,9 +116,9 @@ pub async fn deploy(
DeployResponse {
contract_address: get_udc_deployed_address(
salt,
deploy.class_hash,
&udc_uniqueness(deploy.unique, account.address()),
&deploy.constructor_calldata,
class_hash,
&udc_uniqueness(unique, account.address()),
calldata,
),
transaction_hash: result.transaction_hash,
},
Expand Down
16 changes: 7 additions & 9 deletions crates/sncast/src/starknet_commands/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,21 @@ impl_payable_transaction!(Invoke, token_not_supported_for_invoke,
);

pub async fn invoke(
invoke: Invoke,
contract_address: Felt,
calldata: Vec<Felt>,
nonce: Option<Felt>,
fee_args: FeeArgs,
function_selector: Felt,
account: &SingleOwnerAccount<&JsonRpcClient<HttpTransport>, LocalWallet>,
wait_config: WaitForTx,
) -> Result<InvokeResponse, StarknetCommandError> {
let fee_args = invoke
.fee_args
.clone()
.fee_token(invoke.token_from_version());

let call = Call {
to: invoke.contract_address,
to: contract_address,
selector: function_selector,
calldata: invoke.calldata.clone(),
calldata,
};

execute_calls(account, vec![call], fee_args, invoke.nonce, wait_config).await
execute_calls(account, vec![call], fee_args, nonce, wait_config).await
}

pub async fn execute_calls(
Expand Down
Loading

0 comments on commit 4717204

Please sign in to comment.