Skip to content

Commit

Permalink
Add transfer method to address
Browse files Browse the repository at this point in the history
  • Loading branch information
danhper committed Nov 21, 2024
1 parent f4cd0ed commit d856d2a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
* Add `repl.startPrank` / `repl.stopPrank` to start/stop impersonating an address
* Add `FUNC.traceCall` method to contract functions
* Add `abi.decodeData` to decode function calldata and errors from any known ABI
* Add `address.transfer` to send ETH to an address

### Other changes

* Encode `FixedBytes` as with zero padding on the left instead of the right
* Allow to load a private key from `bytes32`

## v0.1.3 (2024-08-15)

Expand Down
35 changes: 31 additions & 4 deletions src/interpreter/builtins/address.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::sync::Arc;

use alloy::{providers::Provider, transports::BoxFuture};
use anyhow::Result;
use alloy::{
network::TransactionBuilder, providers::Provider, rpc::types::TransactionRequest,
transports::BoxFuture,
};
use anyhow::{anyhow, Result};
use futures::FutureExt;
use lazy_static::lazy_static;

use crate::interpreter::{
functions::{AsyncProperty, FunctionDef},
Env, Value,
functions::{AsyncMethod, AsyncProperty, FunctionDef, FunctionParam},
Env, Type, Value,
};

fn get_balance<'a>(env: &'a Env, receiver: &'a Value) -> BoxFuture<'a, Result<Value>> {
Expand All @@ -22,7 +25,31 @@ fn get_balance<'a>(env: &'a Env, receiver: &'a Value) -> BoxFuture<'a, Result<Va
.boxed()
}

fn transfer<'a>(
env: &'a mut Env,
receiver: &'a Value,
args: &'a [Value],
) -> BoxFuture<'a, Result<Value>> {
async move {
let provider = env.get_provider();
let value = args
.first()
.ok_or(anyhow!("Missing value"))
.and_then(|v| v.as_u256())?;
let addr = receiver.as_address()?;
let tx_req = TransactionRequest::default().with_to(addr).value(value);
let tx = provider.send_transaction(tx_req).await?;
Ok(Value::Transaction(*tx.tx_hash()))
}
.boxed()
}

lazy_static! {
pub static ref ADDRESS_BALANCE: Arc<dyn FunctionDef> =
AsyncProperty::arc("balance", get_balance);
pub static ref ADDRESS_TRANSFER: Arc<dyn FunctionDef> = AsyncMethod::arc(
"transfer",
transfer,
vec![vec![FunctionParam::new("amount", Type::Uint(256))]]
);
}
1 change: 1 addition & 0 deletions src/interpreter/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ lazy_static! {
let mut addr_methods = HashMap::new();
addr_methods.insert("format".to_string(), format::NON_NUM_FORMAT.clone());
addr_methods.insert("balance".to_string(), address::ADDRESS_BALANCE.clone());
addr_methods.insert("transfer".to_string(), address::ADDRESS_TRANSFER.clone());
m.insert(NonParametricType::Address, addr_methods);

let mut transaction_methods = HashMap::new();
Expand Down
14 changes: 9 additions & 5 deletions src/interpreter/builtins/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ fn get_default_sender(env: &Env) -> Value {
}

fn load_private_key(env: &mut Env, _receiver: &Value, args: &[Value]) -> Result<Value> {
let key = match args {
[Value::Str(key)] => key.clone(),
[] => rpassword::prompt_password("Enter private key: ")?,
let signer: PrivateKeySigner = match args {
[Value::Str(key)] => key.parse()?,
[Value::FixBytes(bytes, 32)] => PrivateKeySigner::from_bytes(bytes)?,
[] => rpassword::prompt_password("Enter private key: ")?.parse()?,
_ => bail!("loadPrivateKey: invalid arguments"),
};
let signer: PrivateKeySigner = key.parse()?;
env.set_signer(signer)?;
Ok(get_default_sender(env))
}
Expand Down Expand Up @@ -318,7 +318,11 @@ lazy_static! {
pub static ref REPL_LOAD_PRIVATE_KEY: Arc<dyn FunctionDef> = SyncMethod::arc(
"loadPrivateKey",
load_private_key,
vec![vec![], vec![FunctionParam::new("privateKey", Type::String)]]
vec![
vec![],
vec![FunctionParam::new("privateKey", Type::String)],
vec![FunctionParam::new("privateKey", Type::FixBytes(32))]
]
);
pub static ref REPL_LOAD_KEYSTORE: Arc<dyn FunctionDef> = SyncMethod::arc(
"loadKeystore",
Expand Down

0 comments on commit d856d2a

Please sign in to comment.