2017-01-25 18:51:41 +01:00
|
|
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
Initial new UI source code import (#2607)
* address -> name mappings
* expanding, loading all coin details
* send use only actual BasicCoin tokens registered (any reg)
* sending token & accounts
* form styling updates
* send form layout in place
* coin send working as expected
* api subscriptions on multiple addresses
* bring in events
* simplify
* basic events display in-place, functionally complete
* basic functionality in-place
* fix horrible event address issue
* rwork display of events slightly
* test TLA availability
* table for owner -> tokens
* fix signature lookup address
* fix signature lookup address
* basic overview styling
* txhash links
* page layout adjustments
* background import
* adjust colors
* no global registration, simplify color selection
* updated styling
* connection dialog for "busy connecting"
* initial token connection - WIP
* init token updates take place
* basic test for manual token
* rework connection display
* allow updates of the secure token
* first stab at making the build build
* update runner tags
* fix linting issues
* skip tests requiring network (should be e2e, TODO)
* re-enable javascript tag/runner
* release push does the trick
* push to any branch, CI name
* javscript-test runner as well
* swap dependencies build requires test
* revert stages swap
* retrieve images associated with tokens
* remove js build deps order
* null image when hash = 0x0
* 6x64 images (hashes for registries)
* don't pass tokens as prop to IdentityIcon
* check images against content hash pictures
* cleanup signer after connection changes
* fix naming typo
* display unknownImages for balances (not available as content hash)
* unknownImage for transfer dialog
* basic githubhint layout
* single input for commit/filename
* ethcore_hashContent call
* lookup hash
* registration in place
* fixes
* events is using a proper table
* pass value through as-is
* stop wrongly using main app IdentityIcon
* NEVER export class instance functions
* alignment back to normal
* typo in definition
* set & get images working (mostly)
* show content retrieval info
* set exitcode via ||
* use javascript:latest images
* disable npm progress bar
* rename phase I
* rename phase II
* only send build output to GitHub on major branches
* also run the build step as part of the test (until comprehensive)
* ci-specific build (no webpack progress)
* allow for account creation via recovery phrase
* display account uuid (where available), closes #2546
* connection dialog now shows up in dapps as well, closes #2538
* token images show up as expected
* IdentityName component added and deployed
* fix padding tests
* adjust tests to map to stricter 0x-prefixed hex
* render names via common component for the address -> name
* split lint into seperate script (early exit)
* test phases changed to lint, test & pack
* pack part of test phase
* remove files marked for deletion (cleanup)
* Signer cleanups, start moving in the direction of the rest
* add personal signer methods
* basic signer request subscription
* don't poll blockNumber when not connected
* missing return, creating massive ws queue backlogs
* ΞTH -> ETH
* fix failing tests
* registry uses setAddress to actually set addresses now
* bytes mapping operates on lowerCase hex strings
* sha3 ids for each application
* add dappreg to list of contracts
* adjust alignment of queries
* show gas estimation log
* abi with payable for register function
* add key as required
* image retrieval from dappreg
* use proper Image urls
* embed and link apps from Parity, retrieved via /api/apps
* filter apps that has been replaced
* proxy entry for parity-utils
* add basiccoin abi
* add support for fallback abi type
* capture constructor paramaters
* merge master into js
* move images to assets/images/
* add font assets
* import fonts as part of build
* don't inline woff files
* Revert "merge master into js"
This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe.
* remove unused npm packages
* information on gas estimates (like almost everywhere else)
* don't pass gas & gasPrice to estimation
* display account passwordhint when available
* signer subscriptions based on polling & function trapping
* pending requests retrieved via jsapi
* update signer middleware
* remove all web3 instances
* remove web3 package
* last web3 dependencies removed
* no need to toChecksumAddress - api takes care of it
* expand description for personal_confirmRequest
* Signer conversion from web3 -> parity.js completed
* explicit in no return
* green circle background
* remove generated background
* convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary)
* change dapps to load from localhost:8080/ui/*
* remove dangling web3 files
* update manager test for signer
* /api/ping -> /
* additional token images
* additional token images
* add missing styles.css for 8180 error pages
* cater for txhash returning null/empty object
* adjust output directories
* Release merge with origin with ours strategy
* additional token images
* cater for development server
* s/localhost/127.0.0.1/ (cater for origin)
* Fix address selection for contract deployment
* Adjust z-index for error overlay
* better text on unique background pattern
* fix signer rejections
* Don't allow gavcoin transfer with no balance
* fix txhash rendering in signer
* remove unnecessary ParityBackground
* script to update js-precompiled
* Redirect from :8080 to :8180
* Remove extra return
* Dapp logo images
2016-10-18 11:52:56 +02:00
|
|
|
// This file is part of Parity.
|
|
|
|
|
|
|
|
// Parity is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// Parity is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
import { uniq, isEqual } from 'lodash';
|
2016-12-10 23:55:36 +01:00
|
|
|
import { push } from 'react-router-redux';
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-21 11:40:22 +02:00
|
|
|
import { sha3 } from '@parity/api/util/sha3';
|
|
|
|
|
2017-05-09 12:01:44 +02:00
|
|
|
import { LOG_KEYS, getLogger } from '@parity/shared/config';
|
|
|
|
import { notifyTransaction } from '@parity/shared/util/notifications';
|
|
|
|
import { ETH_TOKEN, fetchAccountsBalances } from '@parity/shared/util/tokens';
|
2016-12-10 23:55:36 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const TRANSFER_SIGNATURE = sha3('Transfer(address,address,uint256)');
|
2016-12-10 23:55:36 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const log = getLogger(LOG_KEYS.Balances);
|
2016-12-10 23:55:36 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
let tokensFilter = {};
|
2016-12-10 23:55:36 +01:00
|
|
|
|
|
|
|
function _setBalances (balances) {
|
Initial new UI source code import (#2607)
* address -> name mappings
* expanding, loading all coin details
* send use only actual BasicCoin tokens registered (any reg)
* sending token & accounts
* form styling updates
* send form layout in place
* coin send working as expected
* api subscriptions on multiple addresses
* bring in events
* simplify
* basic events display in-place, functionally complete
* basic functionality in-place
* fix horrible event address issue
* rwork display of events slightly
* test TLA availability
* table for owner -> tokens
* fix signature lookup address
* fix signature lookup address
* basic overview styling
* txhash links
* page layout adjustments
* background import
* adjust colors
* no global registration, simplify color selection
* updated styling
* connection dialog for "busy connecting"
* initial token connection - WIP
* init token updates take place
* basic test for manual token
* rework connection display
* allow updates of the secure token
* first stab at making the build build
* update runner tags
* fix linting issues
* skip tests requiring network (should be e2e, TODO)
* re-enable javascript tag/runner
* release push does the trick
* push to any branch, CI name
* javscript-test runner as well
* swap dependencies build requires test
* revert stages swap
* retrieve images associated with tokens
* remove js build deps order
* null image when hash = 0x0
* 6x64 images (hashes for registries)
* don't pass tokens as prop to IdentityIcon
* check images against content hash pictures
* cleanup signer after connection changes
* fix naming typo
* display unknownImages for balances (not available as content hash)
* unknownImage for transfer dialog
* basic githubhint layout
* single input for commit/filename
* ethcore_hashContent call
* lookup hash
* registration in place
* fixes
* events is using a proper table
* pass value through as-is
* stop wrongly using main app IdentityIcon
* NEVER export class instance functions
* alignment back to normal
* typo in definition
* set & get images working (mostly)
* show content retrieval info
* set exitcode via ||
* use javascript:latest images
* disable npm progress bar
* rename phase I
* rename phase II
* only send build output to GitHub on major branches
* also run the build step as part of the test (until comprehensive)
* ci-specific build (no webpack progress)
* allow for account creation via recovery phrase
* display account uuid (where available), closes #2546
* connection dialog now shows up in dapps as well, closes #2538
* token images show up as expected
* IdentityName component added and deployed
* fix padding tests
* adjust tests to map to stricter 0x-prefixed hex
* render names via common component for the address -> name
* split lint into seperate script (early exit)
* test phases changed to lint, test & pack
* pack part of test phase
* remove files marked for deletion (cleanup)
* Signer cleanups, start moving in the direction of the rest
* add personal signer methods
* basic signer request subscription
* don't poll blockNumber when not connected
* missing return, creating massive ws queue backlogs
* ΞTH -> ETH
* fix failing tests
* registry uses setAddress to actually set addresses now
* bytes mapping operates on lowerCase hex strings
* sha3 ids for each application
* add dappreg to list of contracts
* adjust alignment of queries
* show gas estimation log
* abi with payable for register function
* add key as required
* image retrieval from dappreg
* use proper Image urls
* embed and link apps from Parity, retrieved via /api/apps
* filter apps that has been replaced
* proxy entry for parity-utils
* add basiccoin abi
* add support for fallback abi type
* capture constructor paramaters
* merge master into js
* move images to assets/images/
* add font assets
* import fonts as part of build
* don't inline woff files
* Revert "merge master into js"
This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe.
* remove unused npm packages
* information on gas estimates (like almost everywhere else)
* don't pass gas & gasPrice to estimation
* display account passwordhint when available
* signer subscriptions based on polling & function trapping
* pending requests retrieved via jsapi
* update signer middleware
* remove all web3 instances
* remove web3 package
* last web3 dependencies removed
* no need to toChecksumAddress - api takes care of it
* expand description for personal_confirmRequest
* Signer conversion from web3 -> parity.js completed
* explicit in no return
* green circle background
* remove generated background
* convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary)
* change dapps to load from localhost:8080/ui/*
* remove dangling web3 files
* update manager test for signer
* /api/ping -> /
* additional token images
* additional token images
* add missing styles.css for 8180 error pages
* cater for txhash returning null/empty object
* adjust output directories
* Release merge with origin with ours strategy
* additional token images
* cater for development server
* s/localhost/127.0.0.1/ (cater for origin)
* Fix address selection for contract deployment
* Adjust z-index for error overlay
* better text on unique background pattern
* fix signer rejections
* Don't allow gavcoin transfer with no balance
* fix txhash rendering in signer
* remove unnecessary ParityBackground
* script to update js-precompiled
* Redirect from :8080 to :8180
* Remove extra return
* Dapp logo images
2016-10-18 11:52:56 +02:00
|
|
|
return {
|
2016-11-25 16:46:35 +01:00
|
|
|
type: 'setBalances',
|
Initial new UI source code import (#2607)
* address -> name mappings
* expanding, loading all coin details
* send use only actual BasicCoin tokens registered (any reg)
* sending token & accounts
* form styling updates
* send form layout in place
* coin send working as expected
* api subscriptions on multiple addresses
* bring in events
* simplify
* basic events display in-place, functionally complete
* basic functionality in-place
* fix horrible event address issue
* rwork display of events slightly
* test TLA availability
* table for owner -> tokens
* fix signature lookup address
* fix signature lookup address
* basic overview styling
* txhash links
* page layout adjustments
* background import
* adjust colors
* no global registration, simplify color selection
* updated styling
* connection dialog for "busy connecting"
* initial token connection - WIP
* init token updates take place
* basic test for manual token
* rework connection display
* allow updates of the secure token
* first stab at making the build build
* update runner tags
* fix linting issues
* skip tests requiring network (should be e2e, TODO)
* re-enable javascript tag/runner
* release push does the trick
* push to any branch, CI name
* javscript-test runner as well
* swap dependencies build requires test
* revert stages swap
* retrieve images associated with tokens
* remove js build deps order
* null image when hash = 0x0
* 6x64 images (hashes for registries)
* don't pass tokens as prop to IdentityIcon
* check images against content hash pictures
* cleanup signer after connection changes
* fix naming typo
* display unknownImages for balances (not available as content hash)
* unknownImage for transfer dialog
* basic githubhint layout
* single input for commit/filename
* ethcore_hashContent call
* lookup hash
* registration in place
* fixes
* events is using a proper table
* pass value through as-is
* stop wrongly using main app IdentityIcon
* NEVER export class instance functions
* alignment back to normal
* typo in definition
* set & get images working (mostly)
* show content retrieval info
* set exitcode via ||
* use javascript:latest images
* disable npm progress bar
* rename phase I
* rename phase II
* only send build output to GitHub on major branches
* also run the build step as part of the test (until comprehensive)
* ci-specific build (no webpack progress)
* allow for account creation via recovery phrase
* display account uuid (where available), closes #2546
* connection dialog now shows up in dapps as well, closes #2538
* token images show up as expected
* IdentityName component added and deployed
* fix padding tests
* adjust tests to map to stricter 0x-prefixed hex
* render names via common component for the address -> name
* split lint into seperate script (early exit)
* test phases changed to lint, test & pack
* pack part of test phase
* remove files marked for deletion (cleanup)
* Signer cleanups, start moving in the direction of the rest
* add personal signer methods
* basic signer request subscription
* don't poll blockNumber when not connected
* missing return, creating massive ws queue backlogs
* ΞTH -> ETH
* fix failing tests
* registry uses setAddress to actually set addresses now
* bytes mapping operates on lowerCase hex strings
* sha3 ids for each application
* add dappreg to list of contracts
* adjust alignment of queries
* show gas estimation log
* abi with payable for register function
* add key as required
* image retrieval from dappreg
* use proper Image urls
* embed and link apps from Parity, retrieved via /api/apps
* filter apps that has been replaced
* proxy entry for parity-utils
* add basiccoin abi
* add support for fallback abi type
* capture constructor paramaters
* merge master into js
* move images to assets/images/
* add font assets
* import fonts as part of build
* don't inline woff files
* Revert "merge master into js"
This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe.
* remove unused npm packages
* information on gas estimates (like almost everywhere else)
* don't pass gas & gasPrice to estimation
* display account passwordhint when available
* signer subscriptions based on polling & function trapping
* pending requests retrieved via jsapi
* update signer middleware
* remove all web3 instances
* remove web3 package
* last web3 dependencies removed
* no need to toChecksumAddress - api takes care of it
* expand description for personal_confirmRequest
* Signer conversion from web3 -> parity.js completed
* explicit in no return
* green circle background
* remove generated background
* convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary)
* change dapps to load from localhost:8080/ui/*
* remove dangling web3 files
* update manager test for signer
* /api/ping -> /
* additional token images
* additional token images
* add missing styles.css for 8180 error pages
* cater for txhash returning null/empty object
* adjust output directories
* Release merge with origin with ours strategy
* additional token images
* cater for development server
* s/localhost/127.0.0.1/ (cater for origin)
* Fix address selection for contract deployment
* Adjust z-index for error overlay
* better text on unique background pattern
* fix signer rejections
* Don't allow gavcoin transfer with no balance
* fix txhash rendering in signer
* remove unnecessary ParityBackground
* script to update js-precompiled
* Redirect from :8080 to :8180
* Remove extra return
* Dapp logo images
2016-10-18 11:52:56 +02:00
|
|
|
balances
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
/**
|
|
|
|
* @param {Object} _balances - In the shape:
|
|
|
|
* {
|
|
|
|
* [ who ]: { [ tokenId ]: BigNumber } // The balances of `who`
|
|
|
|
* }
|
|
|
|
* @param {Boolean} skipNotifications [description]
|
|
|
|
*/
|
|
|
|
function setBalances (updates, skipNotifications = false) {
|
2016-11-25 16:46:35 +01:00
|
|
|
return (dispatch, getState) => {
|
2017-04-19 18:00:05 +02:00
|
|
|
const { tokens, balances } = getState();
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const prevBalances = balances;
|
|
|
|
const nextBalances = { ...prevBalances };
|
2017-01-23 13:39:52 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
Object.keys(updates)
|
|
|
|
.forEach((who) => {
|
|
|
|
const accountUpdates = updates[who];
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
Object.keys(accountUpdates)
|
|
|
|
.forEach((tokenId) => {
|
|
|
|
const token = tokens[tokenId];
|
|
|
|
const prevTokenValue = (prevBalances[who] || {})[tokenId];
|
|
|
|
const nextTokenValue = accountUpdates[tokenId];
|
2017-01-12 14:25:32 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
if (prevTokenValue && prevTokenValue.lt(nextTokenValue)) {
|
|
|
|
dispatch(notifyBalanceChange(who, prevTokenValue, nextTokenValue, token));
|
2016-11-25 16:46:35 +01:00
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
// Add the token if it's native ETH or if it has a value
|
|
|
|
if (token.native || nextTokenValue.gt(0)) {
|
|
|
|
nextBalances[who] = {
|
|
|
|
...(nextBalances[who] || {}),
|
|
|
|
[tokenId]: nextTokenValue
|
|
|
|
};
|
|
|
|
}
|
2016-11-25 16:46:35 +01:00
|
|
|
});
|
|
|
|
});
|
2017-04-19 18:00:05 +02:00
|
|
|
|
|
|
|
return dispatch(_setBalances(nextBalances));
|
2016-11-25 16:46:35 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
function notifyBalanceChange (who, fromValue, toValue, token) {
|
2016-11-25 16:46:35 +01:00
|
|
|
return (dispatch, getState) => {
|
2017-04-19 18:00:05 +02:00
|
|
|
const account = getState().personal.accounts[who];
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
if (account) {
|
|
|
|
const txValue = toValue.minus(fromValue);
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const redirectToAccount = () => {
|
|
|
|
const basePath = account.wallet
|
|
|
|
? 'wallet'
|
|
|
|
: 'accounts';
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const route = `/${basePath}/${account.address}`;
|
2016-12-07 12:47:44 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
dispatch(push(route));
|
|
|
|
};
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
notifyTransaction(account, token, txValue, redirectToAccount);
|
|
|
|
}
|
2016-11-25 16:46:35 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
// TODO: fetch txCount when needed
|
|
|
|
export function fetchBalances (_addresses, skipNotifications = false) {
|
|
|
|
return fetchTokensBalances(_addresses, [ ETH_TOKEN ], skipNotifications);
|
|
|
|
}
|
|
|
|
|
2017-01-12 14:25:32 +01:00
|
|
|
export function updateTokensFilter (_addresses, _tokens, options = {}) {
|
2016-11-25 16:46:35 +01:00
|
|
|
return (dispatch, getState) => {
|
2017-04-19 18:00:05 +02:00
|
|
|
const { api, personal, tokens } = getState();
|
2016-12-10 23:55:36 +01:00
|
|
|
const { visibleAccounts, accounts } = personal;
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2016-12-10 23:55:36 +01:00
|
|
|
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
|
|
|
const addresses = uniq(_addresses || addressesToFetch || []).sort();
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const tokensToUpdate = _tokens || Object.values(tokens);
|
|
|
|
const tokenAddresses = tokensToUpdate
|
|
|
|
.map((t) => t.address)
|
|
|
|
.filter((address) => address)
|
|
|
|
.sort();
|
2016-11-25 16:46:35 +01:00
|
|
|
|
|
|
|
if (tokensFilter.filterFromId || tokensFilter.filterToId) {
|
2017-01-12 14:25:32 +01:00
|
|
|
// Has the tokens addresses changed (eg. a network change)
|
2016-11-25 16:46:35 +01:00
|
|
|
const sameTokens = isEqual(tokenAddresses, tokensFilter.tokenAddresses);
|
|
|
|
|
2017-01-12 14:25:32 +01:00
|
|
|
// Addresses that are not in the current filter (omit those
|
|
|
|
// that the filter includes)
|
|
|
|
const newAddresses = addresses.filter((address) => !tokensFilter.addresses.includes(address));
|
|
|
|
|
|
|
|
// If no new addresses and the same tokens, don't change the filter
|
|
|
|
if (sameTokens && newAddresses.length === 0) {
|
|
|
|
log.debug('no need to update token filter', addresses, tokenAddresses, tokensFilter);
|
2016-11-25 16:46:35 +01:00
|
|
|
return queryTokensFilter(tokensFilter)(dispatch, getState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-12 14:25:32 +01:00
|
|
|
log.debug('updating the token filter', addresses, tokenAddresses);
|
|
|
|
const promises = [];
|
2016-11-25 16:46:35 +01:00
|
|
|
|
|
|
|
if (tokensFilter.filterFromId) {
|
2017-01-12 14:25:32 +01:00
|
|
|
promises.push(api.eth.uninstallFilter(tokensFilter.filterFromId));
|
2016-11-25 16:46:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tokensFilter.filterToId) {
|
2017-01-12 14:25:32 +01:00
|
|
|
promises.push(api.eth.uninstallFilter(tokensFilter.filterToId));
|
2016-11-25 16:46:35 +01:00
|
|
|
}
|
|
|
|
|
2017-07-25 08:39:41 +02:00
|
|
|
Promise
|
|
|
|
.all([
|
|
|
|
api.eth.blockNumber()
|
|
|
|
].concat(promises))
|
|
|
|
.then(([ block ]) => {
|
|
|
|
const topicsFrom = [ TRANSFER_SIGNATURE, addresses, null ];
|
|
|
|
const topicsTo = [ TRANSFER_SIGNATURE, null, addresses ];
|
|
|
|
|
|
|
|
const filterOptions = {
|
|
|
|
fromBlock: block,
|
|
|
|
toBlock: 'pending',
|
|
|
|
address: tokenAddresses
|
|
|
|
};
|
|
|
|
|
|
|
|
const optionsFrom = {
|
|
|
|
...filterOptions,
|
|
|
|
topics: topicsFrom
|
|
|
|
};
|
|
|
|
|
|
|
|
const optionsTo = {
|
|
|
|
...filterOptions,
|
|
|
|
topics: topicsTo
|
|
|
|
};
|
|
|
|
|
|
|
|
const newFilters = Promise.all([
|
|
|
|
api.eth.newFilter(optionsFrom),
|
|
|
|
api.eth.newFilter(optionsTo)
|
|
|
|
]);
|
|
|
|
|
|
|
|
return newFilters;
|
|
|
|
})
|
2016-11-25 16:46:35 +01:00
|
|
|
.then(([ filterFromId, filterToId ]) => {
|
|
|
|
const nextTokensFilter = {
|
|
|
|
filterFromId, filterToId,
|
|
|
|
addresses, tokenAddresses
|
|
|
|
};
|
|
|
|
|
2017-01-12 14:25:32 +01:00
|
|
|
const { skipNotifications } = options;
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
tokensFilter = nextTokensFilter;
|
|
|
|
fetchTokensBalances(addresses, tokensToUpdate, skipNotifications)(dispatch, getState);
|
2016-11-25 16:46:35 +01:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.warn('balances::updateTokensFilter', error);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
export function queryTokensFilter () {
|
2016-11-25 16:46:35 +01:00
|
|
|
return (dispatch, getState) => {
|
2017-04-19 18:00:05 +02:00
|
|
|
const { api, personal, tokens } = getState();
|
2016-12-10 23:55:36 +01:00
|
|
|
const { visibleAccounts, accounts } = personal;
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const allAddresses = visibleAccounts.concat(Object.keys(accounts));
|
|
|
|
const addressesToFetch = uniq(allAddresses);
|
|
|
|
const lcAddresses = addressesToFetch.map((a) => a.toLowerCase());
|
2016-11-25 16:46:35 +01:00
|
|
|
|
|
|
|
Promise
|
|
|
|
.all([
|
|
|
|
api.eth.getFilterChanges(tokensFilter.filterFromId),
|
|
|
|
api.eth.getFilterChanges(tokensFilter.filterToId)
|
|
|
|
])
|
|
|
|
.then(([ logsFrom, logsTo ]) => {
|
|
|
|
const addresses = [];
|
|
|
|
const tokenAddresses = [];
|
2017-04-19 18:00:05 +02:00
|
|
|
const logs = logsFrom.concat(logsTo);
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
if (logs.length > 0) {
|
|
|
|
log.debug('got tokens filter logs', logs);
|
|
|
|
}
|
|
|
|
|
|
|
|
logs
|
2016-11-25 16:46:35 +01:00
|
|
|
.forEach((log) => {
|
|
|
|
const tokenAddress = log.address;
|
2016-12-10 23:55:36 +01:00
|
|
|
|
2016-11-25 16:46:35 +01:00
|
|
|
const fromAddress = '0x' + log.topics[1].slice(-40);
|
|
|
|
const toAddress = '0x' + log.topics[2].slice(-40);
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const fromAddressIndex = lcAddresses.indexOf(fromAddress);
|
|
|
|
const toAddressIndex = lcAddresses.indexOf(toAddress);
|
|
|
|
|
|
|
|
if (fromAddressIndex > -1) {
|
|
|
|
addresses.push(addressesToFetch[fromAddressIndex]);
|
2016-11-25 16:46:35 +01:00
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
if (toAddressIndex > -1) {
|
|
|
|
addresses.push(addressesToFetch[toAddressIndex]);
|
2016-11-25 16:46:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
tokenAddresses.push(tokenAddress);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (addresses.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const tokensToUpdate = Object.values(tokens)
|
2016-12-02 15:21:01 +01:00
|
|
|
.filter((t) => tokenAddresses.includes(t.address));
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
fetchTokensBalances(uniq(addresses), tokensToUpdate)(dispatch, getState);
|
2016-11-25 16:46:35 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-12 14:25:32 +01:00
|
|
|
export function fetchTokensBalances (_addresses = null, _tokens = null, skipNotifications = false) {
|
2016-11-25 16:46:35 +01:00
|
|
|
return (dispatch, getState) => {
|
2017-04-19 18:00:05 +02:00
|
|
|
const { api, personal, tokens } = getState();
|
2016-12-10 23:55:36 +01:00
|
|
|
const { visibleAccounts, accounts } = personal;
|
2017-04-19 18:00:05 +02:00
|
|
|
const allTokens = Object.values(tokens);
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2016-12-10 23:55:36 +01:00
|
|
|
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
|
|
|
const addresses = _addresses || addressesToFetch;
|
2017-04-19 18:00:05 +02:00
|
|
|
const tokensToUpdate = _tokens || allTokens;
|
2016-11-25 16:46:35 +01:00
|
|
|
|
|
|
|
if (addresses.length === 0) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
const updates = addresses.reduce((updates, who) => {
|
|
|
|
updates[who] = tokensToUpdate.map((token) => token.id);
|
|
|
|
return updates;
|
|
|
|
}, {});
|
2016-11-25 16:46:35 +01:00
|
|
|
|
2017-04-19 18:00:05 +02:00
|
|
|
return fetchAccountsBalances(api, allTokens, updates)
|
|
|
|
.then((balances) => {
|
2017-01-12 14:25:32 +01:00
|
|
|
dispatch(setBalances(balances, skipNotifications));
|
2016-11-25 16:46:35 +01:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.warn('balances::fetchTokensBalances', error);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|