Middleware
The ArbiterMiddleware
is the main interface for interacting with an Environment
.
We implement the ethers-rs
Middleware
trait so that you may work with contract bindings generated by forge
or arbiter bind
as if you were interacting with a live network.
Not all methods are implemented, but the relevant ones are.
ArbiterMiddleware
owns a Connection
which is the client's interface to the Environment
's Socket
.
This Connection
acts much like a WebSocket connection and is used to send Instruction
s and receive their outcome from the Environment
as well as subscribe to events.
To make this Connection
and ArbiterMiddleware
flexible, we also implement (for both) the JsonRpcClient
and PubSubClient
traits.
We also provide ArbiterMiddleware
a wallet so that it can be associated to an account in the Environment
's world state.
The wallet: EOA
field of ArbiterMiddleware
is decided upon creation of the ArbiterMiddleware
and, if the wallet is generated from calling ArbiterMiddleware::new()
, wallet will be of EOA::Wallet(Wallet<SigningKey>)
which allows for ArbiterMiddleware
to sign transactions if need be.
It is possible to create accounts from a forked database, in which case you would call ArbiterMiddleware::new_from_forked_eoa()
and the wallet would be of EOA::Forked(Address)
.
This type is unable to sign as it is effectively impossible to recover the signing key from an address.
Fortunately, for almost every usecase of ArbiterMiddleware
, you will not need to sign transactions, so this distinction does not matter.
Usage
To create a ArbiterMiddleware
that is associated with an account in the Environment
's world state, we can do the following:
use arbiter_core::{middleware::ArbiterMiddleware, environment::Environment};
fn main() {
let env = Environment::builder().build();
// Create a client for the above `Environment` with an ID
let id = "alice";
let alice = ArbiterMiddleware::new(&env, Some(id));
// Create a client without an ID
let client = ArbiterMiddleware::new(&env, None);
}
These created clients can then get access to making calls and transactions to contracts deployed into the Environment
's world state. We can do the following:
use arbiter_core::{middleware::ArbiterMiddleware, environment::Environment};
use arbiter_bindings::bindings::arbiter_token::ArbiterToken;
#[tokio::main]
async fn main() {
let env = Environment::builder().build();
let client = ArbiterMiddleware::new(&env, None).unwrap();
// Deploy a contract
let contract = ArbiterToken::deploy(client, ("ARBT".to_owned(), "Arbiter Token".to_owned(), 18u8)).unwrap().send().await.unwrap();
}