Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract execute_from_outside and upgrade #799

Merged
merged 2 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading