@ -3,6 +3,17 @@ const ObservableStore = require('obs-store')
const ethUtil = require ( 'ethereumjs-util' )
const Transaction = require ( 'ethereumjs-tx' )
const EthQuery = require ( 'ethjs-query' )
const abi = require ( 'human-standard-token-abi' )
const abiDecoder = require ( 'abi-decoder' )
abiDecoder . addABI ( abi )
const {
TOKEN _METHOD _APPROVE ,
TOKEN _METHOD _TRANSFER ,
TOKEN _METHOD _TRANSFER _FROM ,
SEND _ETHER _ACTION _KEY ,
DEPLOY _CONTRACT _ACTION _KEY ,
CONTRACT _INTERACTION _KEY ,
} = require ( '../../../../ui/app/helpers/constants/transactions.js' )
const TransactionStateManager = require ( './tx-state-manager' )
const TxGasUtil = require ( './tx-gas-utils' )
const PendingTransactionTracker = require ( './pending-tx-tracker' )
@ -180,9 +191,11 @@ class TransactionController extends EventEmitter {
}
txUtils . validateTxParams ( normalizedTxParams )
// construct txMeta
const { transactionCategory , code } = await this . _determineTransactionCategory ( txParams )
let txMeta = this . txStateManager . generateTxMeta ( {
txParams : normalizedTxParams ,
type : TRANSACTION _TYPE _STANDARD ,
transactionCategory ,
} )
this . addTx ( txMeta )
this . emit ( 'newUnapprovedTx' , txMeta )
@ -191,7 +204,7 @@ class TransactionController extends EventEmitter {
// check whether recipient account is blacklisted
recipientBlacklistChecker . checkAccount ( txMeta . metamaskNetworkId , normalizedTxParams . to )
// add default tx params
txMeta = await this . addTxGasDefaults ( txMeta )
txMeta = await this . addTxGasDefaults ( txMeta , code )
} catch ( error ) {
log . warn ( error )
txMeta . loadingDefaults = false
@ -211,7 +224,7 @@ class TransactionController extends EventEmitter {
@ param txMeta { Object } - the txMeta object
@ returns { Promise < object > } resolves with txMeta
* /
async addTxGasDefaults ( txMeta ) {
async addTxGasDefaults ( txMeta , code ) {
const txParams = txMeta . txParams
// ensure value
txParams . value = txParams . value ? ethUtil . addHexPrefix ( txParams . value ) : '0x0'
@ -222,7 +235,7 @@ class TransactionController extends EventEmitter {
}
txParams . gasPrice = ethUtil . addHexPrefix ( gasPrice . toString ( 16 ) )
// set gasLimit
return await this . txGasUtil . analyzeGasUsage ( txMeta )
return await this . txGasUtil . analyzeGasUsage ( txMeta , code )
}
/ * *
@ -555,6 +568,42 @@ class TransactionController extends EventEmitter {
} )
}
/ * *
Returns a "type" for a transaction out of the following list : simpleSend , tokenTransfer , tokenApprove ,
contractDeployment , contractMethodCall
* /
async _determineTransactionCategory ( txParams ) {
const { data , to } = txParams
const { name } = data && abiDecoder . decodeMethod ( data ) || { }
const tokenMethodName = [
TOKEN _METHOD _APPROVE ,
TOKEN _METHOD _TRANSFER ,
TOKEN _METHOD _TRANSFER _FROM ,
] . find ( tokenMethodName => tokenMethodName === name && name . toLowerCase ( ) )
let result
let code
if ( ! txParams . data ) {
result = SEND _ETHER _ACTION _KEY
} else if ( tokenMethodName ) {
result = tokenMethodName
} else if ( ! to ) {
result = DEPLOY _CONTRACT _ACTION _KEY
} else {
try {
code = await this . query . getCode ( to )
} catch ( e ) {
log . warn ( e )
}
// For an address with no code, geth will return '0x', and ganache-core v2.2.1 will return '0x0'
const codeIsEmpty = ! code || code === '0x' || code === '0x0'
result = codeIsEmpty ? SEND _ETHER _ACTION _KEY : CONTRACT _INTERACTION _KEY
}
return { transactionCategory : result , code }
}
/ * *
Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
in the list have the same nonce