mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add txReceipt data to transaction details (#5513)
This commit is contained in:
parent
61dec4ea46
commit
c821a8354c
@ -424,6 +424,9 @@
|
||||
"gasLimitTooLow": {
|
||||
"message": "Gas limit must be at least 21000"
|
||||
},
|
||||
"gasUsed": {
|
||||
"message": "Gas Used"
|
||||
},
|
||||
"generatingSeed": {
|
||||
"message": "Generating Seed..."
|
||||
},
|
||||
|
@ -366,7 +366,40 @@ class TransactionController extends EventEmitter {
|
||||
this.txStateManager.setTxStatusSubmitted(txId)
|
||||
}
|
||||
|
||||
confirmTransaction (txId) {
|
||||
/**
|
||||
* Sets the status of the transaction to confirmed and sets the status of nonce duplicates as
|
||||
* dropped if the txParams have data it will fetch the txReceipt
|
||||
* @param {number} txId - The tx's ID
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async confirmTransaction (txId) {
|
||||
// get the txReceipt before marking the transaction confirmed
|
||||
// to ensure the receipt is gotten before the ui revives the tx
|
||||
const txMeta = this.txStateManager.getTx(txId)
|
||||
|
||||
if (!txMeta) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const txReceipt = await this.query.getTransactionReceipt(txMeta.hash)
|
||||
|
||||
// It seems that sometimes the numerical values being returned from
|
||||
// this.query.getTransactionReceipt are BN instances and not strings.
|
||||
const gasUsed = typeof txReceipt.gasUsed !== 'string'
|
||||
? txReceipt.gasUsed.toString(16)
|
||||
: txReceipt.gasUsed
|
||||
|
||||
txMeta.txReceipt = {
|
||||
...txReceipt,
|
||||
gasUsed,
|
||||
}
|
||||
|
||||
this.txStateManager.updateTx(txMeta, 'transactions#confirmTransaction - add txReceipt')
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
}
|
||||
|
||||
this.txStateManager.setTxStatusConfirmed(txId)
|
||||
this._markNonceDuplicatesDropped(txId)
|
||||
}
|
||||
|
@ -400,6 +400,11 @@ class TransactionStateManager extends EventEmitter {
|
||||
*/
|
||||
_setTxStatus (txId, status) {
|
||||
const txMeta = this.getTx(txId)
|
||||
|
||||
if (!txMeta) {
|
||||
return
|
||||
}
|
||||
|
||||
txMeta.status = status
|
||||
setTimeout(() => {
|
||||
try {
|
||||
|
@ -46,11 +46,15 @@ export function getActivities (transaction) {
|
||||
if (!Array.isArray(base) && base.status === UNAPPROVED_STATUS && base.txParams) {
|
||||
const { time, txParams: { value } = {} } = base
|
||||
return acc.concat(eventCreator(TRANSACTION_CREATED_EVENT, time, value))
|
||||
// An entry in the history may be an array of more sub-entries.
|
||||
} else if (Array.isArray(base)) {
|
||||
const events = []
|
||||
|
||||
base.forEach(entry => {
|
||||
const { op, path, value, timestamp } = entry
|
||||
const { op, path, value, timestamp: entryTimestamp } = entry
|
||||
// Not all sub-entries in a history entry have a timestamp. If the sub-entry does not have a
|
||||
// timestamp, the first sub-entry in a history entry should.
|
||||
const timestamp = entryTimestamp || base[0] && base[0].timestamp
|
||||
|
||||
if (path in eventPathsHash && op === REPLACE_OP) {
|
||||
switch (path) {
|
||||
|
@ -26,8 +26,11 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
render () {
|
||||
const { t } = this.context
|
||||
const { transaction, className } = this.props
|
||||
const { txParams: { gas, gasPrice, value } = {} } = transaction
|
||||
const hexGasTotal = getHexGasTotal({ gasLimit: gas, gasPrice })
|
||||
const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {} } = transaction
|
||||
|
||||
const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas
|
||||
|
||||
const hexGasTotal = getHexGasTotal({ gasLimit, gasPrice })
|
||||
const totalInHex = sumHexes(hexGasTotal, value)
|
||||
|
||||
return (
|
||||
@ -52,6 +55,19 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
value={gas}
|
||||
/>
|
||||
</TransactionBreakdownRow>
|
||||
{
|
||||
typeof gasUsed === 'string' && (
|
||||
<TransactionBreakdownRow
|
||||
title={`${t('gasUsed')} (${t('units')})`}
|
||||
className="transaction-breakdown__row-title"
|
||||
>
|
||||
<HexToDecimal
|
||||
className="transaction-breakdown__value"
|
||||
value={gasUsed}
|
||||
/>
|
||||
</TransactionBreakdownRow>
|
||||
)
|
||||
}
|
||||
<TransactionBreakdownRow title={t('gasPrice')}>
|
||||
<CurrencyDisplay
|
||||
className="transaction-breakdown__value"
|
||||
|
@ -11,6 +11,7 @@ import { CONFIRM_TRANSACTION_ROUTE } from '../../routes'
|
||||
import { UNAPPROVED_STATUS, TOKEN_METHOD_TRANSFER } from '../../constants/transactions'
|
||||
import { ETH } from '../../constants/common'
|
||||
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../app/scripts/lib/enums'
|
||||
import { getStatusKey } from '../../helpers/transactions.util'
|
||||
|
||||
export default class TransactionListItem extends PureComponent {
|
||||
static propTypes = {
|
||||
@ -167,7 +168,7 @@ export default class TransactionListItem extends PureComponent {
|
||||
</div>
|
||||
<TransactionStatus
|
||||
className="transaction-list-item__status"
|
||||
statusKey={transaction.status}
|
||||
statusKey={getStatusKey(transaction)}
|
||||
title={(
|
||||
(transaction.err && transaction.err.rpc)
|
||||
? transaction.err.rpc.message
|
||||
|
@ -25,4 +25,9 @@
|
||||
background-color: #FFF2DB;
|
||||
color: #CA810A;
|
||||
}
|
||||
}
|
||||
|
||||
&--failed {
|
||||
background: lighten($monzo, 56%);
|
||||
color: $monzo;
|
||||
}
|
||||
}
|
||||
|
@ -19,4 +19,39 @@ describe('Transactions utils', () => {
|
||||
assert.doesNotThrow(() => utils.getTokenData())
|
||||
})
|
||||
})
|
||||
|
||||
describe('getStatusKey', () => {
|
||||
it('should return the correct status', () => {
|
||||
const tests = [
|
||||
{
|
||||
transaction: {
|
||||
status: 'confirmed',
|
||||
txReceipt: {
|
||||
status: '0x0',
|
||||
},
|
||||
},
|
||||
expected: 'failed',
|
||||
},
|
||||
{
|
||||
transaction: {
|
||||
status: 'confirmed',
|
||||
txReceipt: {
|
||||
status: '0x1',
|
||||
},
|
||||
},
|
||||
expected: 'confirmed',
|
||||
},
|
||||
{
|
||||
transaction: {
|
||||
status: 'pending',
|
||||
},
|
||||
expected: 'pending',
|
||||
},
|
||||
]
|
||||
|
||||
tests.forEach(({ transaction, expected }) => {
|
||||
assert.equal(utils.getStatusKey(transaction), expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -126,3 +126,21 @@ export function sumHexes (...args) {
|
||||
|
||||
return ethUtil.addHexPrefix(total)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a status key for a transaction. Requires parsing the txMeta.txReceipt on top of
|
||||
* txMeta.status because txMeta.status does not reflect on-chain errors.
|
||||
* @param {Object} transaction - The txMeta object of a transaction.
|
||||
* @param {Object} transaction.txReceipt - The transaction receipt.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getStatusKey (transaction) {
|
||||
const { txReceipt: { status } = {} } = transaction
|
||||
|
||||
// There was an on-chain failure
|
||||
if (status === '0x0') {
|
||||
return 'failed'
|
||||
}
|
||||
|
||||
return transaction.status
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user