utils#receiveAmount TypeScript Examples
The following examples show how to use
utils#receiveAmount.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SendAction.tsx From frontend-v1 with GNU Affero General Public License v3.0 | 4 votes |
SendAction: React.FC = () => {
const {
amount,
token,
send,
hasToApprove,
canApprove,
canSend,
toAddress,
approve,
fees,
spender,
} = useSend();
const { signer, account, name } = useConnection();
const sendState = useAppSelector((state) => state.send);
const [isInfoModalOpen, setOpenInfoModal] = useState(false);
const toggleInfoModal = () => setOpenInfoModal((oldOpen) => !oldOpen);
const [isSendPending, setSendPending] = useState(false);
const [isApprovalPending, setApprovalPending] = useState(false);
const { addTransaction } = useTransactions();
const { addDeposit } = useDeposits();
const [updateEthBalance] = api.endpoints.ethBalance.useLazyQuery();
const { trackEvent } = useMatomo();
// trigger balance update
const [updateBalances] = api.endpoints.balances.useLazyQuery();
const tokenInfo = TOKENS_LIST[
sendState.currentlySelectedFromChain.chainId
].find((t) => t.address === token);
const { error, addError, removeError } = useContext(ErrorContext);
const { refetch } = useAllowance(
{
owner: account!,
spender,
chainId: sendState.currentlySelectedFromChain.chainId,
token,
amount,
},
{ skip: !account }
);
const handleApprove = async () => {
const tx = await approve();
if (tx) {
addTransaction({ ...tx, meta: { label: TransactionTypes.APPROVE } });
await tx.wait(CONFIRMATIONS);
refetch();
}
};
const handleSend = async () => {
const { tx, fees } = await send();
if (tx && fees) {
addTransaction({ ...tx, meta: { label: TransactionTypes.DEPOSIT } });
const receipt = await tx.wait(CONFIRMATIONS);
addDeposit({
tx: receipt,
toChain: sendState.currentlySelectedToChain.chainId,
fromChain: sendState.currentlySelectedFromChain.chainId,
amount,
token,
toAddress,
fees,
});
// update balances after tx
if (account) {
updateEthBalance({
chainId: sendState.currentlySelectedFromChain.chainId,
account,
});
updateBalances({
chainId: sendState.currentlySelectedFromChain.chainId,
account,
});
}
}
};
const handleClick = () => {
if (amount.lte(0) || !signer || disableSendForm) {
return;
}
if (hasToApprove) {
setApprovalPending(true);
handleApprove()
.catch((err) => {
addError(new Error(`Error in approve call: ${err.message}`));
console.error(err);
})
.finally(() => setApprovalPending(false));
return;
}
if (canSend) {
// Matomo track send transactions
trackEvent({
category: "send",
action: "bridge",
name:
tokenInfo &&
JSON.stringify({
symbol: tokenInfo.symbol,
from: sendState.currentlySelectedFromChain.chainId,
to: sendState.currentlySelectedToChain.chainId,
}),
value: tokenInfo && Number(formatUnits(amount, tokenInfo.decimals)),
});
setSendPending(true);
if (error) removeError();
handleSend()
.catch((err) => {
addError(new Error(`Error with send call: ${err.message}`));
console.error(err);
})
// this actually happens after component unmounts, which is not good. it causes a react warning, but we need
// it here if user cancels the send. so keep this until theres a better way.
.finally(() => setSendPending(false));
}
};
const buttonMsg = () => {
if (isSendPending) return "Sending in progress...";
if (isApprovalPending) return "Approval in progress...";
if (hasToApprove) return "Approve";
return "Send";
};
const amountMinusFees = useMemo(() => {
if (sendState.currentlySelectedFromChain.chainId === ChainId.MAINNET) {
return amount;
}
return receiveAmount(amount, fees);
}, [amount, fees, sendState.currentlySelectedFromChain.chainId]);
const buttonDisabled =
isSendPending ||
isApprovalPending ||
(!hasToApprove && !canSend) ||
(hasToApprove && !canApprove) ||
amountMinusFees.lte(0);
const isWETH = tokenInfo?.symbol === "WETH";
return (
<AccentSection>
<Wrapper>
{amount.gt(0) && fees && tokenInfo && (
<>
<InfoHeadlineContainer>
<SlippageDisclaimer>
<ConfettiIcon />
All transfers are slippage free!
</SlippageDisclaimer>
<FeesButton onClick={toggleInfoModal}>Fees info</FeesButton>
</InfoHeadlineContainer>
<InfoContainer>
<Info>
{`Time to ${
CHAINS[sendState.currentlySelectedToChain.chainId].name
}`}
<div>
{getEstimatedDepositTime(
sendState.currentlySelectedToChain.chainId
)}
</div>
</Info>
{sendState.currentlySelectedFromChain.chainId !==
ChainId.MAINNET && (
<Info>
<div>Ethereum Network Gas</div>
<div>
{formatUnits(
fees.instantRelayFee.total.add(fees.slowRelayFee.total),
tokenInfo.decimals
)}{" "}
{tokenInfo.symbol}
</div>
</Info>
)}
<Info>
<div>
{sendState.currentlySelectedFromChain.chainId ===
ChainId.MAINNET
? "Native Bridge Fee"
: "Across Bridge Fee"}
</div>
<div>
{sendState.currentlySelectedFromChain.chainId ===
ChainId.MAINNET
? "Free"
: `${formatUnits(fees.lpFee.total, tokenInfo.decimals)}
${tokenInfo.symbol}`}
</div>
</Info>
</InfoContainer>
<AmountToReceive>
You will receive
<span>
{formatUnits(amountMinusFees, tokenInfo.decimals)}{" "}
{isWETH ? "ETH" : tokenInfo.symbol}
</span>
</AmountToReceive>
</>
)}
<PrimaryButton
onClick={handleClick}
disabled={buttonDisabled || !!disableSendForm}
>
<span>{buttonMsg()}</span>
</PrimaryButton>
{name && name === "WalletConnect" && (
<WalletConnectWarning>
<span>
Do not change networks after connecting to Across with
WalletConnect. Across is not responsible for wallet-based
integration issues with WalletConnect.
</span>
</WalletConnectWarning>
)}
{sendState.currentlySelectedFromChain.chainId === ChainId.MAINNET && (
<L1Info>
<div>L1 to L2 transfers use the destination’s native bridge</div>
</L1Info>
)}
</Wrapper>
<InformationDialog isOpen={isInfoModalOpen} onClose={toggleInfoModal} />
</AccentSection>
);
}
Example #2
Source File: Confirmation.tsx From frontend-v1 with GNU Affero General Public License v3.0 | 4 votes |
Confirmation: React.FC = () => {
const { deposit, toggle } = useDeposits();
if (!deposit) return null;
const amountMinusFees = receiveAmount(deposit.amount, deposit.fees);
const tokenInfo = TOKENS_LIST[deposit.fromChain].find(
(t) => t.address === deposit.token
);
const isWETH = tokenInfo?.symbol === "WETH";
return (
<Layout>
<Wrapper>
<Header>
<Heading>Deposit succeeded</Heading>
<SubHeading>
Your funds will arrive in{" "}
{getConfirmationDepositTime(deposit.toChain)}
</SubHeading>
<SuccessIcon>
<Check strokeWidth={4} />
</SuccessIcon>
</Header>
<InfoSection>
<Link
href={CHAINS[deposit.fromChain].constructExplorerLink(
deposit.txHash
)}
target="_blank"
rel="noopener norefferrer"
>
Explorer <ArrowUpRight width={16} height={16} />
</Link>
<div>
<Row>
<Info>
<h3>Sending</h3>
<div>
<Logo
src={tokenInfo?.logoURI}
alt={`${tokenInfo?.symbol} logo`}
/>
<div>
{formatUnits(deposit.amount, tokenInfo?.decimals ?? 18)}{" "}
{tokenInfo?.symbol}
</div>
</div>
</Info>
<Info></Info>
<Info>
<h3>Receiving</h3>
<div>
<Logo
src={isWETH ? MAINNET_ETH?.logoURI : tokenInfo?.logoURI}
alt={`${
isWETH ? MAINNET_ETH?.symbol : tokenInfo?.symbol
} logo`}
/>
<div>
{formatUnits(
amountMinusFees,
(isWETH ? MAINNET_ETH?.decimals : tokenInfo?.decimals) ??
18
)}{" "}
{isWETH ? MAINNET_ETH?.symbol : tokenInfo?.symbol}
</div>
</div>
</Info>
</Row>
<Info>
<h3>From</h3>
<div>
<Logo
src={CHAINS[deposit.fromChain].logoURI}
alt={`${CHAINS[deposit.fromChain].name} logo`}
/>
<div>
<SecondaryLink
href={`${CHAINS[deposit.fromChain].explorerUrl}/address/${
deposit.from
}`}
target="_blank"
rel="noopener noreferrer"
>
<span>{deposit.from}</span>
<span>{shortenAddressLong(deposit.from ?? "")}</span>
</SecondaryLink>
</div>
</div>
</Info>
<Info>
<h3>To</h3>
<div>
<Logo
src={CHAINS[deposit.toChain].logoURI}
alt={`${CHAINS[deposit.toChain].name} logo`}
/>
<div>
<SecondaryLink
href={`${CHAINS[deposit.toChain].explorerUrl}/address/${
deposit.toAddress
}`}
target="_blank"
rel="noopener noreferrer"
>
<span>{deposit.toAddress}</span>
<span>{shortenAddressLong(deposit.toAddress ?? "")}</span>
</SecondaryLink>
</div>
</div>
</Info>
<Info>
<h3>Estimated time of arrival</h3>
<div>
<div>{getConfirmationDepositTime(deposit.toChain)}</div>
</div>
</Info>
</div>
<Button onClick={() => toggle({ showConfirmationScreen: false })}>
Close
</Button>
</InfoSection>
</Wrapper>
</Layout>
);
}