Skip to content

Commit

Permalink
refactor: tokens addresses (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-ziv authored May 10, 2022
1 parent 87fb2cb commit c75a88a
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 79 deletions.
4 changes: 2 additions & 2 deletions src/components/Containers/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import styles from './Header.module.scss';
export const Header = () => {
const {DISCORD_LINK_URL} = useConstants();
const [trackDiscordClick] = useTracking(TrackEvent.DISCORD_TAB_CLICK);
const {supportedChainId} = useEnvs();
const {supportedL1ChainId} = useEnvs();
const {tabDiscordTxt, tabFaqTxt, tabTermsTxt, chainTxt} = useHeaderTranslation();
const navigate = useNavigate();
const {pathname} = useLocation();
Expand Down Expand Up @@ -70,7 +70,7 @@ export const Header = () => {
<div className={toClasses(styles.logo, 'row')} onClick={onLogoClick}>
<StarkGateLogo />
</div>
{supportedChainId === ChainType.L1.GOERLI && (
{supportedL1ChainId === ChainType.L1.GOERLI && (
<div className={toClasses(styles.chain, 'row')}>{chainTxt}</div>
)}
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/config/envs.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {ChainType} from '../enums';
import {evaluate} from '../utils';

export const env = process.env.NODE_ENV;
export const appUrl = process.env.REACT_APP_URL;
export const autoConnect = process.env.REACT_APP_AUTO_CONNECT === 'true';
export const pollBlockNumberInterval = Number(process.env.REACT_APP_POLL_BLOCK_NUMBER_INTERVAL);
export const supportedTokens = process.env.REACT_APP_SUPPORTED_TOKENS.split(',');
export const supportedChainId = Number(process.env.REACT_APP_SUPPORTED_CHAIN_ID);
export const supportedL1ChainId = Number(process.env.REACT_APP_SUPPORTED_CHAIN_ID);
export const supportedL2ChainId =
supportedL1ChainId === ChainType.L1.GOERLI ? ChainType.L2.GOERLI : ChainType.L2.MAIN;
export const starknetContractAddress = process.env.REACT_APP_STARKNET_CONTRACT_ADDRESS;
export const etherscanUrl = process.env.REACT_APP_ETHERSCAN_URL;
export const etherscanTxUrl = tx => evaluate(`${etherscanUrl}/tx/{{tx}}`, {tx});
Expand Down
54 changes: 18 additions & 36 deletions src/hooks/useContract.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,20 @@ import {L2_BRIDGE_ABI, L2_ERC20_ABI} from '../abis/l2';
import {NetworkType} from '../enums';
import {useL1Token} from '../providers/TokensProvider';
import {useTransfer} from '../providers/TransferProvider';
import {useL1Wallet, useL2Wallet} from '../providers/WalletsProvider';
import {createL1Contract, createL2Contract} from '../utils';
import {useEnvs} from './useEnvs';

const cache = {};

export const useContract = (ABI, chainId, getContractHandler) => {
export const useContract = (abi, getContractHandler) => {
return useCallback(
addresses => {
try {
let address;
if (typeof addresses === 'string') {
address = addresses;
} else if (typeof addresses === 'object') {
address = addresses[chainId];
} else {
return null;
}
if (!cache[address]) {
cache[address] = getContractHandler(address, ABI);
}
return cache[address];
} catch (ex) {
return null;
address => {
if (!cache[address]) {
cache[address] = getContractHandler(address, abi);
}
return cache[address];
},
[ABI, getContractHandler]
[abi, getContractHandler]
);
};

Expand All @@ -41,8 +28,8 @@ export const useTokenContract = () => {
const {isL1} = useTransfer();

return useCallback(
tokenAddresses => {
return isL1 ? getL1TokenContract(tokenAddresses) : getL2TokenContract(tokenAddresses);
tokenAddress => {
return isL1 ? getL1TokenContract(tokenAddress) : getL2TokenContract(tokenAddress);
},
[isL1, getL2TokenContract, getL1TokenContract]
);
Expand All @@ -64,46 +51,41 @@ export const useTokenBridgeContract = () => {
};

export const useL2TokenContract = () => {
const {chainId} = useL2Wallet();
const getContract = useContract(L2_ERC20_ABI, chainId, createL2Contract);
const getContract = useContract(L2_ERC20_ABI, createL2Contract);

return useCallback(tokenAddresses => getContract(tokenAddresses), [getContract]);
return useCallback(tokenAddress => getContract(tokenAddress), [getContract]);
};

export const useL1TokenContract = () => {
const {chainId} = useL1Wallet();
const getContract = useContract(L1_ERC20_ABI, chainId, createL1Contract);
const getContract = useContract(L1_ERC20_ABI, createL1Contract);

return useCallback(tokenAddresses => getContract(tokenAddresses), [getContract]);
return useCallback(tokenAddress => getContract(tokenAddress), [getContract]);
};

export const useStarknetContract = () => {
const {starknetContractAddress} = useEnvs();
const {chainId} = useL1Wallet();
const getContract = useContract(L1_MESSAGING_ABI, chainId, createL1Contract);
const getContract = useContract(L1_MESSAGING_ABI, createL1Contract);

return useMemo(() => getContract(starknetContractAddress), [getContract]);
};

export const useL2TokenBridgeContract = () => {
const {chainId} = useL2Wallet();
const getContract = useContract(L2_BRIDGE_ABI, chainId, createL2Contract);
const getContract = useContract(L2_BRIDGE_ABI, createL2Contract);

return useCallback(bridgeAddress => getContract(bridgeAddress), [getContract]);
};

export const useL1TokenBridgeContract = () => {
const {chainId} = useL1Wallet();
const getTokenBridgeContract = useContract(L1_ERC20_BRIDGE_ABI, chainId, createL1Contract);
const getEthBridgeContract = useContract(L1_ETH_BRIDGE_ABI, chainId, createL1Contract);
const getTokenBridgeContract = useContract(L1_ERC20_BRIDGE_ABI, createL1Contract);
const getEthBridgeContract = useContract(L1_ETH_BRIDGE_ABI, createL1Contract);
const ethToken = useL1Token()(NetworkType.L1.symbol);

return useCallback(
bridgeAddress => {
return bridgeAddress[chainId] === ethToken.bridgeAddress[chainId]
return bridgeAddress === ethToken.bridgeAddress
? getEthBridgeContract(bridgeAddress)
: getTokenBridgeContract(bridgeAddress);
},
[getTokenBridgeContract, getEthBridgeContract, chainId, ethToken]
[getTokenBridgeContract, getEthBridgeContract, ethToken]
);
};
16 changes: 7 additions & 9 deletions src/hooks/useTransferToL2.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {useTransferProgress} from './useTransferProgress';
export const useTransferToL2 = () => {
const logger = useLogger('useTransferToL2');
const [trackInitiated, trackSuccess, trackError, trackReject] = useTransferToL2Tracking();
const {account: l1Account, chainId: l1ChainId, config: l1Config} = useL1Wallet();
const {account: l2Account, chainId: l2ChainId} = useL2Wallet();
const {account: l1Account, config: l1Config} = useL1Wallet();
const {account: l2Account} = useL2Wallet();
const {handleProgress, handleData, handleError} = useTransfer(TransferToL2Steps);
const selectedToken = useSelectedToken();
const getTokenContract = useTokenContract();
Expand All @@ -36,21 +36,20 @@ export const useTransferToL2 = () => {
const tokenContract = getTokenContract(tokenAddress);
const bridgeContract = getTokenBridgeContract(bridgeAddress);
const isEthToken = isEth(symbol);
const tokenBridgeAddress = bridgeAddress[l1ChainId];
const l2TokenAddress = getL2Token(symbol)?.tokenAddress[l2ChainId];
const l2TokenAddress = getL2Token(symbol)?.tokenAddress;

const readAllowance = () => {
return allowance({
owner: l1Account,
spender: tokenBridgeAddress,
spender: bridgeAddress,
contract: tokenContract,
decimals
});
};

const sendApproval = async () => {
return approve({
spender: tokenBridgeAddress,
spender: bridgeAddress,
value: starknet.constants.MASK_250,
contract: tokenContract,
options: {from: l1Account}
Expand Down Expand Up @@ -111,9 +110,9 @@ export const useTransferToL2 = () => {

const isMaxBalanceExceeded = async () => {
const tokenBridgeBalance = await (isEthToken
? ethBalanceOf(tokenBridgeAddress)
? ethBalanceOf(bridgeAddress)
: balanceOf({
account: tokenBridgeAddress,
account: bridgeAddress,
decimals,
contract: tokenContract
}));
Expand Down Expand Up @@ -161,7 +160,6 @@ export const useTransferToL2 = () => {
selectedToken,
addListener,
removeListener,
l1ChainId,
l1Account,
l2Account,
l1Config,
Expand Down
8 changes: 4 additions & 4 deletions src/providers/EventManagerProvider/EventManagerProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ let emitters = [];
export const EventManagerProvider = ({children}) => {
const logger = useLogger(EventManagerProvider.displayName);
const getTokenBridgeContract = useL1TokenBridgeContract();
const {account: l1Account, chainId: l1ChainId} = useL1Wallet();
const {account: l2Account, chainId: l2ChainId} = useL2Wallet();
const {account: l1Account} = useL1Wallet();
const {account: l2Account} = useL2Wallet();
const l1Tokens = useL1Tokens();
const l2Tokens = useL2Tokens();

Expand Down Expand Up @@ -84,8 +84,8 @@ export const EventManagerProvider = ({children}) => {

const setEventFilters = () => {
// LogMessageToL2 filter
const l1BridgesAddresses = l1Tokens.map(token => token.bridgeAddress[l1ChainId]);
const l2BridgesAddress = l2Tokens.map(token => token.bridgeAddress[l2ChainId]);
const l1BridgesAddresses = l1Tokens.map(token => token.bridgeAddress);
const l2BridgesAddress = l2Tokens.map(token => token.bridgeAddress);
filters[EventName.L1.LOG_MESSAGE_TO_L2] = {
from_address: l1BridgesAddresses,
to_address: l2BridgesAddress,
Expand Down
25 changes: 14 additions & 11 deletions src/providers/TokensProvider/TokensProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@ export const TokensProvider = ({children}) => {
const getL2TokenBalance = useL2TokenBalance(l2Account);

useEffect(() => {
updateTokenBalance();
fetchBalances(tokens);
}, []);

const updateTokenBalance = symbol => {
logger.log(symbol ? `Update ${symbol} token balance` : 'Update all tokens balances');
const tokensToUpdate = tokens
.map((t, index) => ({...t, index}))
.filter(t => !symbol || t.symbol === symbol);
logger.log('Tokens to update:', {tokensToUpdate});
const filteredTokens = tokens.filter(t => !symbol || t.symbol === symbol);
fetchBalances(filteredTokens);
};

tokensToUpdate.forEach(token => {
if (!token.isLoading) {
updateToken(token.index, {isLoading: true});
fetchBalance(token.isL1 ? getL1TokenBalance : getL2TokenBalance, token);
}
});
const fetchBalances = tokens => {
logger.log('Tokens to update', tokens);
tokens
.map((t, index) => ({...t, index}))
.forEach(token => {
if (!token.isLoading) {
updateToken(token.index, {isLoading: true});
return fetchBalance(token.isL1 ? getL1TokenBalance : getL2TokenBalance, token);
}
});
};

const fetchBalance = async (fn, token, retry = 1) => {
Expand Down
16 changes: 13 additions & 3 deletions src/providers/TokensProvider/tokens-reducer.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import {supportedTokens} from '../../config/envs';
import {supportedL1ChainId, supportedL2ChainId, supportedTokens} from '../../config/envs';
import Tokens from '../../config/tokens';

export const actions = {
UPDATE_TOKEN: 'Tokens/UPDATE_TOKEN'
};

export const initialState = [
...Tokens.L1.filter(t => supportedTokens.includes(t.symbol)).map(t => ({...t, isL1: true})),
...Tokens.L2.filter(t => supportedTokens.includes(t.symbol)).map(t => ({...t, isL2: true}))
...Tokens.L1.filter(t => supportedTokens.includes(t.symbol)).map(t => ({
...t,
isL1: true,
bridgeAddress: t.bridgeAddress?.[supportedL1ChainId],
tokenAddress: t.tokenAddress?.[supportedL1ChainId]
})),
...Tokens.L2.filter(t => supportedTokens.includes(t.symbol)).map(t => ({
...t,
isL2: true,
bridgeAddress: t.bridgeAddress?.[supportedL2ChainId],
tokenAddress: t.tokenAddress?.[supportedL2ChainId]
}))
];

export const reducer = (state, action) => {
Expand Down
4 changes: 2 additions & 2 deletions src/providers/WalletProvider/WalletProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {UseWalletProvider as UseWalletProviderWrapper} from 'use-wallet';
import {useEnvs} from '../../hooks';

export const WalletProvider = ({children}) => {
const {pollBalanceInterval, pollBlockNumberInterval, supportedChainId} = useEnvs();
const {pollBalanceInterval, pollBlockNumberInterval, supportedL1ChainId} = useEnvs();
return (
<UseWalletProviderWrapper
autoConnect={false}
connectors={{
injected: {
chainId: [supportedChainId]
chainId: [supportedL1ChainId]
}
}}
pollBalanceInterval={pollBalanceInterval}
Expand Down
11 changes: 2 additions & 9 deletions src/providers/WalletsProvider/wallets-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const useL2Wallet = () => {
};

export const useStarknetWallet = () => {
const {autoConnect, supportedChainId} = useEnvs();
const {autoConnect, supportedL2ChainId} = useEnvs();
const [error, setError] = useState(null);
const [account, setAccount] = useState('');
const [chainId, setChainId] = useState('');
Expand Down Expand Up @@ -121,15 +121,8 @@ export const useStarknetWallet = () => {
}
};

const isChainValid = chainId => {
return (
(chainId === ChainType.L2.MAIN && supportedChainId === ChainType.L1.MAIN) ||
(chainId === ChainType.L2.GOERLI && supportedChainId === ChainType.L1.GOERLI)
);
};

const handleChain = chainId => {
if (isChainValid(chainId)) {
if (chainId === supportedL2ChainId) {
setStatus(WalletStatus.CONNECTED);
setError(null);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/Login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const Login = () => {
} = useLoginTranslation();
const [trackLoginScreen, trackDownloadClick, trackWalletClick, trackLoginError] =
useLoginTracking();
const {autoConnect, supportedChainId} = useEnvs();
const {autoConnect, supportedL1ChainId} = useEnvs();
const [selectedWalletName, setSelectedWalletName] = useState('');
const [error, setError] = useState(null);
const [, swapToL1] = useIsL1();
Expand Down Expand Up @@ -125,7 +125,7 @@ export const Login = () => {
setError({
type: LoginErrorType.UNSUPPORTED_CHAIN_ID,
message: evaluate(unsupportedChainIdTxt, {
chainName: ChainInfo.L1[supportedChainId].NAME
chainName: ChainInfo.L1[supportedL1ChainId].NAME
})
});
}
Expand Down

0 comments on commit c75a88a

Please sign in to comment.