Transactions¶
Info
Relevant JSON-RPC method: custodian_createTransaction
MMI creates/proposes transactions to the custodian API, including a proposed gas price. However, custodians may (at their users’ request, or automatically) use a different gas price. Custodians are responsible for the ordering of transactions.
Transaction updates¶
- MMI needs to know when transactions are signed and pushed to the blockchain so that the user can interact with Dapps.
Info
Normally, once the transaction is on-chain and it has the transaction hash, MetaMask yields control to the Dapp so that the Dapp can do something with the result.
MetaMask shows the status of a transaction in the activity pane.
-
We expect the custodian to have some way of communicating updates to the MMI web service; the ideal method being webhooks to a specific HTTPS URL.
-
The custodian sends updates to our web service. They may have an Oauth2 JWT in the Authorization header, described on the authentication page. It must be possible to match the incoming transaction to the user and customer.
-
Read the webhook specification
Rules¶
-
To give users access to the Defi ecosystem, they must have the power to make calls to smart contracts and conduct other types of transactions, such as:
- ETH transfers.
- ERC-20 transfers and approves - a special case of smart contract calls.
- General smart contract calls, i.e. transactions where the
to
parameter is a smart contract address and the data.
-
We expect custodians to have their own rules on what contracts their customers can call.
Call failure¶
- If a call fails due to non-compliance with such a rule, a
4xx
HTTP response including a descriptive error message helps users to remedy the situation.
Parameters¶
The parameters we send with our HTTP request are similar to the ITXParams
in the appendices, and closely resemble the parameters of eth_sendTransaction
in the Ethereum JSON-RPC API. Hexlified string values are necessary for supporting large numbers.
from
: the Ethereum address of the user.to
: the Ethereum address of the contract we are calling, or the recipient in the case of a simple transfer.value
: stringified integer of the value sent with this transaction, in Wei.gasLimit
: same asvalue
, set by the user, but can be overridden.data
: the calldata, i.e. the 4 byte prefix and the contract method parameters.- Gas parameters: see the next section.
Nonce
We do not send a nonce. We expect the custodian to manage the nonce as well as publish the transaction. This is essential for avoiding stuck transactions.
Transactions FAQ¶
Who handles gas prices?¶
See Gas.
Who handles the nonce field?¶
This must be set by the custodian to facilitate transaction retries. Updated nonces should be included in webhooks and in the response to custodian_getTransactionById
, as they are used by the extension UI to order transactions.
Who broadcasts the transaction?¶
Normally, Metamask broadcasts the transaction using whatever JSON-RPC API it is connected to; Infura by default. In MMI, generally, we expect the custodian to broadcast transactions, for the following reasons:
- Due to approval processes within the custodian, transactions may take a long time (minutes to days) to actually sign. There is a chance that the original MMI user who initiated the transaction is now offline.
- Transactions may fail due to incorrect nonce, gas prices, and other reasons. For this reason, it is better if the entity which sets these parameters (the custodian) broadcasts transactions.
- Custodians will need to monitor transactions in order to show their users via UIs whether they were successful and also to communicate this to MMI.
There are some exceptions, however. See Transaction broadcast.
How do transaction statuses work?¶
In transaction methods and webhooks, the status
field has the following content:
{
finished: boolean
signed: boolean
submitted: boolean
success: boolean
displayText: string
reason: string
}
Subfield explanations¶
finished
- whether the transaction is done, i.e. it is no longer necessary to poll for the status of this transaction. This should be true whether or not the transaction was successfulsigned
- Whether the transaction has been signed - it has an available hashsubmitted
- Whether the transaction has been broadcast to an RPC network and made available in the mempoolsuccess
- Whether the transaction was successful - for example it has been validated by a node, and not reverted or rejecteddisplayText
- a short, capitalised name for the transaction status, for example: Pending, Proposed, Rejected, Complete, Failed. This is shown to the user by the extension.reason
- an explanation for the current status. For example “Transaction was rejected by approver”, or if an error was received from an EVM node, this could be included here. This is displayed to the user by the extension if the transaction is not successful.