-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
feat: cast ls + cast accounts #656
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for this,
looking good, but a couple of nits and suggestions
cast/src/lib.rs
Outdated
let chain_id = self.chain_id().await?; | ||
|
||
// for each file in $HOME/.ethereum/keystore | ||
if let Ok(home_dir) = std::env::var("HOME") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's the dirs-next
crate that provides a helper for finding the home dir
https://crates.io/crates/dirs-next
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use that in the foundry_config crate as well
cast/src/lib.rs
Outdated
// for each file in $HOME/.ethereum/keystore | ||
if let Ok(home_dir) = std::env::var("HOME") { | ||
let path = std::path::Path::new(&home_dir).join(".ethereum").join("keystore"); | ||
let entries = fs::read_dir(path)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want a better error message here as io errors don't provide info about the dir path of a dir that does not exist.
cast/src/lib.rs
Outdated
let map = value.as_object_mut().unwrap(); | ||
let addr = map.get_mut("address").unwrap().as_str().unwrap(); | ||
let t = H160::from_str(addr).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while it is (perhaps) unlikely that this fails, these unwraps here are a bit invasive.
alternatively, you can simply define a helper struct directly in this function like:
#[derive(Deserialize)
struct Entry {
address: Address
}
} | ||
|
||
} | ||
Err(_) => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we print something here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seth
doesn't print anything in this case, if its assumed that the output is safe to be consumed from a script then I don't think printing anything makes sense. I do think this command could use a -v
flag
cast/src/lib.rs
Outdated
let mut s = String::new(); | ||
for (i, balance) in balances.iter().enumerate() { | ||
let addr = addrs[i]; | ||
let result = match balance { | ||
Ok(balance) => format!("{:?}\t{}\n", addr, balance), | ||
Err(_) => format!("{:?}\t{}\n", addr, 0), | ||
}; | ||
s.push_str(&result); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather like the function to return the pairs of (Address, Result)
and do we do this formatting part outside, when printing to stdout, basically in the Subcommand::Ls
Glancing through, trezor should work pretty much the same as ledger here. I can test it out after the PR is closer to done. What do you think of showing the derivation path if dealing with hardware wallets? Edit: plus some labels to know what comes from where ( keystore vs ledger vs trezor) |
I'm into this idea, thinking of breaking out the code that finds accounts into another command $ seth accounts
0x27770a9694e4B4b1E130Ab91Bc327C36855f612E keystore
0x47baC1Afc3Ef96aAb8209c63b38B9AaAAe4EBDC4 keystore
0x00000398232E2064F896018496b4b44b3D62751F keystore
0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 ledger-m/44'/60'/0'/0/0
0x422F94147B13e7fd435981c003a83ba4a7c5B20D ledger-m/44'/60'/1'/0/0
0xde768894c145871746BAd479c133403a379780e7 ledger-m/44'/60'/2'/0/0
0x508885e9ce33A83784c5569f6a1BF09c66e4deD5 ledger-m/44'/60'/3'/0/0
0x9cc889680F5fBC0Ee0FbA8A68866C27acC599b35 ledger-m/44'/60'/4'/0/0
0x0245eDdb15eA32D89f04C564da9aa31A29502e65 ledger-m/44'/60'/5'/0/0
0xc8f19745d6301D21dfA0eeEA8006a1fBf993837b ledger-m/44'/60'/0'/0
0x84f70449f90300997840eCb0918873745Ede7aE6 ledger-m/44'/60'/0'/1
0x27770a9694e4B4b1E130Ab91Bc327C36855f612E ledger-m/44'/60'/0'/2
0x9DD1Ec758E49b07DbAb6ef52BBb61979fEfF831A ledger-m/44'/60'/0'/3
0x911537a2da8fE765350383b35118758F37047776 ledger-m/44'/60'/0'/4
0x7C9DbFC58af7b5538Ef30601d219D9f79c050625 ledger-m/44'/60'/0'/5 |
ETH_RPC_ACCOUNTS works by querying the eth_accounts endpoint, ethersrs supports that, so I'd add that. As a follow up:Wdyt about also making this work with a mnemonic, and also showing the eth/erc20 balances for the accounts? Almost like a quick overview/summary of all accs |
} | ||
} | ||
|
||
// Check the keystore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be able to take an argument similar to geth --datadir
and fall back to the default keystore if it is not passed. The default keystore is OS dependent
|
||
Some(path) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This get_account
function should be renamed or refactored when trezor support is added
"windows" => { | ||
if let Ok(local_app_data) = std::env::var("LOCALAPPDATA") { | ||
path = std::path::Path::new(&local_app_data).join("Ethereum"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
geth
panics if LOCALAPPDATA
is not defined, meaning that its running on windows xp. This needs to be updated with logic for when its not defined so that the default keystore path isn't the windows equivalent of $HOME/keystore
I've added the ability to query remote accounts using I can definitely add flags to make this work with a mnemonic, thinking Regarding eth/erc20 balances, it currently shows eth balance when doing To print erc20 balances, I think the functionality would be to look at the chainid, then grab addresses from the address book. Any opinions on which erc20 balances are queried? Some potentials:
|
dd690ab
to
bc613e1
Compare
@tynes any plans to add new things in this PR, or should we mark as ready for review? |
Implement `cast ls` and `cast accounts` `cast ls` prints out a list of accounts and their balances. `cast accounts` prints out a lits of accounts and their type of account. These are based on `seth`. The `seth` implementation is based on `ethsign`, see: - https://github.com/dapphub/dapptools/blob/1be7d796a468f52a5eb5b6830591d76a3b4b1c49/src/seth/libexec/seth/seth-accounts#L4 - https://github.com/dapphub/dapptools/blob/1be7d796a468f52a5eb5b6830591d76a3b4b1c49/src/ethsign/ethsign.go#L210
} | ||
|
||
#[derive(Debug)] | ||
pub enum CastAccountType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like its a bit redundant, I've seen similar types in ethers elsewehere
Closing as stale, let's revisit if we prioritize #926 |
I mostly use cast with hardware wallets and something like |
Motivation
I'd like to use
cast
for sending transactions with a key on my hardware wallet.Implementing
cast ls
helps with making sure that the correct hardware walletis plugged in.
cast ls
should list off the available wallets that can be used for signing. Thisincludes the local keystore (
geth account list
), plugged in ledgers and pluggedin trezors.
seth
can also support the RPC endpointeth_accounts
when the env var
ETH_RPC_ACCOUNTS
is set. I don't see an ethers remote signerthat uses RPC for signing so its probably early for that
functionality.
This PR doesn't yet support trezor as I don't have a trezor wallet to test out, but it
should be easy to add. It also needs sane default keystore locations based on the
OS.
ethsign ls
be made available tocast ls
? They aren't withseth ls
,unless you use env vars
but it doesn't support pulling the
address
field out of the keystore JSON. This field was removedfrom the keystore spec as to preserve privacy
Solution
Implement
cast ls
which prints out a list ofaddresses and their balances. The
seth
implementationis based on
ethsign
, see: