Skip to content

Commit

Permalink
fix: update app state on accountsChanged event (starknet-io#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-ziv authored May 3, 2022
1 parent b699a03 commit 3161cc9
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 35 deletions.
10 changes: 0 additions & 10 deletions src/__tests__/utils/storage.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,4 @@ describe('StorageManager', () => {
expect(getItem('testNumber')).toEqual(testNumber);
expect(getItem('testString')).toEqual(testString);
});

it('should backward compatible for saved arrays', () => {
const jsonArray = JSON.stringify(testArray);
localStorage.setItem('test', jsonArray);
expect(localStorage.getItem('test')).toEqual(jsonArray);
expect(getItem('test')).toEqual(testArray);
expect(localStorage.getItem('test')).toEqual(
'eyIwIjoiV3c9PSIsIjEiOiJldz09IiwiMiI6IklnPT0iLCIzIjoiWVE9PSIsIjQiOiJJZz09IiwiNSI6Ik9nPT0iLCI2IjoiTVE9PSIsIjciOiJmUT09IiwiOCI6IlhRPT0ifQ=='
);
});
});
18 changes: 16 additions & 2 deletions src/components/Features/ToastProvider/ToastProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import utils from '../../../utils';
import {CompleteTransferToL1Toast, ToastBody, TransferToast} from '../../UI';
import styles from './ToastProvider.module.scss';

const toastsMap = {};
const toastsDismissed = {};
let toastsMap = {};
let toastsDismissed = {};

export const ToastProvider = () => {
const {alphaDisclaimerMsg} = useToastsTranslation();
Expand All @@ -46,6 +46,10 @@ export const ToastProvider = () => {
});
}, [transfers]);

useEffect(() => {
return () => clearToasts();
}, []);

