Make Wallet first-class citizens (#3990)

* Fixed hint in Address Select + Wallet as first-class-citizen

* Separate Owned and not Owned Wallets

* Fix balance not updating

* Fix MethodDecoding for Contract Deployment

* Fix TypedInput params

* Fix Token Transfer for Wallet

* Small change to contracts

* Fix wallets shown twice

* Fix separation of accounts and wallets in Accounts

* Fix linting

* Execute contract methods from Wallet ✓

* Fixing linting

* Wallet as first-class citizen: Part 1 (Manual) #3784

* Lower level wallet transaction convertion

* Fix linting

* Proper autoFocus on right Signer input

* PR Grumble: don't show Wallets in dApps Permissions

* Add postTransaction and gasEstimate wrapper methods

* Extract Wallet postTx and gasEstimate to utils + PATCH api

* Remove invalid test

It's totally valid for input's length not to be a multiple of 32 bytes. EG. for Wallet Contracts

* Merge master

* Fix linting

* Fix merge issue

* Rename Portal

* Rename Protal => Portal (typo)
This commit is contained in:
Nicolas Gotchac
2016-12-30 12:28:12 +01:00
committed by Gav Wood
parent 88c0329a31
commit fd41a10319
46 changed files with 570 additions and 230 deletions

View File

@@ -175,7 +175,7 @@ export function fetchBalances (_addresses) {
const { api, personal } = getState();
const { visibleAccounts, accounts } = personal;
const addresses = uniq(_addresses || visibleAccounts || []);
const addresses = uniq((_addresses || visibleAccounts || []).concat(Object.keys(accounts)));
if (addresses.length === 0) {
return Promise.resolve();
@@ -183,7 +183,7 @@ export function fetchBalances (_addresses) {
const fullFetch = addresses.length === 1;
const addressesToFetch = uniq(addresses.concat(Object.keys(accounts)));
const addressesToFetch = uniq(addresses);
return Promise
.all(addressesToFetch.map((addr) => fetchAccount(addr, api, fullFetch)))

View File

@@ -14,14 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { isEqual } from 'lodash';
import { isEqual, intersection } from 'lodash';
import { fetchBalances } from './balancesActions';
import { attachWallets } from './walletActions';
import Contract from '~/api/contract';
import MethodDecodingStore from '~/ui/MethodDecoding/methodDecodingStore';
import WalletsUtils from '~/util/wallets';
import { wallet as WalletAbi } from '~/contracts/abi';
export function personalAccountsInfo (accountsInfo) {
const addresses = [];
const accounts = {};
const contacts = {};
const contracts = {};
@@ -32,6 +36,7 @@ export function personalAccountsInfo (accountsInfo) {
.filter((account) => account.uuid || !account.meta.deleted)
.forEach((account) => {
if (account.uuid) {
addresses.push(account.address);
accounts[account.address] = account;
} else if (account.meta.wallet) {
account.wallet = true;
@@ -46,14 +51,52 @@ export function personalAccountsInfo (accountsInfo) {
// Load user contracts for Method Decoding
MethodDecodingStore.loadContracts(contracts);
return (dispatch) => {
const data = {
accountsInfo,
accounts, contacts, contracts, wallets
};
return (dispatch, getState) => {
const { api } = getState();
dispatch(_personalAccountsInfo(data));
dispatch(attachWallets(wallets));
const _fetchOwners = Object
.values(wallets)
.map((wallet) => {
const walletContract = new Contract(api, WalletAbi);
return WalletsUtils.fetchOwners(walletContract.at(wallet.address));
});
Promise
.all(_fetchOwners)
.then((walletsOwners) => {
return Object
.values(wallets)
.map((wallet, index) => {
wallet.owners = walletsOwners[index].map((owner) => ({
address: owner,
name: accountsInfo[owner] && accountsInfo[owner].name || owner
}));
return wallet;
});
})
.then((_wallets) => {
_wallets.forEach((wallet) => {
const owners = wallet.owners.map((o) => o.address);
// Owners ∩ Addresses not null : Wallet is owned
// by one of the accounts
if (intersection(owners, addresses).length > 0) {
accounts[wallet.address] = wallet;
} else {
contacts[wallet.address] = wallet;
}
});
const data = {
accountsInfo,
accounts, contacts, contracts
};
dispatch(_personalAccountsInfo(data));
dispatch(attachWallets(wallets));
dispatch(fetchBalances());
});
};
}

View File

@@ -25,14 +25,13 @@ const initialState = {
hasContacts: false,
contracts: {},
hasContracts: false,
wallet: {},
hasWallets: false,
visibleAccounts: []
};
export default handleActions({
personalAccountsInfo (state, action) {
const { accountsInfo, accounts, contacts, contracts, wallets } = action;
const accountsInfo = action.accountsInfo || state.accountsInfo;
const { accounts, contacts, contracts } = action;
return Object.assign({}, state, {
accountsInfo,
@@ -41,9 +40,7 @@ export default handleActions({
contacts,
hasContacts: Object.keys(contacts).length !== 0,
contracts,
hasContracts: Object.keys(contracts).length !== 0,
wallets,
hasWallets: Object.keys(wallets).length !== 0
hasContracts: Object.keys(contracts).length !== 0
});
},

View File

@@ -90,7 +90,7 @@ export default handleActions({
signerSuccessRejectRequest (state, action) {
const { id } = action.payload;
const rejected = Object.assign(
state.pending.find(p => p.id === id),
state.pending.find(p => p.id === id) || { id },
{ status: 'rejected' }
);
return {