Skip to content

Commit

Permalink
feat: attach required amount of deposit for sign and limit gas fee …
Browse files Browse the repository at this point in the history
…for evm calls (#66)

* chore: we don't need attached deposit for calling `sign` method

* feat: determine the required deposit by calling `experimental_signature_deposit` method on mpc signer contract

* feat: limited fee for evm method calls (#69)

* feat: limited fee for evm method calls

* refactor: custom method that applies gas limits

* fix: parsed U128 properly
  • Loading branch information
frolvanya authored Jan 14, 2025
1 parent 2223030 commit f5eefcd
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ impl EvmBridgeClient {

assert!(serialized_signature.len() == 65);

let call = factory
let mut call = factory
.deploy_token(serialized_signature.into(), payload)
.gas(500_000);
self.apply_required_gas_fee(&mut call).await?;
let tx = call.send().await?;

tracing::info!(
Expand Down Expand Up @@ -180,7 +181,8 @@ impl EvmBridgeClient {
.map_or_else(String::new, |addr| addr.to_string()),
};

let call = factory.fin_transfer(signature.to_bytes().into(), bridge_deposit);
let mut call = factory.fin_transfer(signature.to_bytes().into(), bridge_deposit);
self.apply_required_gas_fee(&mut call).await?;
let tx = call.send().await?;

tracing::info!(
Expand Down Expand Up @@ -298,4 +300,43 @@ impl EvmBridgeClient {
.map_err(|_| BridgeSdkError::ConfigError("Invalid EVM private key".to_string()))?
.with_chain_id(*chain_id))
}

pub async fn get_required_gas_fee(&self) -> Result<(U256, U256)> {
let endpoint = self.endpoint()?;
let client = Provider::<Http>::try_from(endpoint)
.map_err(|_| BridgeSdkError::ConfigError("Invalid EVM rpc endpoint url".to_string()))?;

let response: std::result::Result<U256, ProviderError> =
client.request("eth_maxPriorityFeePerGas", ()).await;

let max_priority_fee_per_gas = match response {
Ok(fee) => fee,
Err(_) => U256::zero(),
};

let response = client.get_block(BlockNumber::Latest).await;

let base_fee_per_gas = match response {
Ok(Some(block)) => block.base_fee_per_gas.unwrap_or_default(),
_ => return Err(BridgeSdkError::UnknownError),
};

Ok((max_priority_fee_per_gas, base_fee_per_gas))
}

pub async fn apply_required_gas_fee<B, M, D>(
&self,
call: &mut FunctionCall<B, M, D>,
) -> Result<()> {
let (max_priority_fee_per_gas, base_fee_per_gas) = self.get_required_gas_fee().await?;

let Some(tx) = call.tx.as_eip1559_mut() else {
return Err(BridgeSdkError::UnknownError);
};

tx.max_priority_fee_per_gas = Some(max_priority_fee_per_gas);
tx.max_fee_per_gas = Some(base_fee_per_gas);

Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,32 @@ impl NearBridgeClient {
fee: Option<Fee>,
) -> Result<CryptoHash> {
let endpoint = self.endpoint()?;
let token_locker_id = self.token_locker_id_as_account_id()?;

let response = near_rpc_client::view(
endpoint,
ViewRequest {
contract_account_id: token_locker_id,
method_name: "get_mpc_account".to_string(),
args: serde_json::Value::Null,
},
)
.await?;

let mpc_account = serde_json::from_slice::<AccountId>(&response)?;

let response = near_rpc_client::view(
endpoint,
ViewRequest {
contract_account_id: mpc_account,
method_name: "experimental_signature_deposit".to_string(),
args: serde_json::Value::Null,
},
)
.await?;

let required_deposit = serde_json::from_slice::<String>(&response)
.map(|response| response.parse::<u128>().unwrap_or(SIGN_TRANSFER_DEPOSIT))?;

let tx_hash = near_rpc_client::change_and_wait(
endpoint,
Expand All @@ -378,7 +404,7 @@ impl NearBridgeClient {
.to_string()
.into_bytes(),
gas: SIGN_TRANSFER_GAS,
deposit: SIGN_TRANSFER_DEPOSIT, // TODO: make a contract call to signer account to determine the required deposit
deposit: required_deposit,
},
near_primitives::views::TxExecutionStatus::Executed,
)
Expand Down

0 comments on commit f5eefcd

Please sign in to comment.