Skip to content

Commit

Permalink
feat: test Safe against Sepolia and Sepolia
Browse files Browse the repository at this point in the history
  • Loading branch information
chris13524 committed Sep 11, 2024
1 parent c921dbd commit 48efea0
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 33 deletions.
3 changes: 2 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ BUNDLER_API_KEY=""
BUNDLER_BASE_URL=""
RPC_API_KEY=""
RPC_BASE_URL=""
FAUCET_MNEMONIC=""
PIMLICO_API_KEY=""
PIMLICO_BUNDLER_URL=""
PIMLICO_RPC_URL=""
PIMLICO_RPC_URL=""
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ jobs:
- run: while ! curl localhost:8545/health; do sleep 1; done
- run: while ! curl localhost:4337/health; do sleep 1; done
- run: while ! curl localhost:3000/ping; do sleep 1; done
- run: cargo build --workspace --all-features --all-targets
- run: cargo test --all-features --lib --bins
# - run: cargo clippy --workspace --all-features --all-targets -- -D warnings
- run: cargo build --workspace --features=full --all-targets
- run: cargo test --features=full --lib --bins
# - run: cargo clippy --workspace --features=full --all-targets -- -D warnings
- run: cargo +nightly fmt --all -- --check

udeps:
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
# - run: rustup target add wasm32-unknown-unknown
# - run: git submodule update --init --recursive
# - run: make setup-thirdparty
# - run: cargo build --workspace --all-features --lib --bins --target wasm32-unknown-unknown --exclude=ffi
# - run: cargo build --workspace --features=full --lib --bins --target wasm32-unknown-unknown --exclude=ffi

