ethers.js/docs.wrm/api/signer.wrm

357 lines
13 KiB
Plaintext
Raw Normal View History

2020-06-12 10:38:55 +03:00
2020-05-08 10:24:40 +03:00
_section: Signers @<signers>
2020-06-12 10:38:55 +03:00
A **Signer** in //ethers// is an abstraction of an Ethereum Account,
which can be used to sign messages and transactions and send
signed transactions to the Ethereum Network to execute state
changing operations.
The available operations depends largely on the sub-class used.
For example, a Signer from MetaMask can send transactions and sign
messages but cannot sign a transaction (without broadcasting it).
The most common Signers you will encounter are:
- [[Wallet]], which is a class which knows its private key and can
execute any operations with it
- [[JsonRpcSigner]], which is connected to a [[JsonRpcProvider]] (or
sub-class) and is acquired using [getSigner](JsonRpcProvider-getSigner)
2020-05-08 10:24:40 +03:00
_subsection: Signer @<Signer> @SRC<abstract-signer:class.Signer>
2020-06-12 10:38:55 +03:00
The **Signer** class is abstract and cannot be directly instaniated.
Instead use one of the concreate sub-classes, such as the [[Wallet]],
[[VoidSigner]] or [[JsonRpcSigner]].
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: signer.connect(provider) => [[Signer]] @<Signer-connect>
2020-01-10 09:01:00 +03:00
Sub-classes **must** implement this, however they may simply throw an error
if changing providers is not supported.
2020-06-12 10:38:55 +03:00
_property: signer.getAddress() => Promise<string<[[address]]>> @<Signer-getaddress> @SRC<abstract-signer:Signer.connect>
2020-01-10 09:01:00 +03:00
Returns a Promise that resolves to the account address.
This is a Promise so that a **Signer** can be designed around an
asynchronous source, such as hardware wallets.
Sub-classes **must** implement this.
2020-05-08 10:24:40 +03:00
_property: Signer.isSigner(object) => boolean @<Signer-isSigner> @SRC<abstract-signer>
2020-01-10 09:01:00 +03:00
Returns true if an only if //object// is a **Signer**.
2020-05-08 10:24:40 +03:00
_heading: Blockchain Methods @<Signer--blockchain-methods>
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: signer.getBalance([ blockTag = "latest" ]) => Promise<[[BigNumber]]> @<Signer-getBalance> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the balance of this wallet at //blockTag//.
2020-05-08 10:24:40 +03:00
_property: signer.getChainId() => Promise<number> @<Signer-getChainId> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns ths chain ID this wallet is connected to.
2020-05-08 10:24:40 +03:00
_property: signer.getGasPrice() => Promise<[[BigNumber]]> @<Signer-getGasPrice> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the current gas price.
2020-05-08 10:24:40 +03:00
_property: signer.getTransactionCount([ blockTag = "latest" ]) => Promise<number> @<Signer-getTransactionCount> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the number of transactions this account has ever sent. This
is the value required to be included in transactions as the ``nonce``.
2020-05-08 10:24:40 +03:00
_property: signer.call(transactionRequest) => Promise<string<[[DataHexString]]>> @<Signer-call> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the result of calling using the //transactionRequest//, with this
account address being used as the ``from`` field.
2020-05-08 10:24:40 +03:00
_property: signer.estimateGas(transactionRequest) => Promise<[[BigNumber]]> @<Signer-estimateGas> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the result of estimating the cost to send the //transactionRequest//,
with this account address being used as the ``from`` field.
2020-06-12 10:38:55 +03:00
_property: signer.resolveName(ensName) => Promise<string<[[address]]>> @<Signer-resolveName> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
Returns the address associated with the //ensName//.
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
_heading: Signing @<Signer--signing-methods>
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: signer.signMessage(message) => Promise<string<[RawSignature](signature-raw)>> @<Signer-signMessage>
This returns a Promise which resolves to the [[signature-raw]]
2020-01-10 09:01:00 +03:00
of //message//.
2020-01-10 09:01:00 +03:00
Sub-classes **must** implement this, however they may throw if signing a
2020-06-12 10:38:55 +03:00
message is not supported, such as in a Contract-based Wallet or
Meta-Transaction-based Wallet.
2020-01-10 09:01:00 +03:00
_note: Note
If //message// is a string, it is **treated as a string** and
converted to its representation in UTF8 bytes.
2020-05-08 10:24:40 +03:00
**If and only if** a message is a [[Bytes]] will it be treated as
2020-01-10 09:01:00 +03:00
binary data.
For example, the string ``"0x1234"`` is 6 characters long (and in
this case 6 bytes long). This is **not** equivalent to the array
``[ 0x12, 0x34 ]``, which is 2 bytes long.
A common case is to sign a hash. In this case, if the hash is a
string, it **must** be converted to an array first, using the
[arrayify](utils-arrayify) utility function.
_null:
2020-05-08 10:24:40 +03:00
_property: signer.signTransaction(transactionRequest) => Promise<string<[[DataHexString]]>> @<Signer-signTransaction>
2020-01-10 09:01:00 +03:00
Returns a Promise which resolves to the signed transaction of the
//transactionRequest//. This method does not populate any missing fields.
Sub-classes **must** implement this, however they may throw if signing a
2020-06-12 10:38:55 +03:00
transaction is not supported, which is common for security reasons in many
clients.
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: signer.sendTransaction(transactionRequest) => Promise<[[providers-TransactionResponse]]> @<Signer-sendTransaction>
2020-01-10 09:01:00 +03:00
This method populates the transactionRequest with missing fields, using
2020-05-08 10:24:40 +03:00
[populateTransaction](Signer-populateTransaction) and returns a Promise which resolves to the transaction.
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
Sub-classes **must** implement this, however they may throw if sending a
transaction is not supported, such as the [[VoidSigner]] or if the
Wallet is offline and not connected to a [[Provider]].
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_heading: Sub-Classes @<Signer--subclassing>
2020-01-10 09:01:00 +03:00
It is very important that all important properties of a **Signer** are
**immutable**. Since Ethereum is very asynchronous and deals with critical
data (such as ether and other potentially valuable crypto assets), keeping
2020-06-12 10:38:55 +03:00
properties such as the //provider// and //address// static throughout the
life-cycle of the Signer helps prevent serious issues and many other classes
and libraries make this assumption.
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
A sub-class **must** extend Sigenr and **must** call ``super()``.
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: signer.checkTransaction(transactionRequest) => [[providers-TransactionRequest]] @<Signer-checkTransaction> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
This is generally not required to be overridden, but may needed to provide
custom behaviour in sub-classes.
This should return a **copy** of the //transactionRequest//, with any properties
needed by ``call``, ``estimateGas`` and ``populateTransaction`` (which is used
by sendTransaction). It should also throw an error if any unknown key is specified.
2020-05-08 10:24:40 +03:00
The default implementation checks only valid [[providers-TransactionRequest]] properties
2020-06-12 10:38:55 +03:00
exist and adds ``from`` to the transaction if it does not exist.
If there is a ``from`` field it **must** be verified to be equal to the Signer's address.
2020-05-08 10:24:40 +03:00
_property: signer.populateTransaction(transactionRequest) => Promise<[[providers-TransactionRequest]]> @<Signer-populateTransaction> @SRC<abstract-signer>
2020-02-01 11:39:21 +03:00
This is generally not required to be overridden, but may needed to provide
custom behaviour in sub-classes.
This should return a **copy** of //transactionRequest//, follow the same procedure
as ``checkTransaction`` and fill in any properties required for sending a transaction.
The result should have all promises resolved; if needed the [resolveProperties](utils-resolveproperties)
utility function can be used for this.
2020-02-01 11:39:21 +03:00
The default implementation calls ``checkTransaction`` and resolves to if it is an
ENS name, adds ``gasPrice``, ``nonce``, ``gasLimit`` and ``chainId`` based on the
related operations on Signer.
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
2020-05-08 10:24:40 +03:00
_subsection: Wallet @<Wallet> @INHERIT<[[ExternallyOwnedAccount]] and [[Signer]]> @SRC<wallet:class.Wallet>
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
The Wallet class inherits [[Signer]] and can sign transactions and messages
2020-01-10 09:01:00 +03:00
using a private key as a standard Externally Owned Account (EOA).
2020-05-08 10:24:40 +03:00
_property: new ethers.Wallet(privateKey [ , provider ]) @<Wallet-constructor> @SRC<wallet:constructor.Wallet>
2020-01-10 09:01:00 +03:00
Create a new Wallet instance for //privateKey// and optionally
connected to the //provider//.
2020-05-08 10:24:40 +03:00
_property: ethers.Wallet.createRandom( [ options = { } ]) => [[Wallet]] @<Wallet-createRandom> @SRC<wallet>
2020-01-10 09:01:00 +03:00
Returns a new Wallet with a random private key, generated from
cryptographically secure entropy sources. If the current environment
does not have a secure entropy source, an error is thrown.
2020-06-12 10:38:55 +03:00
Wallets created using this method will have a mnemonic.
2020-05-08 10:24:40 +03:00
_property: ethers.Wallet.fromEncryptedJson(json, password [ , progress ]) => Promise<[[Wallet]]> @<Wallet-fromEncryptedJson> @SRC<wallet>
2020-06-12 10:38:55 +03:00
Create an instance from an encrypted JSON wallet.
If //progress// is provided it will be called during decryption
with a value between 0 and 1 indicating the progress towards
completion.
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_property: ethers.Wallet.fromEncryptedJsonSync(json, password) => [[Wallet]] @<Wallet-fromEncryptedJsonSync> @SRC<wallet>
2020-04-17 05:25:05 +03:00
Create an instance from an encrypted JSON wallet.
This operation will operate synchronously which will lock up the user
interface, possibly for a non-trivial duration. Most applications should
use the asynchronous ``fromEncryptedJson`` instead.
2020-06-12 10:38:55 +03:00
_property: ethers.Wallet.fromMnemonic(mnemonic [ , path, [ wordlist ] ]) => [[Wallet]] @<Wallet.fromMnemonic>
2020-01-10 09:01:00 +03:00
Create an instance from a mnemonic phrase.
2020-06-12 10:38:55 +03:00
If path is not specified, the Ethereum default path is used (i.e. ``m/44'/60'/0'/0/0``).
2020-01-10 09:01:00 +03:00
If wordlist is not specified, the English Wordlist is used.
2020-06-12 10:38:55 +03:00
_heading: Properties @<Wallet--properties>
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
_property: wallet.address => string<[[address]]>
2020-01-10 09:01:00 +03:00
The address for the account this Wallet represents.
2020-05-08 10:24:40 +03:00
_property: wallet.provider => [[Provider]]
The provider this wallet is connected to, which will ge used for any [[Signer--blockchain-methods]]
2020-01-10 09:01:00 +03:00
methods. This can be null.
_note: Note
A **Wallet** instance is immuatable, so if you wish to change the Provider, you
2020-05-08 10:24:40 +03:00
may use the [connect](Signer-connect) method to create a new instance connected
2020-01-10 09:01:00 +03:00
to the desired provider.
2020-05-08 10:24:40 +03:00
_property: wallet.publicKey => string<[[DataHexString]]<65>>
2020-01-10 09:01:00 +03:00
The uncompressed public key for this Wallet represents.
2020-06-12 10:38:55 +03:00
_heading: Methods @<Wallet--methods>
2020-01-10 09:01:00 +03:00
2020-06-12 10:38:55 +03:00
_property: wallet.encrypt(password, [ options = { }, [ progress ] ]) => Promise<string> @<Wallet-encrypt>
2020-01-10 09:01:00 +03:00
Encrypt the wallet using //password// returning a Promise which resolves
to a JSON wallet.
2020-06-12 10:38:55 +03:00
If //progress// is provided it will be called during decryption
with a value between 0 and 1 indicating the progress towards
completion.
_code: Wallet Examples @lang<javascript>
// Create a wallet instance from a mnemonic...
mnemonic = "announce room limb pattern dry unit scale effort smooth jazz weasel alcohol"
walletMnemonic = Wallet.fromMnemonic(mnemonic)
// ...or from a private key
walletPrivateKey = new Wallet(walletMnemonic.privateKey)
walletMnemonic.address === walletPrivateKey.address
//!
// The address as a Promise per the Signer API
walletMnemonic.getAddress()
//!
// A Wallet address is also available synchronously
walletMnemonic.address
//!
// The internal cryptographic components
walletMnemonic.privateKey
//!
walletMnemonic.publicKey
//!
// The wallet mnemonic
walletMnemonic.mnemonic
//!
// Note: A wallet created with a private key does not
// have a mnemonic (the derivation prevents it)
walletPrivateKey.mnemonic
//!
// Signing a message
walletMnemonic.signMessage("Hello World")
//!
tx = {
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
value: utils.parseEther("1.0")
}
// Signing a transaction
walletMnemonic.signTransaction(tx)
//!
// The connect method returns a new instance of the
// Wallet connected to a provider
wallet = walletMnemonic.connect(provider)
// Querying the network
wallet.getBalance();
//!
wallet.getTransactionCount();
//!
// Sending ether
wallet.sendTransaction(tx)
// <hide>
//! error
// </hide>
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_subsection: VoidSigner @<VoidSigner> @INHERIT<[[Signer]]> @SRC<abstract-signer:class.VoidSigner>
2020-01-10 09:01:00 +03:00
A **VoidSigner** is a simple Signer which cannot sign.
It is useful as a read-only signer, when an API requires a
Signer as a parameter, but it is known only read-only operations
will be carried.
For example, the ``call`` operation will automatically have the
provided address passed along during the execution.
2020-06-12 10:38:55 +03:00
_property: new ethers.VoidSigner(address [ , provider ]) => [[VoidSigner]]
2020-01-10 09:01:00 +03:00
Create a new instance of a **VoidSigner** for //address//.
2020-06-12 10:38:55 +03:00
_property: voidSigner.address => string<[[address]]>
2020-01-10 09:01:00 +03:00
The address of this **VoidSigner**.
2020-06-12 10:38:55 +03:00
_code: VoidSigner Pre-flight Example @lang<javascript>
address = "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
signer = new ethers.VoidSigner(address, provider)
// The DAI token contract
abi = [
"function balanceOf(address) view returns (uint)",
"function transfer(address, uint) returns (bool)"
]
contract = new ethers.Contract("dai.tokens.ethers.eth", abi, signer)
// <hide>
//!
// </hide>
// Get the number of tokens for this account
tokens = await contract.balanceOf(signer.getAddress())
//! async tokens
//
// Pre-flight (check for revert) on DAI from the signer
//
// Note: We do not have the private key at this point, this
// simply allows us to check what would happen if we
// did. This can be useful to check before prompting
// a request in the UI
//
// This will pass since the token balance is available
contract.callStatic.transfer("donations.ethers.eth", tokens)
//!
// This will fail since it is greater than the token balance
contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
//! error
2020-01-10 09:01:00 +03:00
2020-05-08 10:24:40 +03:00
_subsection: ExternallyOwnedAccount @<ExternallyOwnedAccount>
2020-01-10 09:01:00 +03:00
2020-02-25 22:57:11 +03:00
This is an interface which contains a minimal set of properties
required for Externally Owned Accounts which can have certain
operations performed, such as encoding as a JSON wallet.
2020-06-12 10:38:55 +03:00
_property: eoa.address => string<[[address]]>
2020-01-10 09:01:00 +03:00
The [[address]] of this EOA.
2020-05-08 10:24:40 +03:00
_property: eoa.privateKey => string<[[DataHexString]]<32>>
2020-01-10 09:01:00 +03:00
The privateKey of this EOA
2020-05-08 10:24:40 +03:00
_property: eoa.mnemonic => [[Mnemonic]]
2020-01-10 09:01:00 +03:00
2020-02-25 22:57:11 +03:00
//Optional//. The account HD mnemonic, if it has one and can be
determined. Some sources do not encode the mnemonic, such as an
HD extended keys.