Skip to content
This repository was archived by the owner on May 11, 2023. It is now read-only.

Commit 49ad2de

Browse files
committed
Remove legacy (tx) flag from env
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
1 parent f199b3d commit 49ad2de

6 files changed

Lines changed: 297 additions & 290 deletions

File tree

common/src/ethereum.rs

Lines changed: 97 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::convert::TryFrom;
33
use std::env;
44
use std::ffi::OsString;
5+
use std::fmt::Debug;
56
use std::path::PathBuf;
67
use std::str::FromStr;
78

@@ -10,7 +11,6 @@ use coins_bip32::path::DerivationPath;
1011
use anyhow::anyhow;
1112
use anyhow::Context as _;
1213
use ethers::abi::Detokenize;
13-
use ethers::prelude::builders::ContractCall;
1414
use ethers::prelude::*;
1515
use ethers::types::transaction::eip712::Eip712;
1616
use ethers::types::Chain;
@@ -22,7 +22,7 @@ pub mod signer;
2222

2323
mod walletconnect;
2424

25-
use self::signer::Signer as ExtendedSigner;
25+
use self::signer::{ContractCall, ExtendedMiddleware, ExtendedSigner};
2626
use self::walletconnect::WalletConnect;
2727

2828
/// Radicle's ENS domain.
@@ -32,6 +32,7 @@ pub const SIGNER_OPTIONS: &str = r#"
3232
--ledger-hdpath <hdpath> Account derivation path when using a Ledger hardware device
3333
--keystore <file> Keystore file containing encrypted private key (default: none)
3434
--walletconnect Use WalletConnect
35+
--legacy Send transactions in legacy mode
3536
"#;
3637

3738
pub const PROVIDER_OPTIONS: &str = r#"
@@ -52,6 +53,8 @@ pub struct SignerOptions {
5253
pub keystore: Option<PathBuf>,
5354
/// Walletconnect account (default: false).
5455
pub walletconnect: bool,
56+
/// Legacy transaction (default: false).
57+
pub legacy: bool,
5558
}
5659