build_swift_and_test:
name: Swift Package - latest
Expand Down
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,35 @@ After installing the dependencies, clone the repository and run the following co
make setup
```

This will fetch the third party dependencies and build the project, including the Swift bindings.
This will fetch the third party dependencies and build the project, including the Swift bindings.

### Devloop

During normal development you can use the `just devloop` command to test your code both during development and before comitting/pushing. This is handy as it runs as many checks as possible and fixes any issues (such as formatting) automatically.

This command does not require any configuration.

```bash
just devloop
```

TODO: make this setup anvil automatically

### Specific tests

Some tests require some configuration (such as funds on Sepolia). For these, supply `FAUCET_MNEMONIC` and add some funds on the account.

#### Pimlico/Sepolia

```bash
just test-pimlico-api
```

Required environment variables:

```text
FAUCET_MNEMONIC
PIMLICO_API_KEY
PIMLICO_BUNDLER_URL
PIMLICO_RPC_URL
```
4 changes: 4 additions & 0 deletions crates/yttrium/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ version.workspace = true
edition.workspace = true
rust-version.workspace = true

[features]
full = []
test_pimlico_api = []

[dependencies]
# Ethereum
alloy = { git = "https://github.com/alloy-rs/alloy", version = "0.3.2", features = [
Expand Down
127 changes: 105 additions & 22 deletions crates/yttrium/src/transaction/send/safe_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ mod tests {
use alloy::{
consensus::{SignableTransaction, TxEip7702},
dyn_abi::{DynSolValue, Eip712Domain},
network::{Ethereum, TxSignerSync},
network::{Ethereum, EthereumWallet, TransactionBuilder, TxSignerSync},
primitives::{
aliases::U48, Address, Bytes, FixedBytes, Uint, U128, U256, U64,
},
providers::{
ext::AnvilApi, PendingTransactionConfig, Provider, ReqwestProvider,
ext::AnvilApi, PendingTransactionConfig, Provider, ProviderBuilder,
ReqwestProvider,
},
rpc::types::TransactionRequest,
signers::{k256::ecdsa::SigningKey, local::LocalSigner, SignerSync},
sol,
sol_types::{SolCall, SolValue},
Expand All @@ -81,9 +83,8 @@ mod tests {
owner: LocalSigner<SigningKey>,
address: Option<Address>,
authorization_list: Option<Vec<Authorization>>,
config: Config,
) -> eyre::Result<String> {
let config = crate::config::Config::local();

let bundler_base_url = config.endpoints.bundler.base_url;
let paymaster_base_url = config.endpoints.paymaster.base_url;

Expand Down Expand Up @@ -449,11 +450,40 @@ mod tests {
Ok(user_operation_hash)
}

#[tokio::test]
async fn test_send_transaction() -> eyre::Result<()> {
let rpc_url = Config::local().endpoints.rpc.base_url;
let rpc_url: reqwest::Url = rpc_url.parse()?;
let provider = ReqwestProvider::<Ethereum>::new_http(rpc_url);
async fn use_faucet(
provider: ReqwestProvider,
faucet: LocalSigner<SigningKey>,
amount: U256,
to: Address,
) -> eyre::Result<()> {
if amount > U256::from(20) {
panic!("You probably don't need that much");
}
println!("address: {}", faucet.address());

ProviderBuilder::new()
.with_recommended_fillers()
.wallet(EthereumWallet::new(faucet))
.on_provider(provider.clone())
.send_transaction(
TransactionRequest::default().with_to(to).with_value(amount),
)
.await?
.watch()
.await?;
let balance = provider.get_balance(to).await?;
assert_eq!(balance, amount);

Ok(())
}

async fn test_send_transaction(
config: Config,
faucet: LocalSigner<SigningKey>,
) -> eyre::Result<()> {
let provider = ReqwestProvider::<Ethereum>::new_http(
config.endpoints.rpc.base_url.parse()?,
);

let destination = LocalSigner::random();
let balance = provider.get_balance(destination.address()).await?;
Expand All @@ -466,30 +496,42 @@ mod tests {
)
.await;

provider.anvil_set_balance(sender_address, U256::from(100)).await?;
use_faucet(
provider.clone(),
faucet.clone(),
U256::from(2),
sender_address,
)
.await?;

let transaction = vec![Execution {
target: destination.address(),
value: Uint::from(1),
callData: Bytes::new(),
}];

let transaction_hash =
send_transaction(transaction, owner.clone(), None, None).await?;
let transaction_hash = send_transaction(
transaction,
owner.clone(),
None,
None,
config.clone(),
)
.await?;

println!("Transaction sent: {}", transaction_hash);

let balance = provider.get_balance(destination.address()).await?;
assert_eq!(balance, Uint::from(1));

provider.anvil_set_balance(sender_address, U256::from(100)).await?;
let transaction = vec![Execution {
target: destination.address(),
value: Uint::from(1),
callData: Bytes::new(),
}];

let transaction_hash =
send_transaction(transaction, owner, None, None).await?;
send_transaction(transaction, owner, None, None, config).await?;

println!("Transaction sent: {}", transaction_hash);

Expand All @@ -499,12 +541,43 @@ mod tests {
Ok(())
}

async fn anvil_faucet(config: Config) -> LocalSigner<SigningKey> {
let faucet = LocalSigner::random();
let provider = ReqwestProvider::<Ethereum>::new_http(
config.endpoints.rpc.base_url.parse().unwrap(),
);
provider.anvil_set_balance(faucet.address(), U256::MAX).await.unwrap();
faucet
}

#[tokio::test]
async fn test_send_transaction_local() {
let config = Config::local();
let faucet = anvil_faucet(config.clone()).await;
test_send_transaction(config, faucet).await.unwrap();
}

#[tokio::test]
#[cfg(feature = "test_pimlico_api")]
async fn test_send_transaction_pimlico() {
let config = Config::pimlico();
let faucet = MnemonicBuilder::<English>::default()
.phrase(
std::env::var("FAUCET_MNEMONIC")
.expect("You've not set the FAUCET_MNEMONIC"),
)
.build()
.unwrap();
test_send_transaction(config, faucet).await.unwrap();
}

#[tokio::test]
#[ignore]
async fn test_send_transaction_7702() -> eyre::Result<()> {
let rpc_url = Config::local().endpoints.rpc.base_url;
let rpc_url: reqwest::Url = rpc_url.parse()?;
let provider = ReqwestProvider::<Ethereum>::new_http(rpc_url);
let config = Config::local();
let provider = ReqwestProvider::<Ethereum>::new_http(
config.endpoints.rpc.base_url.parse()?,
);

let destination = LocalSigner::random();
let balance = provider.get_balance(destination.address()).await?;
Expand Down Expand Up @@ -558,6 +631,7 @@ mod tests {
Some(authority.address()),
Some(authorization_list.clone()),
// None,
config.clone(),
)
.await?;
println!("Transaction sent: {}", transaction_hash);
Expand Down Expand Up @@ -585,6 +659,7 @@ mod tests {
// None,
// Some(authorization_list.clone()),
None,
config,
)
.await?;

Expand All @@ -599,9 +674,10 @@ mod tests {
#[tokio::test]
#[ignore]
async fn test_send_transaction_7702_vanilla_bundler() -> eyre::Result<()> {
let rpc_url = Config::local().endpoints.rpc.base_url;
let rpc_url: reqwest::Url = rpc_url.parse()?;
let provider = ReqwestProvider::<Ethereum>::new_http(rpc_url);
let config = Config::local();
let provider = ReqwestProvider::<Ethereum>::new_http(
config.endpoints.rpc.base_url.parse()?,
);

let destination = LocalSigner::random();
let balance = provider.get_balance(destination.address()).await?;
Expand All @@ -615,8 +691,14 @@ mod tests {
.await;

let transaction = vec![];
let transaction_hash =
send_transaction(transaction, owner.clone(), None, None).await?;
let transaction_hash = send_transaction(
transaction,
owner.clone(),
None,
None,
config.clone(),
)
.await?;
println!("Transaction sent: {}", transaction_hash);

let authority = LocalSigner::random();
Expand Down Expand Up @@ -721,6 +803,7 @@ mod tests {
owner,
Some(authority.address()),
None,
config,
)
.await?;

Expand Down
13 changes: 8 additions & 5 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ setup:
devloop: build test fmt udeps

test:
cargo test --all-features --lib --bins
cargo test --features=full --lib --bins

test-pimlico-api:
cargo test --features=test_pimlico_api --lib --bins

clippy:
cargo clippy --workspace --all-features --all-targets -- -D warnings
# cargo clippy --workspace --all-features --lib --bins --target wasm32-unknown-unknown --exclude=ffi -- -D warnings
cargo clippy --workspace --features=full --all-targets -- -D warnings
# cargo clippy --workspace --features=full --lib --bins --target wasm32-unknown-unknown --exclude=ffi -- -D warnings

fmt:
cargo +nightly fmt --all
Expand All @@ -21,5 +24,5 @@ udeps:

# TODO remove `build` in-favor of `clippy` when clippy passes
build:
cargo build --workspace --all-features --all-targets
# cargo build --workspace --all-features --lib --bins --target wasm32-unknown-unknown --exclude=ffi
cargo build --workspace --features=full --all-targets
# cargo build --workspace--features=full --lib --bins --target wasm32-unknown-unknown --exclude=ffi

0 comments on commit 48efea0

Please sign in to comment.