diff --git a/src/TransactionController.test.ts b/src/TransactionController.test.ts index 22bd54decd0..24d46ee8894 100644 --- a/src/TransactionController.test.ts +++ b/src/TransactionController.test.ts @@ -96,6 +96,24 @@ const MOCK_FETCH_TX_HISTORY_DATA_OK = { transactionIndex: '12', txreceipt_status: '1', value: '50000000000000000' + }, + { + blockNumber: '4535105', + confirmations: '4', + contractAddress: '', + cumulativeGasUsed: '693910', + from: '0x6bf137f335ea1b8f193b8f6ea92561a60d23a207', + gas: '335208', + gasPrice: '20000000000', + gasUsed: '21000', + hash: '0x342e9d73e10004af41d04973339fc7219dbadcbb5629730cfe65e9f9cb15ff91', + input: '0x', + isError: '0', + nonce: '1', + timeStamp: '1543596356', + transactionIndex: '13', + txreceipt_status: '1', + value: '50000000000000000' } ], status: '1' @@ -373,7 +391,7 @@ describe('TransactionController', () => { const from = '0x6bf137f335ea1b8f193b8f6ea92561a60d23a207'; const latestBlock = await controller.fetchAll(from); - expect(controller.state.transactions.length).toBe(2); + expect(controller.state.transactions.length).toBe(3); expect(latestBlock).toBe('4535101'); expect(controller.state.transactions[0].transaction.to).toBe(from); }); @@ -387,7 +405,6 @@ describe('TransactionController', () => { } as any; controller.onComposed(); expect(controller.state.transactions.length).toBe(0); - const from = '0x6bf137f335ea1b8f193b8f6ea92561a60d23a207'; const result = await controller.fetchAll(from); expect(controller.state.transactions.length).toBe(0); diff --git a/src/TransactionController.ts b/src/TransactionController.ts index 8a50369c9d1..56806cfc030 100644 --- a/src/TransactionController.ts +++ b/src/TransactionController.ts @@ -1,7 +1,15 @@ import { EventEmitter } from 'events'; import BaseController, { BaseConfig, BaseState } from './BaseController'; import NetworkController from './NetworkController'; -import { BNToHex, fractionBN, hexToBN, normalizeTransaction, safelyExecute, validateTransaction } from './util'; +import { + BNToHex, + fractionBN, + hexToBN, + normalizeTransaction, + safelyExecute, + validateTransaction, + isSmartContractCode +} from './util'; const EthQuery = require('eth-query'); const Transaction = require('ethereumjs-tx'); @@ -55,7 +63,7 @@ export interface Transaction { * @property origin - Origin this transaction was sent from * @property rawTransaction - Hex representation of the underlying transaction * @property status - String status of this transaction - * @property time - Timestamp associated with this transaction + * @property toSmartContract - Whether transaction recipient is a smart contract * @property transaction - Underlying Transaction object * @property transactionHash - Hash of a successful transaction * @property blockNumber - Number of the block where the transaction has been included @@ -71,6 +79,7 @@ export interface TransactionMeta { rawTransaction?: string; status: string; time: number; + toSmartContract?: boolean; transaction: Transaction; transactionHash?: string; blockNumber?: string; @@ -552,7 +561,7 @@ export class TransactionController extends BaseController (/* istanbul ignore next */ a.time < b.time ? -1 : 1)); let latestIncomingTxBlockNumber: string | undefined; - allTxs.forEach((tx) => { + allTxs.forEach(async (tx) => { /* istanbul ignore next */ if ( tx.networkID === currentNetworkID && @@ -567,6 +576,16 @@ export class TransactionController extends BaseController { ) ).not.toThrow(); }); + + it('should not throw if data is correct', () => { + const toSmartContract1 = util.isSmartContractCode(''); + const toSmartContract2 = util.isSmartContractCode('0x'); + const toSmartContract3 = util.isSmartContractCode('0x0'); + const toSmartContract4 = util.isSmartContractCode('0x01234'); + expect(toSmartContract1).toBe(false); + expect(toSmartContract2).toBe(false); + expect(toSmartContract3).toBe(false); + expect(toSmartContract4).toBe(true); + }); }); }); diff --git a/src/util.ts b/src/util.ts index 9217f0d7909..e8873a1bd6b 100644 --- a/src/util.ts +++ b/src/util.ts @@ -257,6 +257,21 @@ export function validateTypedSignMessageDataV3(messageData: TypedMessageParams, } } +/** + * Returns wether the given code corresponds to a smart contract + * + * @returns {string} - Corresponding code to review + */ +export function isSmartContractCode(code: string) { + /* istanbul ignore if */ + if (!code) { + return false; + } + // Geth will return '0x', and ganache-core v2.2.1 will return '0x0' + const smartContractCode = code !== '0x' && code !== '0x0'; + return smartContractCode; +} + export default { BNToHex, fractionBN, @@ -264,6 +279,7 @@ export default { handleFetch, hexToBN, hexToText, + isSmartContractCode, normalizeTransaction, safelyExecute, validateTransaction,