Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<div class="send-alert" role="alert" aria-live="polite">
<alert-icon />
<p aria-label="Error message">{{ errorMsg }}</p>
</div>
</template>

<script setup lang="ts">
import AlertIcon from '@action/icons/send/alert-icon.vue';

interface IProps {
errorMsg: string;
}

defineProps<IProps>();
</script>

<style lang="less">
@import '@action/styles/theme.less';

.send-alert {
margin: 0 32px 8px 32px;
background: @error01;
border-radius: 10px;
padding: 12px 16px 12px 57px;
position: relative;
box-sizing: border-box;

svg {
position: absolute;
left: 16px;
top: 50%;
margin-top: -12px;
}

p {
font-weight: 400;
font-size: 14px;
line-height: 20px;
letter-spacing: 0.25px;
color: @error;
margin: 0;

a {
color: @error;

&:hover {
text-decoration: none;
}
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,7 @@
@gas-type-changed="selectFee"
/>

<send-alert
v-show="hasEnoughBalance && nativeBalanceAfterTransaction.isNeg()"
:native-symbol="network.currencyName"
:price="accountAssets[0]?.price || '0'"
:native-value="
fromBase(
nativeBalanceAfterTransaction.abs().toString(),
network.decimals,
)
"
:decimals="network.decimals"
/>
<send-alert v-show="errorMsg" :error-msg="errorMsg" />

<div class="send-transaction__buttons">
<div class="send-transaction__buttons-cancel">
Expand Down Expand Up @@ -143,7 +132,7 @@ import SendContactsList from '@/providers/common/ui/send-transaction/send-contac
import AssetsSelectList from '@action/views/assets-select-list/index.vue';
import NftSelectList from '@/providers/common/ui/send-transaction/nft-select-list/index.vue';
import SendTokenSelect from './components/send-token-select.vue';
import SendAlert from '@/providers/common/ui/send-transaction/send-alert.vue';
import SendAlert from './components/send-alert.vue';
import SendNftSelect from '@/providers/common/ui/send-transaction/send-nft-select.vue';
import SendInputAmount from '@/providers/common/ui/send-transaction/send-input-amount.vue';
import SendFeeSelect from '@/providers/common/ui/send-transaction/send-fee-select.vue';
Expand All @@ -169,6 +158,7 @@ import erc721 from '../../libs/abi/erc721';
import erc1155 from '../../libs/abi/erc1155';
import { SendTransactionDataType, VerifyTransactionParams } from '../types';
import {
formatFiatValue,
formatFloatingPointValue,
isNumericPositive,
} from '@/libs/utils/number-formatter';
Expand Down Expand Up @@ -217,11 +207,19 @@ const accountAssets = ref<Erc20Token[]>([]);
const selectedAsset = ref<Erc20Token | Partial<Erc20Token>>(loadingAsset);
const amount = ref<string>('');
const isEstimateValid = ref(true);
const hasValidDecimals = computed(() => {
return isValidDecimals(sendAmount.value, selectedAsset.value.decimals!);
});
const hasPositiveSendAmount = computed(() => {
return isNumericPositive(sendAmount.value);
});
const hasEnoughBalance = computed(() => {
if (!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)) {
if (!hasValidDecimals.value) {
return false;
}
if (!hasPositiveSendAmount.value) {
return false;
}

// check if valid sendAmount.value
if (!isNumericPositive(sendAmount.value)) {
return false;
Expand Down Expand Up @@ -341,7 +339,11 @@ const Tx = computed(() => {
return tx;
});

const nativeBalanceAfterTransaction = computed(() => {
/**
* Native balance after the transaction in the base unit of the
* native currency (eg in WETH, Lamports, Satoshis, ...)
*/
const nativeBalanceAfterTransactionInBaseUnits = computed(() => {
if (
isSendToken.value &&
nativeBalance.value &&
Expand Down Expand Up @@ -390,6 +392,71 @@ const nativeBalanceAfterTransaction = computed(() => {
return toBN(0);
});

/**
* Native balance after the transaction in the human unit of the
* native currency (eg in ETH, SOL, BTC, ...)
*/
const nativeBalanceAfterTransactionInHumanUnits = computed(() => {
return fromBase(
nativeBalanceAfterTransactionInBaseUnits.value.abs().toString(),
props.network.decimals,
);
});

const nativeCurrencyUsdPrice = computed(() => {
return accountAssets.value[0]?.price || '0';
});

const balanceAfterInUsd = computed(() => {
return new BigNumber(
nativeBalanceAfterTransactionInHumanUnits.value.toString(),
)
.times(nativeCurrencyUsdPrice.value ?? '0')
.toFixed();
});

const errorMsg = computed(() => {
if (!hasValidDecimals.value) {
return `Too many decimals.`;
}

if (!hasPositiveSendAmount.value) {
return `Invalid amount.`;
}

if (
!hasEnoughBalance.value &&
nativeBalanceAfterTransactionInBaseUnits.value.isNeg()
) {
return `Not enough funds. You are
~${formatFloatingPointValue(nativeBalanceAfterTransactionInHumanUnits.value).value}
${props.network.currencyName} ($ ${
formatFiatValue(balanceAfterInUsd.value).value
}) short.`;
}

if (!props.network.isAddress(addressTo.value) && addressTo.value !== '') {
return `Invalid to address.`;
}

if (
isSendToken.value &&
!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)
) {
return `Invalid decimals for ${selectedAsset.value.symbol}.`;
}

if (!isSendToken.value && !selectedNft.value.id) {
return `Invalid NFT selected.`;
}

if (new BigNumber(sendAmount.value).gt(assetMaxValue.value)) {
return `Amount exceeds maximum value.`;
}

return '';
});

const setTransactionFees = (tx: Transaction) => {
return tx
.getGasCosts()
Expand Down Expand Up @@ -479,7 +546,7 @@ const sendButtonTitle = computed(() => {

const isValidSend = computed<boolean>(() => {
if (!isInputsValid.value) return false;
if (nativeBalanceAfterTransaction.value.isNeg()) return false;
if (nativeBalanceAfterTransactionInBaseUnits.value.isNeg()) return false;
if (!isEstimateValid.value) return false;
return true;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ import { VerifyTransactionParams, SendTransactionDataType } from '../types';
import {
formatFloatingPointValue,
formatFiatValue,
isNumericPositive,
} from '@/libs/utils/number-formatter';
import { routes as RouterNames } from '@/ui/action/router';
import getUiPath from '@/libs/utils/get-ui-path';
Expand Down Expand Up @@ -172,6 +173,7 @@ import {
import getPriorityFees from '../libs/get-priority-fees';
import bs58 from 'bs58';
import SolanaAPI from '@/providers/solana/libs/api';
import { ComputedRefSymbol } from '@vue/reactivity';

const props = defineProps({
network: {
Expand Down Expand Up @@ -211,8 +213,17 @@ const amount = ref<string>('');
const isEstimateValid = ref(true);
const storageFee = ref(0);
const SolTx = ref<SolTransaction>();
const hasEnoughBalance = computed(() => {
if (!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)) {
const hasValidDecimals = computed((): boolean => {
return isValidDecimals(sendAmount.value, selectedAsset.value.decimals!);
});
const hasPositiveSendAmount = computed(() => {
return isNumericPositive(sendAmount.value);
});
const hasEnoughBalance = computed((): boolean => {
if (!hasValidDecimals.value) {
return false;
}
if (!hasPositiveSendAmount.value) {
return false;
}
return toBN(selectedAsset.value.balance ?? '0').gte(
Expand Down Expand Up @@ -276,7 +287,11 @@ const TxInfo = computed<SendTransactionDataType>(() => {
};
});

const nativeBalanceAfterTransaction = computed(() => {
/**
* Native balance after the transaction in the base unit of the
* native currency (eg in WETH, Lamports, Satoshis, ...)
*/
const nativeBalanceAfterTransactionInBaseUnits = computed(() => {
if (
isSendToken.value &&
nativeBalance.value &&
Expand Down Expand Up @@ -320,47 +335,71 @@ const nativeBalanceAfterTransaction = computed(() => {
return toBN(0);
});

const nativeValue = computed(() => {
/**
* Native balance after the transaction in the human unit of the
* native currency (eg in ETH, SOL, BTC, ...)
*/
const nativeBalanceAfterTransactionInHumanUnits = computed(() => {
return fromBase(
nativeBalanceAfterTransaction.value.toString(),
nativeBalanceAfterTransactionInBaseUnits.value.abs().toString(),
props.network.decimals,
);
});

const nativePrice = computed(() => {
const nativeCurrencyUsdPrice = computed(() => {
return accountAssets.value[0]?.price || '0';
});

const priceDifference = computed(() => {
return new BigNumber(nativeValue.value)
.times(nativePrice.value ?? '0')
const balanceAfterInUsd = computed(() => {
return new BigNumber(
nativeBalanceAfterTransactionInHumanUnits.value.toString(),
)
.times(nativeCurrencyUsdPrice.value ?? '0')
.toFixed();
});

const errorMsg = computed(() => {
if (hasEnoughBalance.value && nativeBalanceAfterTransaction.value.isNeg()) {
if (!hasValidDecimals.value) {
return `Too many decimals.`;
}

if (!hasPositiveSendAmount.value) {
return `Invalid amount.`;
}

if (
!hasEnoughBalance.value &&
nativeBalanceAfterTransactionInBaseUnits.value.isNeg()
) {
return `Not enough funds. You are
~${formatFloatingPointValue(nativeValue.value).value}
~${formatFloatingPointValue(nativeBalanceAfterTransactionInHumanUnits.value).value}
${props.network.currencyName} ($ ${
formatFiatValue(priceDifference.value).value
formatFiatValue(balanceAfterInUsd.value).value
}) short.`;
}

if (
!props.network.isAddress(getAddress(addressTo.value)) &&
addressTo.value !== ''
)
) {
return `Invalid to address.`;
}

if (
isSendToken.value &&
!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)
) {
return `Invalid decimals for ${selectedAsset.value.symbol}.`;
}

if (!isSendToken.value && !selectedNft.value.id) {
return `Invalid NFT selected.`;
}
if (new BigNumber(sendAmount.value).gt(assetMaxValue.value))

if (new BigNumber(sendAmount.value).gt(assetMaxValue.value)) {
return `Amount exceeds maximum value.`;
}

return '';
});

Expand Down Expand Up @@ -418,7 +457,7 @@ const sendButtonTitle = computed(() => {

const isValidSend = computed<boolean>(() => {
if (!isInputsValid.value) return false;
if (nativeBalanceAfterTransaction.value.isNeg()) return false;
if (nativeBalanceAfterTransactionInBaseUnits.value.isNeg()) return false;
if (!isEstimateValid.value) return false;
if (gasCostValues.value.ECONOMY.nativeValue === '0') return false;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
</template>

<script setup lang="ts">
// TODO: Is this component deprecated?

import WarningIcon from '@action/icons/send/warning-icon.vue';
defineProps({
feeWarning: {
Expand Down