Skip to content

Commit

Permalink
Extract execute_from_outside and upgrade (#799)
Browse files Browse the repository at this point in the history
* Refactor execute_from_outside

* Extract upgrade
  • Loading branch information
tarrencev authored Oct 2, 2024
1 parent 078057d commit 1ac2995
Show file tree
Hide file tree
Showing 24 changed files with 293 additions and 278 deletions.
24 changes: 14 additions & 10 deletions packages/account-wasm/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::fmt;

use account_sdk::{errors::ControllerError, paymaster::PaymasterError, signers::DeviceError};
use account_sdk::{
errors::ControllerError, provider::ExecuteFromOutsideError, signers::DeviceError,
};
use serde::Serialize;
use starknet::{accounts::AccountError, core::types::StarknetError, providers::ProviderError};
use starknet_types_core::felt::FromStrError;
Expand Down Expand Up @@ -155,31 +157,33 @@ impl From<ControllerError> for JsControllerError {
}
}

impl From<PaymasterError> for JsControllerError {
fn from(error: PaymasterError) -> Self {
impl From<ExecuteFromOutsideError> for JsControllerError {
fn from(error: ExecuteFromOutsideError) -> Self {
let (code, message) = match error {
PaymasterError::ExecutionTimeNotReached => (
ExecuteFromOutsideError::ExecutionTimeNotReached => (
ErrorCode::PaymasterExecutionTimeNotReached,
"Execution time not yet reached".to_string(),
),
PaymasterError::ExecutionTimePassed => (
ExecuteFromOutsideError::ExecutionTimePassed => (
ErrorCode::PaymasterExecutionTimePassed,
"Execution time has passed".to_string(),
),
PaymasterError::InvalidCaller => (
ExecuteFromOutsideError::InvalidCaller => (
ErrorCode::PaymasterInvalidCaller,
"Invalid caller".to_string(),
),
PaymasterError::RateLimitExceeded => (
ExecuteFromOutsideError::RateLimitExceeded => (
ErrorCode::PaymasterRateLimitExceeded,
"Rate limit exceeded".to_string(),
),
PaymasterError::PaymasterNotSupported => (
ExecuteFromOutsideError::ExecuteFromOutsideNotSupported => (
ErrorCode::PaymasterNotSupported,
"Paymaster not supported".to_string(),
),
PaymasterError::Serialization(e) => (ErrorCode::PaymasterSerialization, e.to_string()),
PaymasterError::ProviderError(e) => return e.into(),
ExecuteFromOutsideError::Serialization(e) => {
(ErrorCode::PaymasterSerialization, e.to_string())
}
ExecuteFromOutsideError::ProviderError(e) => return e.into(),
};

JsControllerError {
Expand Down
6 changes: 0 additions & 6 deletions packages/account_sdk/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ pub mod session;
use crate::abigen;
use crate::signers::SignError;

#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait AccountHashSigner {
async fn sign_hash(&self, hash: Felt) -> Result<Vec<Felt>, SignError>;
}

pub enum CallEncoder {}

impl CallEncoder {
Expand Down
4 changes: 4 additions & 0 deletions packages/account_sdk/src/account/session/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ impl Session {
session_key_guid: signer.guid(),
})
}

fn allowed_method_hash_rev_1() -> Felt {
selector!("\"Allowed Method\"(\"Contract Address\":\"ContractAddress\",\"selector\":\"selector\")")
}

pub fn raw(&self) -> RawSession {
RawSession {
expires_at: self.expires_at,
Expand All @@ -72,6 +74,7 @@ impl Session {
session_key_guid: self.session_key_guid,
}
}

pub fn message_hash(
&self,
tx_hash: Felt,
Expand All @@ -83,6 +86,7 @@ impl Session {
Poseidon::hades_permutation(&mut msg_hash);
Ok(msg_hash[0])
}

pub fn single_proof(&self, policy: &Policy) -> Option<Vec<Felt>> {
self.policies
.iter()
Expand Down
1 change: 1 addition & 0 deletions packages/account_sdk/src/account/session/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl MerkleTree {
};
}
}

pub fn compute_proof(leaves: Vec<Felt>, index: usize) -> Vec<Felt> {
let mut proof = vec![];
compute_proof(leaves, index, &mut proof);
Expand Down
66 changes: 7 additions & 59 deletions packages/account_sdk/src/controller.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::abigen::controller::{OutsideExecution, Owner, SignerSignature};
use crate::account::outside_execution::{OutsideExecutionAccount, OutsideExecutionCaller};
use crate::abigen::controller::{Owner, SignerSignature};
use crate::account::session::hash::Policy;
use crate::account::{AccountHashAndCallsSigner, CallEncoder};
use crate::constants::{ETH_CONTRACT_ADDRESS, WEBAUTHN_GAS};
Expand All @@ -9,10 +8,8 @@ use crate::provider::CartridgeProvider;
use crate::signers::Signer;
use crate::storage::StorageValue;
use crate::typed_data::TypedData;
use crate::utils::time::get_current_timestamp;
use crate::{
abigen::{self},
account::AccountHashSigner,
signers::{HashSigner, SignError, SignerTrait},
};
use crate::{impl_account, Backend};
Expand All @@ -29,9 +26,12 @@ use starknet::signers::SignerInteractivityContext;
use starknet::{
accounts::{Account, ConnectedAccount, ExecutionEncoder},
core::types::{BlockId, Felt},
signers::SigningKey,
};

#[cfg(test)]
#[path = "controller_test.rs"]
mod controller_test;

#[derive(Clone)]
pub struct Controller<P, B>
where
Expand Down Expand Up @@ -116,42 +116,6 @@ where
self.owner.signer().guid()
}

async fn execute_from_outside_raw(
&self,
outside_execution: OutsideExecution,
) -> Result<InvokeTransactionResult, ControllerError> {
let signed = self
.sign_outside_execution(outside_execution.clone())
.await?;

let res = self
.provider()
.add_execute_outside_transaction(outside_execution, self.address, signed.signature)
.await
.map_err(ControllerError::PaymasterError)?;

Ok(InvokeTransactionResult {
transaction_hash: res.transaction_hash,
})
}

pub async fn execute_from_outside(
&self,
calls: Vec<Call>,
) -> Result<InvokeTransactionResult, ControllerError> {
let now = get_current_timestamp();

let outside_execution = OutsideExecution {
caller: OutsideExecutionCaller::Any.into(),
execute_after: 0,
execute_before: now + 600,
calls: calls.into_iter().map(|call| call.into()).collect(),
nonce: SigningKey::from_random().secret_scalar(),
};

self.execute_from_outside_raw(outside_execution).await
}

pub async fn estimate_invoke_fee(
&self,
calls: Vec<Call>,
Expand Down Expand Up @@ -297,11 +261,8 @@ where

pub async fn sign_message(&self, data: TypedData) -> Result<Vec<Felt>, SignError> {
let hash = data.encode(self.address)?;
self.sign_hash(hash).await
}

pub fn upgrade(&self, new_class_hash: Felt) -> Call {
self.contract().upgrade_getcall(&new_class_hash.into())
let signature = self.owner.sign(&hash).await?;
Ok(Vec::<SignerSignature>::cairo_serialize(&vec![signature]))
}
}

Expand Down Expand Up @@ -368,16 +329,3 @@ where
CallEncoder::encode_calls(calls)
}
}

#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl<P, B> AccountHashSigner for Controller<P, B>
where
P: CartridgeProvider + Send + Sync + Clone,
B: Backend + Clone,
{
async fn sign_hash(&self, hash: Felt) -> Result<Vec<Felt>, SignError> {
let signature = self.owner.sign(&hash).await?;
Ok(Vec::<SignerSignature>::cairo_serialize(&vec![signature]))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
signers::Signer,
storage::InMemoryBackend,
tests::runners::katana::KatanaRunner,
transaction_waiter::TransactionWaiter,
tests::transaction_waiter::TransactionWaiter,
};
use starknet::{accounts::Account, macros::felt, providers::Provider, signers::SigningKey};
use starknet_crypto::Felt;
Expand Down
4 changes: 2 additions & 2 deletions packages/account_sdk/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use starknet::{
providers::ProviderError,
};

use crate::{paymaster::PaymasterError, signers::SignError};
use crate::{provider::ExecuteFromOutsideError, signers::SignError};

#[derive(Debug, thiserror::Error)]
pub enum ControllerError {
Expand All @@ -28,7 +28,7 @@ pub enum ControllerError {
AccountFactoryError(#[from] AccountFactoryError<SignError>),

#[error(transparent)]
PaymasterError(#[from] PaymasterError),
PaymasterError(#[from] ExecuteFromOutsideError),

#[error(transparent)]
CairoSerde(#[from] cairo_serde::Error),
Expand Down
61 changes: 61 additions & 0 deletions packages/account_sdk/src/execute_from_outside.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use starknet::{
accounts::ConnectedAccount,
core::types::{Call, InvokeTransactionResult},
signers::SigningKey,
};

use crate::{
abigen::controller::OutsideExecution,
account::outside_execution::{OutsideExecutionAccount, OutsideExecutionCaller},
controller::Controller,
errors::ControllerError,
provider::CartridgeProvider,
utils::time::get_current_timestamp,
Backend,
};

#[cfg(test)]
#[path = "execute_from_outside_test.rs"]
mod execute_from_outside_test;

impl<P, B> Controller<P, B>
where
P: CartridgeProvider + Send + Sync + Clone,
B: Backend + Clone,
{
async fn execute_from_outside_raw(
&self,
outside_execution: OutsideExecution,
) -> Result<InvokeTransactionResult, ControllerError> {
let signed = self
.sign_outside_execution(outside_execution.clone())
.await?;

let res = self
.provider()
.add_execute_outside_transaction(outside_execution, self.address, signed.signature)
.await
.map_err(ControllerError::PaymasterError)?;

Ok(InvokeTransactionResult {
transaction_hash: res.transaction_hash,
})
}

pub async fn execute_from_outside(
&self,
calls: Vec<Call>,
) -> Result<InvokeTransactionResult, ControllerError> {
let now = get_current_timestamp();

let outside_execution = OutsideExecution {
caller: OutsideExecutionCaller::Any.into(),
execute_after: 0,
execute_before: now + 600,
calls: calls.into_iter().map(|call| call.into()).collect(),
nonce: SigningKey::from_random().secret_scalar(),
};

self.execute_from_outside_raw(outside_execution).await
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use starknet::{
use crate::abigen::erc_20::Erc20;
use crate::tests::account::FEE_TOKEN_ADDRESS;
use crate::tests::runners::katana::KatanaRunner;
use crate::transaction_waiter::TransactionWaiter;
use crate::tests::transaction_waiter::TransactionWaiter;
use crate::{artifacts::Version, signers::Signer};
use cainome::cairo_serde::{CairoSerde, ContractAddress, U256};

#[tokio::test]
async fn test_paymaster_request_success() {
async fn test_execute_from_outside() {
let signer = Signer::new_starknet_random();
let runner = KatanaRunner::load();
let controller = runner
Expand Down
4 changes: 2 additions & 2 deletions packages/account_sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ pub mod artifacts;
pub mod constants;
pub mod controller;
pub mod errors;
pub mod execute_from_outside;
pub mod factory;
pub mod hash;
pub mod paymaster;
pub mod provider;
pub mod session;
pub mod signers;
pub mod storage;
mod transaction_waiter;
pub mod typed_data;
pub mod upgrade;
pub mod utils;

#[cfg(not(target_arch = "wasm32"))]
Expand Down
Loading

0 comments on commit 1ac2995

Please sign in to comment.