const handleToast = (transfer, prevTransfer) => {
const {status, type} = transfer;
const isChanged = prevTransfer && status !== prevTransfer.status;
Expand Down Expand Up @@ -155,6 +159,16 @@ export const ToastProvider = () => {
showAccountMenu({transferId: transfer.id});
};

const clearToasts = () => {
Object.values(toastsMap).forEach(toasts => {
Object.keys(toasts).forEach(id => {
toast.dismiss(id);
});
});
toastsMap = {};
toastsDismissed = {};
};

return (
<Toaster
containerClassName={styles.toastProvider}
Expand Down
21 changes: 16 additions & 5 deletions src/providers/EventManagerProvider/EventManagerProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {EventManagerContext} from './event-manager-context';

const listeners = {};
const filters = {};
let emitters = [];

export const EventManagerProvider = ({children}) => {
const logger = useLogger(EventManagerProvider.displayName);
Expand All @@ -23,6 +24,7 @@ export const EventManagerProvider = ({children}) => {
useEffect(() => {
setEventFilters();
addDepositWithdrawalListeners();
return () => cleanEmittersAndRemoveListeners();
}, []);

const addListener = (eventName, callback) => {
Expand Down Expand Up @@ -101,14 +103,23 @@ export const EventManagerProvider = ({children}) => {
};

const addContractEventListener = (contract, eventName, filter, handler) => {
contract.events[eventName](
{
filter
},
handler
emitters.push(
contract.events[eventName](
{
filter
},
handler
)
);
};

const cleanEmittersAndRemoveListeners = () => {
logger.log('Remove all listeners.');
emitters.forEach(emitter => emitter.removeAllListeners());
logger.log('Clean emitters.');
emitters = [];
};

const value = {
addListener,
getPastEvents,
Expand Down
43 changes: 31 additions & 12 deletions src/providers/TransfersLogProvider/TransfersLogProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import utils from '../../utils';
import {useBlockHash} from '../BlockHashProvider';
import {useDepositMessageToL2Event} from '../EventManagerProvider';
import {useTokens} from '../TokensProvider';
import {useL2Wallet} from '../WalletsProvider';
import {useAccountHash, useL2Wallet} from '../WalletsProvider';
import {TransfersLogContext} from './transfers-log-context';
import {actions, initialState, reducer} from './transfers-log-reducer';

Expand All @@ -21,12 +21,11 @@ export const TransfersLogProvider = ({children}) => {
const {updateTokenBalance} = useTokens();
const {chainId: l2ChainId} = useL2Wallet();
const getDepositMessageToL2Event = useDepositMessageToL2Event();
const accountHash = useAccountHash();

useEffect(() => {
const storedTransfers = getTransfersFromStorage();
if (Array.isArray(storedTransfers)) {
setTransfers(storedTransfers);
}
setTransfers(storedTransfers);
}, []);

useDeepCompareEffect(() => {
Expand Down Expand Up @@ -97,6 +96,34 @@ export const TransfersLogProvider = ({children}) => {
return transfer;
};

const getTransfersFromStorage = () => {
let storedTransfers = utils.storage.getItem(localStorageTransfersLogKey);
// for backward compatibility
storedTransfers = maybeTransformTransfersArrayToObject(storedTransfers) || {};
return storedTransfers[accountHash] || [];
};

const saveTransfersToStorage = transfers => {
const storedTransfers = utils.storage.getItem(localStorageTransfersLogKey) || {};
const updatedTransfers = Object.assign(storedTransfers, {[accountHash]: transfers});
utils.storage.setItem(localStorageTransfersLogKey, updatedTransfers);
};

const maybeTransformTransfersArrayToObject = storedTransfers => {
if (Array.isArray(storedTransfers)) {
const transfersObject = {};
storedTransfers.forEach(storedTransfer => {
const {sender, recipient} = storedTransfer;
const accountHash = utils.wallet.calcAccountHash(sender, recipient);
transfersObject[accountHash] = transfersObject[accountHash] || [];
transfersObject[accountHash].push(storedTransfer);
});
utils.storage.setItem(localStorageTransfersLogKey, transfersObject);
return transfersObject;
}
return storedTransfers;
};

const updateTransfer = transfer => {
dispatch({
type: actions.UPDATE_TRANSFER,
Expand All @@ -118,14 +145,6 @@ export const TransfersLogProvider = ({children}) => {
});
};

const getTransfersFromStorage = () => {
return utils.storage.getItem(localStorageTransfersLogKey);
};

const saveTransfersToStorage = transfers => {
utils.storage.setItem(localStorageTransfersLogKey, transfers);
};

const context = {
transfers,
addTransfer,
Expand Down
11 changes: 10 additions & 1 deletion src/providers/WalletsProvider/WalletsProvider.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import PropTypes from 'prop-types';
import React, {useEffect, useReducer} from 'react';
import React, {useEffect, useReducer, useState} from 'react';
import {useWallet} from 'use-wallet';

import {WalletStatus} from '../../enums';
import utils from '../../utils';
import {useIsL1, useIsL2} from '../TransferProvider';
import {WalletsContext} from './wallets-context';
import {useStarknetWallet} from './wallets-hooks';
Expand All @@ -22,6 +23,7 @@ export const WalletsProvider = ({children}) => {
} = useStarknetWallet();
const [isL1, swapToL1] = useIsL1();
const [isL2, swapToL2] = useIsL2();
const [accountHash, setAccountHash] = useState('');

useEffect(() => {
(isL2 || state.l2Wallet.config) && maybeUpdateL2Wallet();
Expand All @@ -31,6 +33,12 @@ export const WalletsProvider = ({children}) => {
(isL1 || state.l1Wallet.config) && maybeUpdateL1Wallet();
}, [status, error, account, chainId, networkName]);

useEffect(() => {
if (account && l2Account) {
setAccountHash(utils.wallet.calcAccountHash(account, l2Account));
}
}, [account, l2Account]);

const connectWallet = async walletConfig => {
return isL1 ? connectL1Wallet(walletConfig) : connectL2Wallet(walletConfig);
};
Expand Down Expand Up @@ -122,6 +130,7 @@ export const WalletsProvider = ({children}) => {

const context = {
...state,
accountHash,
connectWallet,
connectL1Wallet,
connectL2Wallet,
Expand Down
1 change: 1 addition & 0 deletions src/providers/WalletsProvider/wallets-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {initialState} from './wallets-reducer';

export const WalletsContext = createContext({
...initialState,
accountHash: '',
connectL1Wallet: () => {},
connectL2Wallet: () => {},
connectWallet: () => {},
Expand Down
6 changes: 6 additions & 0 deletions src/providers/WalletsProvider/wallets-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export const useWallets = () => {
};
};

export const useAccountHash = () => {
const {accountHash} = useContext(WalletsContext);
return accountHash;
};

export const useL1Wallet = () => {
const wallets = useContext(WalletsContext);

Expand Down Expand Up @@ -92,6 +97,7 @@ export const useStarknetWallet = () => {

const addAccountChangedListener = () => {
getStarknet().on('accountsChanged', () => {
setStatus(WalletStatus.DISCONNECTED);
updateAccount();
});
};
Expand Down
5 changes: 0 additions & 5 deletions src/utils/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ Storage.prototype.setObjectHash = function (key, myObject) {
Storage.prototype.getObjectHash = function (key) {
let myObject = this.getItem(key);
if (!myObject) return null;
// For backward compatibility
if (myObject.startsWith('[') && myObject.endsWith(']')) {
this.setObjectHash(key, myObject);
myObject = this.getItem(key);
}
return (
b64d(myObject) &&
JSON.parse(b64d(myObject), function (key) {
Expand Down
10 changes: 10 additions & 0 deletions src/utils/wallet.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import {starknet} from '../libs';
import {parseToFelt} from './parser';

export const formatBalance = balance => {
return typeof balance === 'number' ? String(fromExponential(balance)) : 'N/A';
};
Expand All @@ -14,6 +17,13 @@ export const shortenAddress = account => {
: '';
};

export const calcAccountHash = (account1, account2) => {
return starknet.hash.computeHashOnElements([
parseToFelt(account1).toString(),
parseToFelt(account2).toString()
]);
};

const fromExponential = x => {
if (Math.abs(x) < 1.0) {
const e = parseInt(x.toString().split('e-')[1]);
Expand Down

0 comments on commit 3161cc9

Please sign in to comment.