Skip to content

Commit

Permalink
Merge pull request #269 from neotheprogramist/add/starknet-hive-with-…
Browse files Browse the repository at this point in the history
…custom-acc

Add/starknet hive with custom acc
  • Loading branch information
piotr-stec authored Jan 29, 2025
2 parents cc368ac + 51320aa commit 256b794
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 9 deletions.
138 changes: 131 additions & 7 deletions openrpc-testgen/src/utils/starknet_hive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use std::sync::Arc;
use super::v7::{
accounts::{
account::{
Account, ConnectedAccount, DeclarationV2, DeclarationV3, ExecutionEncoder, ExecutionV1,
ExecutionV3, RawDeclarationV2, RawDeclarationV3, RawExecutionV1, RawExecutionV3,
Account, AccountError, ConnectedAccount, DeclarationV2, DeclarationV3,
ExecutionEncoder, ExecutionV1, ExecutionV3, RawDeclarationV2, RawDeclarationV3,
RawExecutionV1, RawExecutionV3,
},
call::Call,
creation::{
Expand All @@ -18,6 +19,10 @@ use super::v7::{
single_owner::{ExecutionEncoding, SingleOwnerAccount},
},
endpoints::{
declare_contract::{
extract_class_hash_from_error, get_compiled_contract_from_string,
parse_class_hash_from_error, RunnerError,
},
errors::OpenRpcTestGenError,
utils::{get_selector_from_name, wait_for_sent_transaction},
},
Expand All @@ -36,11 +41,11 @@ const STRK: Felt =
Felt::from_hex_unchecked("0x4718F5A0FC34CC1AF16A1CDEE98FFB20C31F5CD61D6AB07201858F4287C938D");

#[derive(Debug)]
pub struct StarkneHive {
pub struct StarknetHive {
pub account: SingleOwnerAccount<JsonRpcClient<HttpTransport>, LocalWallet>,
}

impl StarkneHive {
impl StarknetHive {
pub async fn new(
node_url: Url,
paymaster_account_address: Felt,
Expand Down Expand Up @@ -106,15 +111,134 @@ impl StarkneHive {
);
Ok(Self { account })
}

pub async fn new_with_custom_account(
node_url: Url,
paymaster_account_address: Felt,
paymaster_private_key: Felt,
sierra: String,
casm: String,
) -> Result<Self, OpenRpcTestGenError> {
let provider = JsonRpcClient::new(HttpTransport::new(node_url.clone()));
let chain_id = get_chain_id(&provider).await?;
let paymaster_private_key = SigningKey::from_secret_scalar(paymaster_private_key);

let mut paymaster_account = SingleOwnerAccount::new(
provider.clone(),
LocalWallet::from(paymaster_private_key),
paymaster_account_address,
chain_id,
ExecutionEncoding::New,
);
paymaster_account.set_block_id(BlockId::Tag(BlockTag::Pending));

let (flattened_sierra_class, compiled_class_hash) =
get_compiled_contract_from_string(sierra, casm).await?;

let custom_account_class_hash = match paymaster_account
.declare_v3(flattened_sierra_class.clone(), compiled_class_hash)
.send()
.await
{
Ok(result) => {
wait_for_sent_transaction(result.transaction_hash, &paymaster_account).await?;
Ok(result.class_hash)
}
Err(AccountError::Signing(sign_error)) => {
if sign_error.to_string().contains("is already declared") {
Ok(parse_class_hash_from_error(&sign_error.to_string())?)
} else {
Err(OpenRpcTestGenError::RunnerError(
RunnerError::AccountFailure(format!(
"Transaction execution error: {}",
sign_error
)),
))
}
}

Err(AccountError::Provider(ProviderError::Other(starkneterror))) => {
if starkneterror.to_string().contains("is already declared") {
Ok(parse_class_hash_from_error(&starkneterror.to_string())?)
} else {
Err(OpenRpcTestGenError::RunnerError(
RunnerError::AccountFailure(format!(
"Transaction execution error: {}",
starkneterror
)),
))
}
}
Err(e) => {
let full_error_message = format!("{:?}", e);

if full_error_message.contains("is already declared") {
Ok(extract_class_hash_from_error(&full_error_message)?)
} else {
let full_error_message = format!("{:?}", e);

return Err(OpenRpcTestGenError::AccountError(AccountError::Other(
full_error_message,
)));
}
}
};

let account_data = create_account(
&provider,
AccountType::Oz,
Option::None,
Some(custom_account_class_hash?),
)
.await?;

let transfer_amount = Felt::from_hex("0xfffffffffffffff")?;

let transfer_execution = paymaster_account
.execute_v3(vec![Call {
to: STRK,
selector: get_selector_from_name("transfer")?,
calldata: vec![account_data.address, transfer_amount, Felt::ZERO],
}])
.send()
.await?;

wait_for_sent_transaction(transfer_execution.transaction_hash, &paymaster_account).await?;

let wait_config = WaitForTx {
wait: true,
wait_params: ValidatedWaitParams::default(),
};

let deployment_hash = deploy_account(
&provider,
chain_id,
wait_config,
account_data,
DeployAccountVersion::V3,
)
.await?;

wait_for_sent_transaction(deployment_hash, &paymaster_account).await?;

let account = SingleOwnerAccount::new(
provider.clone(),
LocalWallet::from(account_data.signing_key),
account_data.address,
chain_id,
ExecutionEncoding::New,
);
Ok(Self { account })
}
}

impl ExecutionEncoder for StarkneHive {
impl ExecutionEncoder for StarknetHive {
fn encode_calls(&self, calls: &[Call]) -> Vec<Felt> {
self.account.encode_calls(calls)
}
}

impl Account for StarkneHive {
impl Account for StarknetHive {
type SignError =
<SingleOwnerAccount<JsonRpcClient<HttpTransport>, LocalWallet> as Account>::SignError;

Expand Down Expand Up @@ -194,7 +318,7 @@ impl Account for StarkneHive {
}
}

impl ConnectedAccount for StarkneHive {
impl ConnectedAccount for StarknetHive {
type Provider = JsonRpcClient<HttpTransport>;

fn provider(&self) -> &Self::Provider {
Expand Down
17 changes: 15 additions & 2 deletions openrpc-testgen/src/utils/v7/endpoints/declare_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,21 @@ pub async fn get_compiled_contract(
let contract_artifact: SierraClass = serde_json::from_str(&sierra)?;
let compiled_class: CompiledClass = serde_json::from_str(&casm)?;

let casm_class_hash = compiled_class.class_hash().unwrap();
let flattened_class = contract_artifact.clone().flatten().unwrap();
let casm_class_hash = compiled_class.class_hash()?;
let flattened_class = contract_artifact.clone().flatten()?;

Ok((flattened_class, casm_class_hash))
}

pub async fn get_compiled_contract_from_string(
sierra: String,
casm: String,
) -> Result<(ContractClass<Felt>, TxnHash<Felt>), RunnerError> {
let contract_artifact: SierraClass = serde_json::from_str(&sierra)?;
let compiled_class: CompiledClass = serde_json::from_str(&casm)?;

let casm_class_hash = compiled_class.class_hash()?;
let flattened_class = contract_artifact.clone().flatten()?;

Ok((flattened_class, casm_class_hash))
}
Expand Down

0 comments on commit 256b794

Please sign in to comment.