5760
impl SignerOptions {
@@ -65,6 +68,7 @@ impl SignerOptions {
6568
.ok()
6669
.and_then(|v| DerivationPath::from_str(v.as_str()).ok()),
6770
walletconnect: false,
71+
legacy: false,
6872
};
6973

7074
while let Some(arg) = parser.next()? {
@@ -85,7 +89,7 @@ impl SignerOptions {
8589
options.walletconnect = true;
8690
}
8791
Long("legacy") => {
88-
std::env::set_var("RAD_SIGNER_LEGACY", "true");
92+
options.legacy = true;
8993
}
9094
_ => unparsed.push(args::format(arg)),
9195
}
@@ -161,96 +165,143 @@ pub enum Wallet {
161165
WalletConnect(WalletConnect),
162166
}
163167

168+
#[derive(Debug)]
169+
pub enum TypedWallet {
170+
Legacy(Wallet),
171+
Modern(Wallet),
172+
}
173+
174+
impl TypedWallet {
175+
fn wallet(&self) -> &Wallet {
176+
match self {
177+
Self::Legacy(wallet) => wallet,
178+
Self::Modern(wallet) => wallet,
179+
}
180+
}
181+
182+
fn own_wallet(self) -> Wallet {
183+
match self {
184+
Self::Legacy(wallet) => wallet,
185+
Self::Modern(wallet) => wallet,
186+
}
187+
}
188+
189+
fn wrapper(&self) -> fn(Wallet) -> Self {
190+
match self {
191+
Self::Legacy(_) => Self::Legacy,
192+
Self::Modern(_) => Self::Modern,
193+
}
194+
}
195+
}
196+
164197
#[async_trait::async_trait]
165-
impl ExtendedSigner for Wallet {
198+
impl Signer for TypedWallet {
166199
type Error = WalletError;
167200

168201
fn chain_id(&self) -> u64 {
169-
match self {
170-
Self::Ledger(s) => s.chain_id(),
171-
Self::Local(s) => s.chain_id(),
172-
Self::WalletConnect(s) => s.chain_id(),
202+
match self.wallet() {
203+
Wallet::Ledger(s) => s.chain_id(),
204+
Wallet::Local(s) => s.chain_id(),
205+
Wallet::WalletConnect(s) => s.chain_id(),
173206
}
174207
}
175208

176209
fn address(&self) -> Address {
177-
match self {
178-
Self::Ledger(s) => s.address(),
179-
Self::Local(s) => s.address(),
180-
Self::WalletConnect(s) => s.address(),
210+
match self.wallet() {
211+
Wallet::Ledger(s) => s.address(),
212+
Wallet::Local(s) => s.address(),
213+
Wallet::WalletConnect(s) => s.address(),
181214
}
182215
}
183216

184217
fn with_chain_id<T: Into<u64>>(self, chain_id: T) -> Self {
185-
match self {
186-
Self::Ledger(s) => Self::Ledger(s.with_chain_id(chain_id)),
187-
Self::Local(s) => Self::Local(s.with_chain_id(chain_id)),
188-
Self::WalletConnect(_s) => unimplemented!(),
218+
let wrapper = self.wrapper();
219+
match self.own_wallet() {
220+
Wallet::Ledger(s) => (wrapper)(Wallet::Ledger(s.with_chain_id(chain_id))),
221+
Wallet::Local(s) => (wrapper)(Wallet::Local(s.with_chain_id(chain_id))),
222+
Wallet::WalletConnect(_s) => unimplemented!(),
189223
}
190224
}
191225

192226
async fn sign_typed_data<T: Eip712 + Send + Sync>(
193227
&self,
194228
payload: &T,
195229
) -> Result<Signature, Self::Error> {
196-
match self {
197-
Self::Ledger(s) => s.sign_typed_data(payload).await.map_err(WalletError::from),
198-
Self::Local(s) => s.sign_typed_data(payload).await.map_err(WalletError::from),
199-
Self::WalletConnect(_s) => unimplemented!(),
230+
match self.wallet() {
231+
Wallet::Ledger(s) => s.sign_typed_data(payload).await.map_err(WalletError::from),
232+
Wallet::Local(s) => s.sign_typed_data(payload).await.map_err(WalletError::from),
233+
Wallet::WalletConnect(_s) => unimplemented!(),
200234
}
201235
}
202236

203237
async fn sign_message<S: Send + Sync + AsRef<[u8]>>(
204238
&self,
205239
message: S,
206240
) -> Result<Signature, Self::Error> {
207-
match self {
208-
Self::Ledger(s) => s.sign_message(message).await.map_err(WalletError::from),
209-
Self::Local(s) => s.sign_message(message).await.map_err(WalletError::from),
210-
Self::WalletConnect(s) => s.sign_message(message).await.map_err(WalletError::from),
241+
match self.wallet() {
242+
Wallet::Ledger(s) => s.sign_message(message).await.map_err(WalletError::from),
243+
Wallet::Local(s) => s.sign_message(message).await.map_err(WalletError::from),
244+
Wallet::WalletConnect(s) => s.sign_message(message).await.map_err(WalletError::from),
211245
}
212246
}
213247

214248
async fn sign_transaction(
215249
&self,
216250
message: &ethers::types::transaction::eip2718::TypedTransaction,
217251
) -> Result<Signature, Self::Error> {
218-
match self {
219-
Self::Ledger(s) => s.sign_transaction(message).await.map_err(WalletError::from),
220-
Self::Local(s) => s.sign_transaction(message).await.map_err(WalletError::from),
221-
Self::WalletConnect(s) => s.sign_transaction(message).await.map_err(WalletError::from),
252+
match self.wallet() {
253+
Wallet::Ledger(s) => s.sign_transaction(message).await.map_err(WalletError::from),
254+
Wallet::Local(s) => s.sign_transaction(message).await.map_err(WalletError::from),
255+
Wallet::WalletConnect(s) => {
256+
s.sign_transaction(message).await.map_err(WalletError::from)
257+
}
222258
}
223259
}
260+
}
224261

262+
#[async_trait::async_trait]
263+
impl ExtendedSigner for TypedWallet {
225264
async fn send_transaction(
226265
&self,
227266
message: &ethers::types::transaction::eip2718::TypedTransaction,
228267
) -> Result<H256, Self::Error> {
229-
match self {
230-
Self::Ledger(_) => unimplemented!(),
231-
Self::Local(_) => unimplemented!(),
232-
Self::WalletConnect(s) => s.send_transaction(message).await.map_err(WalletError::from),
268+
match self.wallet() {
269+
Wallet::Ledger(_) => unimplemented!(),
270+
Wallet::Local(_) => unimplemented!(),
271+
Wallet::WalletConnect(s) => {
272+
s.send_transaction(message).await.map_err(WalletError::from)
273+
}
233274
}
234275
}
235276

236277
fn is_walletconnect(&self) -> bool {
278+
match self.wallet() {
279+
Wallet::Ledger(_) => false,
280+
Wallet::Local(_) => false,
281+
Wallet::WalletConnect(_) => true,
282+
}
283+
}
284+
285+
fn is_legacy(&self) -> bool {
237286
match self {
238-
Self::Ledger(_) => false,
239-
Self::Local(_) => false,
240-
Self::WalletConnect(_) => true,
287+
Self::Legacy(_) => true,
288+
Self::Modern(_) => false,
241289
}
242290
}
243291
}
244292

245293
impl Wallet {
246294
/// Open a wallet from the given options and provider.
247-
pub async fn open<P>(options: SignerOptions, provider: Provider<P>) -> anyhow::Result<Wallet>
295+
pub async fn open<P>(
296+
options: SignerOptions,
297+
provider: Provider<P>,
298+
) -> anyhow::Result<TypedWallet>
248299
where
249300
P: JsonRpcClient + Clone + 'static,
250301
{
251302
let chain_id = provider.get_chainid().await?.as_u64();
252303

253-
if let Some(keypath) = &options.keystore {
304+
let wallet = if let Some(keypath) = &options.keystore {
254305
let password = term::secret_input_with_prompt("Keystore password");
255306
let spinner = term::spinner("Decrypting keystore...");
256307
let signer = LocalWallet::decrypt_keystore(keypath, password.unsecure())
@@ -277,6 +328,12 @@ impl Wallet {
277328
Ok(Wallet::WalletConnect(signer))
278329
} else {
279330
Err(WalletError::NoWallet.into())
331+
};
332+
333+
if options.legacy {
334+
wallet.map(TypedWallet::Legacy)
335+
} else {
336+
wallet.map(TypedWallet::Modern)
280337
}
281338
}
282339
}
@@ -285,13 +342,9 @@ impl Wallet {
285342
pub async fn transaction<M, D>(call: ContractCall<M, D>) -> anyhow::Result<TransactionReceipt>
286343
where
287344
D: Detokenize,
288-
M: Middleware + 'static,
345+
M: ExtendedMiddleware + 'static,
289346
{
290-
let call = if std::env::var_os("RAD_SIGNER_LEGACY").is_some() {
291-
call.legacy()
292-
} else {
293-
call
294-
};
347+
let call = call.set_tx_type();
295348
let receipt = loop {
296349
let spinner = term::spinner("Waiting for transaction to be signed...");
297350
let tx = match call.send().await {
@@ -348,7 +401,7 @@ pub fn hex(bytes: impl AsRef<[u8]>) -> String {
348401
pub async fn get_wallet(
349402
signer_opts: SignerOptions,
350403
provider: Provider<Http>,
351-
) -> anyhow::Result<(Wallet, Provider<Http>)> {
404+
) -> anyhow::Result<(TypedWallet, Provider<Http>)> {
352405
use rad_terminal::args::Error;
353406

354407
term::tip!("Accessing your wallet...");

0 commit comments

Comments
 (0)