mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Use chainId
for incoming transactions controller (#9583)
The incoming transactions controller now uses the `chainId` for the current network instead of the `networkId`. This ensures that custom RPC endpoints for the built-in supported networks do correctly receive incoming transactions. As part of this change, the incoming transactions controller will also cease keeping track of the "last block fetched" for networks that are not supported. This piece of state never really represented the last block fetched, as _no_ blocks were fetched for any such networks. It been removed.
This commit is contained in:
parent
c6064072c7
commit
55bff07bbf
@ -6,12 +6,18 @@ import { bnToHex } from '../lib/util'
|
|||||||
import fetchWithTimeout from '../lib/fetch-with-timeout'
|
import fetchWithTimeout from '../lib/fetch-with-timeout'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ROPSTEN,
|
CHAIN_ID_TO_NETWORK_ID_MAP,
|
||||||
RINKEBY,
|
CHAIN_ID_TO_TYPE_MAP,
|
||||||
KOVAN,
|
|
||||||
GOERLI,
|
GOERLI,
|
||||||
|
GOERLI_CHAIN_ID,
|
||||||
|
KOVAN,
|
||||||
|
KOVAN_CHAIN_ID,
|
||||||
MAINNET,
|
MAINNET,
|
||||||
NETWORK_TYPE_TO_ID_MAP,
|
MAINNET_CHAIN_ID,
|
||||||
|
RINKEBY,
|
||||||
|
RINKEBY_CHAIN_ID,
|
||||||
|
ROPSTEN,
|
||||||
|
ROPSTEN_CHAIN_ID,
|
||||||
} from './network/enums'
|
} from './network/enums'
|
||||||
|
|
||||||
const fetch = fetchWithTimeout({
|
const fetch = fetchWithTimeout({
|
||||||
@ -25,6 +31,14 @@ const fetch = fetchWithTimeout({
|
|||||||
* Note that only the built-in Infura networks are supported (i.e. anything in `INFURA_PROVIDER_TYPES`). We will not
|
* Note that only the built-in Infura networks are supported (i.e. anything in `INFURA_PROVIDER_TYPES`). We will not
|
||||||
* attempt to retrieve incoming transactions on any custom RPC endpoints.
|
* attempt to retrieve incoming transactions on any custom RPC endpoints.
|
||||||
*/
|
*/
|
||||||
|
const etherscanSupportedNetworks = [
|
||||||
|
GOERLI_CHAIN_ID,
|
||||||
|
KOVAN_CHAIN_ID,
|
||||||
|
MAINNET_CHAIN_ID,
|
||||||
|
RINKEBY_CHAIN_ID,
|
||||||
|
ROPSTEN_CHAIN_ID,
|
||||||
|
]
|
||||||
|
|
||||||
export default class IncomingTransactionsController {
|
export default class IncomingTransactionsController {
|
||||||
|
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
@ -36,7 +50,6 @@ export default class IncomingTransactionsController {
|
|||||||
this.blockTracker = blockTracker
|
this.blockTracker = blockTracker
|
||||||
this.networkController = networkController
|
this.networkController = networkController
|
||||||
this.preferencesController = preferencesController
|
this.preferencesController = preferencesController
|
||||||
this.getCurrentNetwork = () => networkController.getProviderConfig().type
|
|
||||||
|
|
||||||
this._onLatestBlock = async (newBlockNumberHex) => {
|
this._onLatestBlock = async (newBlockNumberHex) => {
|
||||||
const selectedAddress = this.preferencesController.getSelectedAddress()
|
const selectedAddress = this.preferencesController.getSelectedAddress()
|
||||||
@ -50,11 +63,11 @@ export default class IncomingTransactionsController {
|
|||||||
const initState = {
|
const initState = {
|
||||||
incomingTransactions: {},
|
incomingTransactions: {},
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
incomingTxLastFetchedBlocksByNetwork: {
|
||||||
[ROPSTEN]: null,
|
|
||||||
[RINKEBY]: null,
|
|
||||||
[KOVAN]: null,
|
|
||||||
[GOERLI]: null,
|
[GOERLI]: null,
|
||||||
|
[KOVAN]: null,
|
||||||
[MAINNET]: null,
|
[MAINNET]: null,
|
||||||
|
[RINKEBY]: null,
|
||||||
|
[ROPSTEN]: null,
|
||||||
}, ...opts.initState,
|
}, ...opts.initState,
|
||||||
}
|
}
|
||||||
this.store = new ObservableStore(initState)
|
this.store = new ObservableStore(initState)
|
||||||
@ -88,11 +101,10 @@ export default class IncomingTransactionsController {
|
|||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
this.networkController.on('networkDidChange', async (newType) => {
|
this.networkController.on('networkDidChange', async () => {
|
||||||
const address = this.preferencesController.getSelectedAddress()
|
const address = this.preferencesController.getSelectedAddress()
|
||||||
await this._update({
|
await this._update({
|
||||||
address,
|
address,
|
||||||
networkType: newType,
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -113,29 +125,32 @@ export default class IncomingTransactionsController {
|
|||||||
this.blockTracker.removeListener('latest', this._onLatestBlock)
|
this.blockTracker.removeListener('latest', this._onLatestBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
async _update ({ address, newBlockNumberDec, networkType } = {}) {
|
async _update ({ address, newBlockNumberDec } = {}) {
|
||||||
|
const chainId = this.networkController.getCurrentChainId()
|
||||||
|
if (!etherscanSupportedNetworks.includes(chainId)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const dataForUpdate = await this._getDataForUpdate({ address, newBlockNumberDec, networkType })
|
const dataForUpdate = await this._getDataForUpdate({ address, chainId, newBlockNumberDec })
|
||||||
await this._updateStateWithNewTxData(dataForUpdate)
|
this._updateStateWithNewTxData(dataForUpdate)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err)
|
log.error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getDataForUpdate ({ address, newBlockNumberDec, networkType } = {}) {
|
async _getDataForUpdate ({ address, chainId, newBlockNumberDec } = {}) {
|
||||||
const {
|
const {
|
||||||
incomingTransactions: currentIncomingTxs,
|
incomingTransactions: currentIncomingTxs,
|
||||||
incomingTxLastFetchedBlocksByNetwork: currentBlocksByNetwork,
|
incomingTxLastFetchedBlocksByNetwork: currentBlocksByNetwork,
|
||||||
} = this.store.getState()
|
} = this.store.getState()
|
||||||
|
|
||||||
const network = networkType || this.getCurrentNetwork()
|
const lastFetchBlockByCurrentNetwork = currentBlocksByNetwork[CHAIN_ID_TO_TYPE_MAP[chainId]]
|
||||||
const lastFetchBlockByCurrentNetwork = currentBlocksByNetwork[network]
|
|
||||||
let blockToFetchFrom = lastFetchBlockByCurrentNetwork || newBlockNumberDec
|
let blockToFetchFrom = lastFetchBlockByCurrentNetwork || newBlockNumberDec
|
||||||
if (blockToFetchFrom === undefined) {
|
if (blockToFetchFrom === undefined) {
|
||||||
blockToFetchFrom = parseInt(this.blockTracker.getCurrentBlock(), 16)
|
blockToFetchFrom = parseInt(this.blockTracker.getCurrentBlock(), 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { latestIncomingTxBlockNumber, txs: newTxs } = await this._fetchAll(address, blockToFetchFrom, network)
|
const { latestIncomingTxBlockNumber, txs: newTxs } = await this._fetchAll(address, blockToFetchFrom, chainId)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
latestIncomingTxBlockNumber,
|
latestIncomingTxBlockNumber,
|
||||||
@ -143,17 +158,17 @@ export default class IncomingTransactionsController {
|
|||||||
currentIncomingTxs,
|
currentIncomingTxs,
|
||||||
currentBlocksByNetwork,
|
currentBlocksByNetwork,
|
||||||
fetchedBlockNumber: blockToFetchFrom,
|
fetchedBlockNumber: blockToFetchFrom,
|
||||||
network,
|
chainId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _updateStateWithNewTxData ({
|
_updateStateWithNewTxData ({
|
||||||
latestIncomingTxBlockNumber,
|
latestIncomingTxBlockNumber,
|
||||||
newTxs,
|
newTxs,
|
||||||
currentIncomingTxs,
|
currentIncomingTxs,
|
||||||
currentBlocksByNetwork,
|
currentBlocksByNetwork,
|
||||||
fetchedBlockNumber,
|
fetchedBlockNumber,
|
||||||
network,
|
chainId,
|
||||||
}) {
|
}) {
|
||||||
const newLatestBlockHashByNetwork = latestIncomingTxBlockNumber
|
const newLatestBlockHashByNetwork = latestIncomingTxBlockNumber
|
||||||
? parseInt(latestIncomingTxBlockNumber, 10) + 1
|
? parseInt(latestIncomingTxBlockNumber, 10) + 1
|
||||||
@ -168,28 +183,22 @@ export default class IncomingTransactionsController {
|
|||||||
this.store.updateState({
|
this.store.updateState({
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
incomingTxLastFetchedBlocksByNetwork: {
|
||||||
...currentBlocksByNetwork,
|
...currentBlocksByNetwork,
|
||||||
[network]: newLatestBlockHashByNetwork,
|
[CHAIN_ID_TO_TYPE_MAP[chainId]]: newLatestBlockHashByNetwork,
|
||||||
},
|
},
|
||||||
incomingTransactions: newIncomingTransactions,
|
incomingTransactions: newIncomingTransactions,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async _fetchAll (address, fromBlock, networkType) {
|
async _fetchAll (address, fromBlock, chainId) {
|
||||||
const fetchedTxResponse = await this._fetchTxs(address, fromBlock, networkType)
|
const fetchedTxResponse = await this._fetchTxs(address, fromBlock, chainId)
|
||||||
return this._processTxFetchResponse(fetchedTxResponse)
|
return this._processTxFetchResponse(fetchedTxResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async _fetchTxs (address, fromBlock, networkType) {
|
async _fetchTxs (address, fromBlock, chainId) {
|
||||||
let etherscanSubdomain = 'api'
|
const etherscanSubdomain = chainId === MAINNET_CHAIN_ID
|
||||||
const currentNetworkID = NETWORK_TYPE_TO_ID_MAP[networkType]?.networkId
|
? 'api'
|
||||||
|
: `api-${CHAIN_ID_TO_TYPE_MAP[chainId]}`
|
||||||
|
|
||||||
if (!currentNetworkID) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (networkType !== MAINNET) {
|
|
||||||
etherscanSubdomain = `api-${networkType}`
|
|
||||||
}
|
|
||||||
const apiUrl = `https://${etherscanSubdomain}.etherscan.io`
|
const apiUrl = `https://${etherscanSubdomain}.etherscan.io`
|
||||||
let url = `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1`
|
let url = `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1`
|
||||||
|
|
||||||
@ -202,17 +211,17 @@ export default class IncomingTransactionsController {
|
|||||||
return {
|
return {
|
||||||
...parsedResponse,
|
...parsedResponse,
|
||||||
address,
|
address,
|
||||||
currentNetworkID,
|
chainId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_processTxFetchResponse ({ status, result = [], address, currentNetworkID }) {
|
_processTxFetchResponse ({ status, result = [], address, chainId }) {
|
||||||
if (status === '1' && Array.isArray(result) && result.length > 0) {
|
if (status === '1' && Array.isArray(result) && result.length > 0) {
|
||||||
const remoteTxList = {}
|
const remoteTxList = {}
|
||||||
const remoteTxs = []
|
const remoteTxs = []
|
||||||
result.forEach((tx) => {
|
result.forEach((tx) => {
|
||||||
if (!remoteTxList[tx.hash]) {
|
if (!remoteTxList[tx.hash]) {
|
||||||
remoteTxs.push(this._normalizeTxFromEtherscan(tx, currentNetworkID))
|
remoteTxs.push(this._normalizeTxFromEtherscan(tx, chainId))
|
||||||
remoteTxList[tx.hash] = 1
|
remoteTxList[tx.hash] = 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -241,13 +250,13 @@ export default class IncomingTransactionsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalizeTxFromEtherscan (txMeta, currentNetworkID) {
|
_normalizeTxFromEtherscan (txMeta, chainId) {
|
||||||
const time = parseInt(txMeta.timeStamp, 10) * 1000
|
const time = parseInt(txMeta.timeStamp, 10) * 1000
|
||||||
const status = txMeta.isError === '0' ? 'confirmed' : 'failed'
|
const status = txMeta.isError === '0' ? 'confirmed' : 'failed'
|
||||||
return {
|
return {
|
||||||
blockNumber: txMeta.blockNumber,
|
blockNumber: txMeta.blockNumber,
|
||||||
id: createId(),
|
id: createId(),
|
||||||
metamaskNetworkId: currentNetworkID,
|
metamaskNetworkId: CHAIN_ID_TO_NETWORK_ID_MAP[chainId],
|
||||||
status,
|
status,
|
||||||
time,
|
time,
|
||||||
txParams: {
|
txParams: {
|
||||||
|
@ -57,3 +57,21 @@ export const NETWORK_TO_NAME_MAP = {
|
|||||||
[GOERLI_CHAIN_ID]: GOERLI_DISPLAY_NAME,
|
[GOERLI_CHAIN_ID]: GOERLI_DISPLAY_NAME,
|
||||||
[MAINNET_CHAIN_ID]: MAINNET_DISPLAY_NAME,
|
[MAINNET_CHAIN_ID]: MAINNET_DISPLAY_NAME,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CHAIN_ID_TO_TYPE_MAP = Object.entries(NETWORK_TYPE_TO_ID_MAP)
|
||||||
|
.reduce(
|
||||||
|
(chainIdToTypeMap, [networkType, { chainId }]) => {
|
||||||
|
chainIdToTypeMap[chainId] = networkType
|
||||||
|
return chainIdToTypeMap
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
|
||||||
|
export const CHAIN_ID_TO_NETWORK_ID_MAP = Object.values(NETWORK_TYPE_TO_ID_MAP)
|
||||||
|
.reduce(
|
||||||
|
(chainIdToNetworkIdMap, { chainId, networkId }) => {
|
||||||
|
chainIdToNetworkIdMap[chainId] = networkId
|
||||||
|
return chainIdToNetworkIdMap
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
@ -9,15 +9,18 @@ import {
|
|||||||
GOERLI,
|
GOERLI,
|
||||||
KOVAN,
|
KOVAN,
|
||||||
MAINNET,
|
MAINNET,
|
||||||
|
MAINNET_CHAIN_ID,
|
||||||
RINKEBY,
|
RINKEBY,
|
||||||
ROPSTEN,
|
ROPSTEN,
|
||||||
|
ROPSTEN_CHAIN_ID,
|
||||||
|
ROPSTEN_NETWORK_ID,
|
||||||
} from '../../../../app/scripts/controllers/network/enums'
|
} from '../../../../app/scripts/controllers/network/enums'
|
||||||
|
|
||||||
const IncomingTransactionsController = proxyquire('../../../../app/scripts/controllers/incoming-transactions', {
|
const IncomingTransactionsController = proxyquire('../../../../app/scripts/controllers/incoming-transactions', {
|
||||||
'../lib/random-id': { default: () => 54321 },
|
'../lib/random-id': { default: () => 54321 },
|
||||||
}).default
|
}).default
|
||||||
|
|
||||||
const FAKE_NETWORK = 'FAKE_NETWORK'
|
const FAKE_CHAIN_ID = '0x1338'
|
||||||
const MOCK_SELECTED_ADDRESS = '0x0101'
|
const MOCK_SELECTED_ADDRESS = '0x0101'
|
||||||
|
|
||||||
function getEmptyInitState () {
|
function getEmptyInitState () {
|
||||||
@ -48,27 +51,9 @@ function getNonEmptyInitState () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNonEmptyInitStateWithFakeNetworkState () {
|
function getMockNetworkController (chainId = FAKE_CHAIN_ID) {
|
||||||
return {
|
return {
|
||||||
incomingTransactions: {
|
getCurrentChainId: () => chainId,
|
||||||
'0x123456': { id: 777 },
|
|
||||||
},
|
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
|
||||||
[ROPSTEN]: 1,
|
|
||||||
[RINKEBY]: 2,
|
|
||||||
[KOVAN]: 3,
|
|
||||||
[GOERLI]: 5,
|
|
||||||
[MAINNET]: 4,
|
|
||||||
[FAKE_NETWORK]: 1111,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMockNetworkController (networkType = FAKE_NETWORK) {
|
|
||||||
return {
|
|
||||||
getProviderConfig: () => {
|
|
||||||
return { type: networkType }
|
|
||||||
},
|
|
||||||
on: sinon.spy(),
|
on: sinon.spy(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +149,6 @@ describe('IncomingTransactionsController', function () {
|
|||||||
assert.equal(incomingTransactionsController._update.callCount, 1)
|
assert.equal(incomingTransactionsController._update.callCount, 1)
|
||||||
assert.deepEqual(incomingTransactionsController._update.getCall(0).args[0], {
|
assert.deepEqual(incomingTransactionsController._update.getCall(0).args[0], {
|
||||||
address: '0x0101',
|
address: '0x0101',
|
||||||
networkType: 'testNetworkType',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
incomingTransactionsController._update.resetHistory()
|
incomingTransactionsController._update.resetHistory()
|
||||||
@ -200,7 +184,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should update upon latest block when started and on supported network', async function () {
|
it('should update upon latest block when started and on supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(ROPSTEN),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -258,34 +242,44 @@ describe('IncomingTransactionsController', function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update last block fetched when started and not on supported network', async function () {
|
it('should not update upon latest block when started and not on supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
// reply with a valid request for any supported network, so that this test has every opportunity to fail
|
||||||
|
for (const network of [GOERLI, KOVAN, MAINNET, RINKEBY, ROPSTEN]) {
|
||||||
|
nock(`https://api${network === MAINNET ? '' : `-${network.toLowerCase()}`}.etherscan.io`)
|
||||||
|
.get(/api.+/u)
|
||||||
|
.reply(
|
||||||
|
200,
|
||||||
|
JSON.stringify({
|
||||||
|
status: '1',
|
||||||
|
result: [getFakeEtherscanTransaction()],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
||||||
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
||||||
|
const putStateStub = sinon.stub(incomingTransactionsController.store, 'putState')
|
||||||
|
const putStateCalled = waitUntilCalled(putStateStub, incomingTransactionsController.store)
|
||||||
|
|
||||||
incomingTransactionsController.start()
|
incomingTransactionsController.start()
|
||||||
|
|
||||||
await updateStateCalled
|
try {
|
||||||
|
await Promise.race([
|
||||||
const state = incomingTransactionsController.store.getState()
|
updateStateCalled,
|
||||||
assert.deepStrictEqual(
|
putStateCalled,
|
||||||
state,
|
new Promise((_, reject) => {
|
||||||
{
|
setTimeout(() => reject(new Error('TIMEOUT')), 1000)
|
||||||
incomingTransactions: {
|
}),
|
||||||
...getNonEmptyInitState().incomingTransactions,
|
])
|
||||||
},
|
assert.fail('Update state should not have been called')
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
} catch (error) {
|
||||||
...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork,
|
assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown')
|
||||||
[FAKE_NETWORK]: 11,
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
'Should update last block fetched',
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not update upon latest block when started and incoming transactions disabled', async function () {
|
it('should not update upon latest block when started and incoming transactions disabled', async function () {
|
||||||
@ -331,7 +325,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should not update upon latest block when not started', async function () {
|
it('should not update upon latest block when not started', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(ROPSTEN),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -369,7 +363,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should not update upon latest block when stopped', async function () {
|
it('should not update upon latest block when stopped', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(ROPSTEN),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -409,7 +403,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should update when the selected address changes and on supported network', async function () {
|
it('should update when the selected address changes and on supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(ROPSTEN),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -473,7 +467,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update last block fetched when selected address changes and not on supported network', async function () {
|
it('should not update when the selected address changes and not on supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: { ...getMockBlockTracker() },
|
blockTracker: { ...getMockBlockTracker() },
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(),
|
||||||
@ -495,6 +489,8 @@ describe('IncomingTransactionsController', function () {
|
|||||||
}
|
}
|
||||||
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
||||||
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
||||||
|
const putStateStub = sinon.stub(incomingTransactionsController.store, 'putState')
|
||||||
|
const putStateCalled = waitUntilCalled(putStateStub, incomingTransactionsController.store)
|
||||||
|
|
||||||
const subscription = incomingTransactionsController.preferencesController.store.subscribe.getCall(1).args[0]
|
const subscription = incomingTransactionsController.preferencesController.store.subscribe.getCall(1).args[0]
|
||||||
// The incoming transactions controller will always skip the first event
|
// The incoming transactions controller will always skip the first event
|
||||||
@ -503,28 +499,24 @@ describe('IncomingTransactionsController', function () {
|
|||||||
await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS })
|
await subscription({ selectedAddress: MOCK_SELECTED_ADDRESS })
|
||||||
await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS })
|
await subscription({ selectedAddress: NEW_MOCK_SELECTED_ADDRESS })
|
||||||
|
|
||||||
await updateStateCalled
|
try {
|
||||||
|
await Promise.race([
|
||||||
const state = incomingTransactionsController.store.getState()
|
updateStateCalled,
|
||||||
assert.deepStrictEqual(
|
putStateCalled,
|
||||||
state,
|
new Promise((_, reject) => {
|
||||||
{
|
setTimeout(() => reject(new Error('TIMEOUT')), 1000)
|
||||||
incomingTransactions: {
|
}),
|
||||||
...getNonEmptyInitState().incomingTransactions,
|
])
|
||||||
},
|
assert.fail('Update state should not have been called')
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
} catch (error) {
|
||||||
...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork,
|
assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown')
|
||||||
[FAKE_NETWORK]: 11,
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
'Should update last block fetched',
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update when switching to a supported network', async function () {
|
it('should update when switching to a supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(ROPSTEN),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -542,7 +534,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
||||||
|
|
||||||
const subscription = incomingTransactionsController.networkController.on.getCall(0).args[1]
|
const subscription = incomingTransactionsController.networkController.on.getCall(0).args[1]
|
||||||
incomingTransactionsController.networkController = getMockNetworkController(ROPSTEN)
|
incomingTransactionsController.networkController = getMockNetworkController(ROPSTEN_CHAIN_ID)
|
||||||
await subscription(ROPSTEN)
|
await subscription(ROPSTEN)
|
||||||
await updateStateCalled
|
await updateStateCalled
|
||||||
|
|
||||||
@ -584,10 +576,11 @@ describe('IncomingTransactionsController', function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should update last block fetched when switching to an unsupported network', async function () {
|
it('should not update when switching to an unsupported network', async function () {
|
||||||
|
const networkController = getMockNetworkController(ROPSTEN_CHAIN_ID)
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController,
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -605,26 +598,26 @@ describe('IncomingTransactionsController', function () {
|
|||||||
}
|
}
|
||||||
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
const updateStateStub = sinon.stub(incomingTransactionsController.store, 'updateState')
|
||||||
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
const updateStateCalled = waitUntilCalled(updateStateStub, incomingTransactionsController.store)
|
||||||
|
const putStateStub = sinon.stub(incomingTransactionsController.store, 'putState')
|
||||||
|
const putStateCalled = waitUntilCalled(putStateStub, incomingTransactionsController.store)
|
||||||
|
|
||||||
const subscription = incomingTransactionsController.networkController.on.getCall(0).args[1]
|
const subscription = incomingTransactionsController.networkController.on.getCall(0).args[1]
|
||||||
await subscription('SECOND_FAKE_NETWORK')
|
|
||||||
|
|
||||||
await updateStateCalled
|
networkController.getCurrentChainId = () => FAKE_CHAIN_ID
|
||||||
|
await subscription()
|
||||||
|
|
||||||
const state = incomingTransactionsController.store.getState()
|
try {
|
||||||
assert.deepStrictEqual(
|
await Promise.race([
|
||||||
state,
|
updateStateCalled,
|
||||||
{
|
putStateCalled,
|
||||||
incomingTransactions: {
|
new Promise((_, reject) => {
|
||||||
...getNonEmptyInitState().incomingTransactions,
|
setTimeout(() => reject(new Error('TIMEOUT')), 1000)
|
||||||
},
|
}),
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
])
|
||||||
...getNonEmptyInitState().incomingTxLastFetchedBlocksByNetwork,
|
assert.fail('Update state should not have been called')
|
||||||
SECOND_FAKE_NETWORK: 11,
|
} catch (error) {
|
||||||
},
|
assert(error.message === 'TIMEOUT', 'TIMEOUT error should be thrown')
|
||||||
},
|
}
|
||||||
'Should update last block fetched',
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -632,66 +625,53 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should call fetchAll with the correct params when passed a new block number and the current network has no stored block', async function () {
|
it('should call fetchAll with the correct params when passed a new block number and the current network has no stored block', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getEmptyInitState(),
|
||||||
})
|
})
|
||||||
incomingTransactionsController._fetchAll = sinon.stub().returns({})
|
incomingTransactionsController._fetchAll = sinon.stub().returns({})
|
||||||
|
|
||||||
await incomingTransactionsController._getDataForUpdate({ address: 'fakeAddress', newBlockNumberDec: 999 })
|
await incomingTransactionsController._getDataForUpdate({
|
||||||
|
address: 'fakeAddress',
|
||||||
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
|
newBlockNumberDec: 999,
|
||||||
|
})
|
||||||
|
|
||||||
assert(incomingTransactionsController._fetchAll.calledOnce)
|
assert(incomingTransactionsController._fetchAll.calledOnce)
|
||||||
|
|
||||||
assert.deepEqual(incomingTransactionsController._fetchAll.getCall(0).args, [
|
assert.deepEqual(incomingTransactionsController._fetchAll.getCall(0).args, [
|
||||||
'fakeAddress', 999, 'FAKE_NETWORK',
|
'fakeAddress', 999, ROPSTEN_CHAIN_ID,
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call fetchAll with the correct params when passed a new block number but the current network has a stored block', async function () {
|
it('should call fetchAll with the correct params when passed a new block number but the current network has a stored block', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitStateWithFakeNetworkState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
|
||||||
incomingTransactionsController._fetchAll = sinon.stub().returns({})
|
|
||||||
|
|
||||||
await incomingTransactionsController._getDataForUpdate({ address: 'fakeAddress', newBlockNumberDec: 999 })
|
|
||||||
|
|
||||||
assert(incomingTransactionsController._fetchAll.calledOnce)
|
|
||||||
|
|
||||||
assert.deepEqual(incomingTransactionsController._fetchAll.getCall(0).args, [
|
|
||||||
'fakeAddress', 1111, 'FAKE_NETWORK',
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should call fetchAll with the correct params when passed a new network type but no block info exists', async function () {
|
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
|
||||||
blockTracker: getMockBlockTracker(),
|
|
||||||
networkController: getMockNetworkController(),
|
|
||||||
preferencesController: getMockPreferencesController(),
|
|
||||||
initState: getNonEmptyInitStateWithFakeNetworkState(),
|
|
||||||
})
|
})
|
||||||
incomingTransactionsController._fetchAll = sinon.stub().returns({})
|
incomingTransactionsController._fetchAll = sinon.stub().returns({})
|
||||||
|
|
||||||
await incomingTransactionsController._getDataForUpdate({
|
await incomingTransactionsController._getDataForUpdate({
|
||||||
address: 'fakeAddress',
|
address: 'fakeAddress',
|
||||||
networkType: 'NEW_FAKE_NETWORK',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
|
newBlockNumberDec: 999,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert(incomingTransactionsController._fetchAll.calledOnce)
|
assert(incomingTransactionsController._fetchAll.calledOnce)
|
||||||
|
|
||||||
assert.deepEqual(incomingTransactionsController._fetchAll.getCall(0).args, [
|
assert.deepEqual(incomingTransactionsController._fetchAll.getCall(0).args, [
|
||||||
'fakeAddress', 10, 'NEW_FAKE_NETWORK',
|
'fakeAddress', 4, ROPSTEN_CHAIN_ID,
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return the expected data', async function () {
|
it('should return the expected data', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitStateWithFakeNetworkState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
incomingTransactionsController._fetchAll = sinon.stub().returns({
|
incomingTransactionsController._fetchAll = sinon.stub().returns({
|
||||||
latestIncomingTxBlockNumber: 444,
|
latestIncomingTxBlockNumber: 444,
|
||||||
@ -700,7 +680,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
|
|
||||||
const result = await incomingTransactionsController._getDataForUpdate({
|
const result = await incomingTransactionsController._getDataForUpdate({
|
||||||
address: 'fakeAddress',
|
address: 'fakeAddress',
|
||||||
networkType: 'FAKE_NETWORK',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
@ -710,15 +690,14 @@ describe('IncomingTransactionsController', function () {
|
|||||||
'0x123456': { id: 777 },
|
'0x123456': { id: 777 },
|
||||||
},
|
},
|
||||||
currentBlocksByNetwork: {
|
currentBlocksByNetwork: {
|
||||||
[ROPSTEN]: 1,
|
[GOERLI]: 1,
|
||||||
[RINKEBY]: 2,
|
[KOVAN]: 2,
|
||||||
[KOVAN]: 3,
|
[MAINNET]: 3,
|
||||||
[GOERLI]: 5,
|
[RINKEBY]: 5,
|
||||||
[MAINNET]: 4,
|
[ROPSTEN]: 4,
|
||||||
FAKE_NETWORK: 1111,
|
|
||||||
},
|
},
|
||||||
fetchedBlockNumber: 1111,
|
fetchedBlockNumber: 4,
|
||||||
network: 'FAKE_NETWORK',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -730,15 +709,14 @@ describe('IncomingTransactionsController', function () {
|
|||||||
'0x123456': { id: 777, hash: '0x123456' },
|
'0x123456': { id: 777, hash: '0x123456' },
|
||||||
},
|
},
|
||||||
currentBlocksByNetwork: {
|
currentBlocksByNetwork: {
|
||||||
[ROPSTEN]: 1,
|
[GOERLI]: 1,
|
||||||
[RINKEBY]: 2,
|
[KOVAN]: 2,
|
||||||
[KOVAN]: 3,
|
[MAINNET]: 3,
|
||||||
[GOERLI]: 5,
|
[RINKEBY]: 5,
|
||||||
[MAINNET]: 4,
|
[ROPSTEN]: 4,
|
||||||
FAKE_NETWORK: 1111,
|
|
||||||
},
|
},
|
||||||
fetchedBlockNumber: 1111,
|
fetchedBlockNumber: 1111,
|
||||||
network: 'FAKE_NETWORK',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MOCK_INPUT_WITH_LASTEST = {
|
const MOCK_INPUT_WITH_LASTEST = {
|
||||||
@ -749,7 +727,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should update state with correct blockhash and transactions when passed a truthy latestIncomingTxBlockNumber', async function () {
|
it('should update state with correct blockhash and transactions when passed a truthy latestIncomingTxBlockNumber', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -762,7 +740,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
assert.deepEqual(incomingTransactionsController.store.updateState.getCall(0).args[0], {
|
assert.deepEqual(incomingTransactionsController.store.updateState.getCall(0).args[0], {
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
incomingTxLastFetchedBlocksByNetwork: {
|
||||||
...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork,
|
...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork,
|
||||||
'FAKE_NETWORK': 445,
|
[ROPSTEN]: 445,
|
||||||
},
|
},
|
||||||
incomingTransactions: {
|
incomingTransactions: {
|
||||||
'0x123456': { id: 777, hash: '0x123456' },
|
'0x123456': { id: 777, hash: '0x123456' },
|
||||||
@ -774,7 +752,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should update state with correct blockhash and transactions when passed a falsy latestIncomingTxBlockNumber', async function () {
|
it('should update state with correct blockhash and transactions when passed a falsy latestIncomingTxBlockNumber', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -787,7 +765,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
assert.deepEqual(incomingTransactionsController.store.updateState.getCall(0).args[0], {
|
assert.deepEqual(incomingTransactionsController.store.updateState.getCall(0).args[0], {
|
||||||
incomingTxLastFetchedBlocksByNetwork: {
|
incomingTxLastFetchedBlocksByNetwork: {
|
||||||
...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork,
|
...MOCK_INPUT_WITH_LASTEST.currentBlocksByNetwork,
|
||||||
'FAKE_NETWORK': 1112,
|
[ROPSTEN]: 1112,
|
||||||
},
|
},
|
||||||
incomingTransactions: {
|
incomingTransactions: {
|
||||||
'0x123456': { id: 777, hash: '0x123456' },
|
'0x123456': { id: 777, hash: '0x123456' },
|
||||||
@ -815,12 +793,12 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should call fetch with the expected url when passed an address, block number and supported network', async function () {
|
it('should call fetch with the expected url when passed an address, block number and supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
|
||||||
await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', ROPSTEN)
|
await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', ROPSTEN_CHAIN_ID)
|
||||||
|
|
||||||
assert(mockFetch.calledOnce)
|
assert(mockFetch.calledOnce)
|
||||||
assert.equal(mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`)
|
assert.equal(mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`)
|
||||||
@ -829,12 +807,12 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should call fetch with the expected url when passed an address, block number and MAINNET', async function () {
|
it('should call fetch with the expected url when passed an address, block number and MAINNET', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(MAINNET_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
|
||||||
await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', MAINNET)
|
await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', MAINNET_CHAIN_ID)
|
||||||
|
|
||||||
assert(mockFetch.calledOnce)
|
assert(mockFetch.calledOnce)
|
||||||
assert.equal(mockFetch.getCall(0).args[0], `https://api.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`)
|
assert.equal(mockFetch.getCall(0).args[0], `https://api.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1&startBlock=789`)
|
||||||
@ -843,46 +821,32 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should call fetch with the expected url when passed an address and supported network, but a falsy block number', async function () {
|
it('should call fetch with the expected url when passed an address and supported network, but a falsy block number', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
|
||||||
await incomingTransactionsController._fetchTxs('0xfakeaddress', null, ROPSTEN)
|
await incomingTransactionsController._fetchTxs('0xfakeaddress', null, ROPSTEN_CHAIN_ID)
|
||||||
|
|
||||||
assert(mockFetch.calledOnce)
|
assert(mockFetch.calledOnce)
|
||||||
assert.equal(mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1`)
|
assert.equal(mockFetch.getCall(0).args[0], `https://api-${ROPSTEN}.etherscan.io/api?module=account&action=txlist&address=0xfakeaddress&tag=latest&page=1`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not fetch and return an empty object when passed an unsported network', async function () {
|
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
|
||||||
blockTracker: getMockBlockTracker(),
|
|
||||||
networkController: getMockNetworkController(),
|
|
||||||
preferencesController: getMockPreferencesController(),
|
|
||||||
initState: getNonEmptyInitState(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = await incomingTransactionsController._fetchTxs('0xfakeaddress', null, 'UNSUPPORTED_NETWORK')
|
|
||||||
|
|
||||||
assert(mockFetch.notCalled)
|
|
||||||
assert.deepEqual(result, {})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return the results from the fetch call, plus the address and currentNetworkID, when passed an address, block number and supported network', async function () {
|
it('should return the results from the fetch call, plus the address and currentNetworkID, when passed an address, block number and supported network', async function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', ROPSTEN)
|
const result = await incomingTransactionsController._fetchTxs('0xfakeaddress', '789', ROPSTEN_CHAIN_ID)
|
||||||
|
|
||||||
assert(mockFetch.calledOnce)
|
assert(mockFetch.calledOnce)
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
someKey: 'someValue',
|
someKey: 'someValue',
|
||||||
address: '0xfakeaddress',
|
address: '0xfakeaddress',
|
||||||
currentNetworkID: '3',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -891,7 +855,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should return a null block number and empty tx array if status is 0', function () {
|
it('should return a null block number and empty tx array if status is 0', function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -911,7 +875,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should return a null block number and empty tx array if the passed result array is empty', function () {
|
it('should return a null block number and empty tx array if the passed result array is empty', function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -931,21 +895,21 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should return the expected block number and tx list when passed data from a successful fetch', function () {
|
it('should return the expected block number and tx list when passed data from a successful fetch', function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
|
|
||||||
incomingTransactionsController._normalizeTxFromEtherscan = (tx, currentNetworkID) => ({
|
incomingTransactionsController._normalizeTxFromEtherscan = (tx) => ({
|
||||||
...tx,
|
...tx,
|
||||||
currentNetworkID,
|
currentNetworkID: ROPSTEN_NETWORK_ID,
|
||||||
normalized: true,
|
normalized: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = incomingTransactionsController._processTxFetchResponse({
|
const result = incomingTransactionsController._processTxFetchResponse({
|
||||||
status: '1',
|
status: '1',
|
||||||
address: '0xfakeaddress',
|
address: '0xfakeaddress',
|
||||||
currentNetworkID: 'FAKE_NETWORK',
|
chainId: ROPSTEN_CHAIN_ID,
|
||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
hash: '0xabc123',
|
hash: '0xabc123',
|
||||||
@ -1009,7 +973,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
blockNumber: 5000,
|
blockNumber: 5000,
|
||||||
time: 9,
|
time: 9,
|
||||||
normalized: true,
|
normalized: true,
|
||||||
currentNetworkID: 'FAKE_NETWORK',
|
currentNetworkID: ROPSTEN_NETWORK_ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
hash: '0xabc123',
|
hash: '0xabc123',
|
||||||
@ -1019,7 +983,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
blockNumber: 5000,
|
blockNumber: 5000,
|
||||||
time: 10,
|
time: 10,
|
||||||
normalized: true,
|
normalized: true,
|
||||||
currentNetworkID: 'FAKE_NETWORK',
|
currentNetworkID: ROPSTEN_NETWORK_ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
hash: '0xabc12345',
|
hash: '0xabc12345',
|
||||||
@ -1029,7 +993,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
blockNumber: 5001,
|
blockNumber: 5001,
|
||||||
time: 11,
|
time: 11,
|
||||||
normalized: true,
|
normalized: true,
|
||||||
currentNetworkID: 'FAKE_NETWORK',
|
currentNetworkID: ROPSTEN_NETWORK_ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
hash: '0xabc123456',
|
hash: '0xabc123456',
|
||||||
@ -1039,7 +1003,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
blockNumber: 5001,
|
blockNumber: 5001,
|
||||||
time: 12,
|
time: 12,
|
||||||
normalized: true,
|
normalized: true,
|
||||||
currentNetworkID: 'FAKE_NETWORK',
|
currentNetworkID: ROPSTEN_NETWORK_ID,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@ -1050,7 +1014,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should return the expected data when the tx is in error', function () {
|
it('should return the expected data when the tx is in error', function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -1066,12 +1030,12 @@ describe('IncomingTransactionsController', function () {
|
|||||||
to: '0xe',
|
to: '0xe',
|
||||||
value: '15',
|
value: '15',
|
||||||
hash: '0xg',
|
hash: '0xg',
|
||||||
}, 'FAKE_NETWORK')
|
}, ROPSTEN_CHAIN_ID)
|
||||||
|
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
blockNumber: 333,
|
blockNumber: 333,
|
||||||
id: 54321,
|
id: 54321,
|
||||||
metamaskNetworkId: 'FAKE_NETWORK',
|
metamaskNetworkId: ROPSTEN_NETWORK_ID,
|
||||||
status: 'failed',
|
status: 'failed',
|
||||||
time: 4444000,
|
time: 4444000,
|
||||||
txParams: {
|
txParams: {
|
||||||
@ -1090,7 +1054,7 @@ describe('IncomingTransactionsController', function () {
|
|||||||
it('should return the expected data when the tx is not in error', function () {
|
it('should return the expected data when the tx is not in error', function () {
|
||||||
const incomingTransactionsController = new IncomingTransactionsController({
|
const incomingTransactionsController = new IncomingTransactionsController({
|
||||||
blockTracker: getMockBlockTracker(),
|
blockTracker: getMockBlockTracker(),
|
||||||
networkController: getMockNetworkController(),
|
networkController: getMockNetworkController(ROPSTEN_CHAIN_ID),
|
||||||
preferencesController: getMockPreferencesController(),
|
preferencesController: getMockPreferencesController(),
|
||||||
initState: getNonEmptyInitState(),
|
initState: getNonEmptyInitState(),
|
||||||
})
|
})
|
||||||
@ -1106,12 +1070,12 @@ describe('IncomingTransactionsController', function () {
|
|||||||
to: '0xe',
|
to: '0xe',
|
||||||
value: '15',
|
value: '15',
|
||||||
hash: '0xg',
|
hash: '0xg',
|
||||||
}, 'FAKE_NETWORK')
|
}, ROPSTEN_CHAIN_ID)
|
||||||
|
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
blockNumber: 333,
|
blockNumber: 333,
|
||||||
id: 54321,
|
id: 54321,
|
||||||
metamaskNetworkId: 'FAKE_NETWORK',
|
metamaskNetworkId: ROPSTEN_NETWORK_ID,
|
||||||
status: 'confirmed',
|
status: 'confirmed',
|
||||||
time: 4444000,
|
time: 4444000,
|
||||||
txParams: {
|
txParams: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user