2020-09-24 21:33:09 +00:00
|
|
|
//! Provides a unified interface for locally signing transactions.
|
|
|
|
//!
|
|
|
|
//! You can implement the `Signer` trait to extend functionality to other signers
|
|
|
|
//! such as Hardware Security Modules, KMS etc.
|
|
|
|
//!
|
|
|
|
//! The exposed interfaces return a recoverable signature. In order to convert the signature
|
|
|
|
//! and the [`TransactionRequest`] to a [`Transaction`], look at the signing middleware.
|
|
|
|
//!
|
|
|
|
//! Supported signers:
|
2020-12-31 19:08:12 +00:00
|
|
|
//! - [Private key](crate::LocalWallet)
|
|
|
|
//! - [Ledger](crate::Ledger)
|
|
|
|
//! - [YubiHSM2](crate::YubiWallet)
|
2021-08-01 21:18:24 +00:00
|
|
|
//! - [AWS KMS](crate::AwsSigner)
|
2020-06-20 13:55:07 +00:00
|
|
|
//!
|
|
|
|
//! ```no_run
|
2021-08-28 21:06:29 +00:00
|
|
|
//! # use ethers_signers::{LocalWallet, Signer};
|
|
|
|
//! # use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest};
|
|
|
|
//!
|
2020-06-20 13:55:07 +00:00
|
|
|
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
2020-09-24 21:33:09 +00:00
|
|
|
//! // instantiate the wallet
|
|
|
|
//! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
|
2020-10-02 08:41:16 +00:00
|
|
|
//! .parse::<LocalWallet>()?;
|
2020-06-20 13:55:07 +00:00
|
|
|
//!
|
|
|
|
//! // create a transaction
|
|
|
|
//! let tx = TransactionRequest::new()
|
|
|
|
//! .to("vitalik.eth") // this will use ENS
|
2021-08-09 00:31:11 +00:00
|
|
|
//! .value(10000).into();
|
2020-06-20 13:55:07 +00:00
|
|
|
//!
|
2020-09-24 21:33:09 +00:00
|
|
|
//! // sign it
|
|
|
|
//! let signature = wallet.sign_transaction(&tx).await?;
|
2020-06-20 13:55:07 +00:00
|
|
|
//!
|
2020-09-24 21:33:09 +00:00
|
|
|
//! // can also sign a message
|
|
|
|
//! let signature = wallet.sign_message("hello world").await?;
|
|
|
|
//! signature.verify("hello world", wallet.address()).unwrap();
|
2020-06-20 13:55:07 +00:00
|
|
|
//! # Ok(())
|
|
|
|
//! # }
|
2020-12-24 15:44:08 +00:00
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! [`Transaction`]: ethers_core::types::Transaction
|
|
|
|
//! [`TransactionRequest`]: ethers_core::types::TransactionRequest
|
2020-05-26 10:24:19 +00:00
|
|
|
mod wallet;
|
2021-04-05 07:44:58 +00:00
|
|
|
pub use wallet::{MnemonicBuilder, Wallet, WalletError};
|
|
|
|
|
|
|
|
/// Re-export the BIP-32 crate so that wordlists can be accessed conveniently.
|
|
|
|
pub use coins_bip39;
|
2020-05-26 10:24:19 +00:00
|
|
|
|
2020-10-02 08:41:16 +00:00
|
|
|
/// A wallet instantiated with a locally stored private key
|
|
|
|
pub type LocalWallet = Wallet<ethers_core::k256::ecdsa::SigningKey>;
|
|
|
|
|
|
|
|
#[cfg(feature = "yubi")]
|
|
|
|
/// A wallet instantiated with a YubiHSM
|
|
|
|
pub type YubiWallet = Wallet<yubihsm::ecdsa::Signer<ethers_core::k256::Secp256k1>>;
|
|
|
|
|
2020-09-20 15:17:02 +00:00
|
|
|
#[cfg(feature = "ledger")]
|
2020-09-20 18:27:00 +00:00
|
|
|
mod ledger;
|
|
|
|
#[cfg(feature = "ledger")]
|
2020-09-23 08:04:54 +00:00
|
|
|
pub use ledger::{
|
|
|
|
app::LedgerEthereum as Ledger,
|
|
|
|
types::{DerivationType as HDPath, LedgerError},
|
|
|
|
};
|
2020-09-20 15:17:02 +00:00
|
|
|
|
2020-10-02 08:41:16 +00:00
|
|
|
#[cfg(feature = "yubi")]
|
|
|
|
pub use yubihsm;
|
|
|
|
|
2021-08-01 21:18:24 +00:00
|
|
|
#[cfg(feature = "aws")]
|
|
|
|
mod aws;
|
|
|
|
|
|
|
|
#[cfg(feature = "aws")]
|
2021-08-01 22:19:23 +00:00
|
|
|
pub use aws::{AwsSigner, AwsSignerError};
|
2021-08-01 21:18:24 +00:00
|
|
|
|
2020-09-20 15:17:02 +00:00
|
|
|
use async_trait::async_trait;
|
derive-eip712: initial implementation of eip712 derive macro (#481)
* derive-eip712: initial implementation of eip712 derive macro
This commit provides an initial implementation for a derive macro
to encode typed data according to EIP-712, https://eips.ethereum.org/EIPS/eip-712
Additionally, this commit introduces a new signer trait method:
async fn sign_typed_data<T: Eip712 + Send + Sync>(
&self,
payload: &T,
) -> Result<Signature, Self::Error>;
And implements the new method for each of the signers (wallet, ledger,
aws).
Additionally, these changes include using `WalletError` for the Wallet
signer error type
At the moment, derive does not recurse the primary type to find nested
Eip712 structs. This is something that is noted in the source and
currently responds with an error regarding custom types.
A subsequent PR should be opened once this issue becomes needed. For the
moment, the current implementation should satisfy non-nested, basic struct types.
* rename to ethers-derive-eip712; move to ethers-core
* refactor of derive-eip712 macro; use ParamType and EthAbiToken
* macro updates; add byte array checker for paramtype; use literal constant for domain type hash
* replace std::convert::Infallible with WalletError as Wallet signer error type
* update workspace members and dev dependencies for examples folder
* add example for eip712 and test against contract
* remove extraneous backward slash in '\x19\x01' prefix; example tests pass
* update unreleased change log
* remove print statements
* use parse_macro_input macro; remove dead code; handle nest struct not implemented error
* move eip712 example to solidity-contract tests folder; update cargo workspace dependencies
* allow optional EIP712Domain parameter when encoding eip712 struct and signing typed data
* add documentation for eip712 feature
* Update ethers-signers/src/ledger/mod.rs
Co-authored-by: Sebastian Martinez <me@sebastinez.dev>
* add error enum for Eip712Error; use sign_payload for ledger signer
* add EIP712WithDomain type for providing a wrapper around custom setting of the domain
* make LedgerWallet sign_payload public
* use optional feature gated dependencies for eip712; add default method for encode_eip712
* add default domain_separator method, pre-compute separator hash
* move derive-eip712 deps to dev deps
* remove invalid sign payload parameter, add await on async method
* remove deprecated comment
* debugging 'bad key handle' error for ledger signer
try using 'sign_message'
* await sign digest for aws signer
* remove extra space, fix fmt warning
* fix test, fmt errors
* use gt 0.6.0 pragma compiler version
* enable ABIEncoderV2 for solidity test contract
* chore: make test constructor public
Co-authored-by: Sebastian Martinez <me@sebastinez.dev>
Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
2021-10-08 15:22:51 +00:00
|
|
|
use ethers_core::types::{
|
|
|
|
transaction::eip2718::TypedTransaction, transaction::eip712::Eip712, Address, Signature,
|
|
|
|
};
|
2020-05-26 10:24:19 +00:00
|
|
|
use std::error::Error;
|
|
|
|
|
2020-12-24 10:38:27 +00:00
|
|
|
/// Applies [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)
|
2021-07-29 20:22:25 +00:00
|
|
|
pub fn to_eip155_v<T: Into<u8>>(recovery_id: T, chain_id: u64) -> u64 {
|
|
|
|
(recovery_id.into() as u64) + 35 + chain_id * 2
|
2020-12-24 10:38:27 +00:00
|
|
|
}
|
|
|
|
|
2020-05-26 10:24:19 +00:00
|
|
|
/// Trait for signing transactions and messages
|
|
|
|
///
|
|
|
|
/// Implement this trait to support different signing modes, e.g. Ledger, hosted etc.
|
2021-08-23 09:56:44 +00:00
|
|
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
|
|
|
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
2020-10-02 08:41:16 +00:00
|
|
|
pub trait Signer: std::fmt::Debug + Send + Sync {
|
2020-09-24 21:33:09 +00:00
|
|
|
type Error: Error + Send + Sync;
|
2020-05-26 10:24:19 +00:00
|
|
|
/// Signs the hash of the provided message after prefixing it
|
2020-09-20 15:17:02 +00:00
|
|
|
async fn sign_message<S: Send + Sync + AsRef<[u8]>>(
|
|
|
|
&self,
|
|
|
|
message: S,
|
|
|
|
) -> Result<Signature, Self::Error>;
|
2020-05-26 10:24:19 +00:00
|
|
|
|
|
|
|
/// Signs the transaction
|
2021-08-09 00:31:11 +00:00
|
|
|
async fn sign_transaction(&self, message: &TypedTransaction) -> Result<Signature, Self::Error>;
|
2020-05-26 10:24:19 +00:00
|
|
|
|
derive-eip712: initial implementation of eip712 derive macro (#481)
* derive-eip712: initial implementation of eip712 derive macro
This commit provides an initial implementation for a derive macro
to encode typed data according to EIP-712, https://eips.ethereum.org/EIPS/eip-712
Additionally, this commit introduces a new signer trait method:
async fn sign_typed_data<T: Eip712 + Send + Sync>(
&self,
payload: &T,
) -> Result<Signature, Self::Error>;
And implements the new method for each of the signers (wallet, ledger,
aws).
Additionally, these changes include using `WalletError` for the Wallet
signer error type
At the moment, derive does not recurse the primary type to find nested
Eip712 structs. This is something that is noted in the source and
currently responds with an error regarding custom types.
A subsequent PR should be opened once this issue becomes needed. For the
moment, the current implementation should satisfy non-nested, basic struct types.
* rename to ethers-derive-eip712; move to ethers-core
* refactor of derive-eip712 macro; use ParamType and EthAbiToken
* macro updates; add byte array checker for paramtype; use literal constant for domain type hash
* replace std::convert::Infallible with WalletError as Wallet signer error type
* update workspace members and dev dependencies for examples folder
* add example for eip712 and test against contract
* remove extraneous backward slash in '\x19\x01' prefix; example tests pass
* update unreleased change log
* remove print statements
* use parse_macro_input macro; remove dead code; handle nest struct not implemented error
* move eip712 example to solidity-contract tests folder; update cargo workspace dependencies
* allow optional EIP712Domain parameter when encoding eip712 struct and signing typed data
* add documentation for eip712 feature
* Update ethers-signers/src/ledger/mod.rs
Co-authored-by: Sebastian Martinez <me@sebastinez.dev>
* add error enum for Eip712Error; use sign_payload for ledger signer
* add EIP712WithDomain type for providing a wrapper around custom setting of the domain
* make LedgerWallet sign_payload public
* use optional feature gated dependencies for eip712; add default method for encode_eip712
* add default domain_separator method, pre-compute separator hash
* move derive-eip712 deps to dev deps
* remove invalid sign payload parameter, add await on async method
* remove deprecated comment
* debugging 'bad key handle' error for ledger signer
try using 'sign_message'
* await sign digest for aws signer
* remove extra space, fix fmt warning
* fix test, fmt errors
* use gt 0.6.0 pragma compiler version
* enable ABIEncoderV2 for solidity test contract
* chore: make test constructor public
Co-authored-by: Sebastian Martinez <me@sebastinez.dev>
Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
2021-10-08 15:22:51 +00:00
|
|
|
/// Encodes and signs the typed data according EIP-712.
|
|
|
|
/// Payload must implement Eip712 trait.
|
|
|
|
async fn sign_typed_data<T: Eip712 + Send + Sync>(
|
|
|
|
&self,
|
|
|
|
payload: T,
|
|
|
|
) -> Result<Signature, Self::Error>;
|
|
|
|
|
2020-05-26 10:24:19 +00:00
|
|
|
/// Returns the signer's Ethereum Address
|
2020-09-24 21:33:09 +00:00
|
|
|
fn address(&self) -> Address;
|
2021-07-29 20:22:25 +00:00
|
|
|
|
|
|
|
/// Returns the signer's chain id
|
|
|
|
fn chain_id(&self) -> u64;
|
|
|
|
|
|
|
|
/// Sets the signer's chain id
|
|
|
|
fn with_chain_id<T: Into<u64>>(self, chain_id: T) -> Self;
|
2020-05-26 09:37:31 +00:00
|
|
|
}
|