diff --git a/manifest.json b/manifest.json index bbc8dcd11..9fbd00e8e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Pali Wallet", - "version": "2.0.15", + "version": "2.0.17", "icons": { "16": "assets/icons/favicon-16.png", "32": "assets/icons/favicon-32.png", @@ -91,4 +91,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 195663e7d..8bcd7a6e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "paliwallet", - "version": "2.0.15", + "version": "2.0.17", "description": "A Non-Custodial Crypto Wallet", "private": true, "repository": { @@ -48,7 +48,7 @@ "@babel/runtime": "^7.21.5", "@headlessui/react": "^1.6.0", "@heroicons/react": "^1.0.5", - "@pollum-io/sysweb3-keyring": "^1.0.478", + "@pollum-io/sysweb3-keyring": "^1.0.479", "@pollum-io/sysweb3-network": "^1.0.95", "@pollum-io/sysweb3-utils": "^1.1.232", "@reduxjs/toolkit": "^1.4.0", diff --git a/palette.js b/palette.js index 1f60e6a22..afea109ff 100644 --- a/palette.js +++ b/palette.js @@ -108,11 +108,6 @@ module.exports = { whiteAlpha300: 'rgba(255, 255, 255, 0.16)', }, - alpha: { - whiteAlpha300: 'rgba(255, 255, 255, 0.16)', - whiteAlpha200: 'rgba(255, 255, 255, 0.08)', - }, - extraColors: { red: '#D70000', }, diff --git a/source/assets/icons/hardwallet.svg b/source/assets/icons/hardwallet.svg new file mode 100644 index 000000000..522927b61 --- /dev/null +++ b/source/assets/icons/hardwallet.svg @@ -0,0 +1,3 @@ + + + diff --git a/source/assets/locales/en.json b/source/assets/locales/en.json index 20d8c988e..b3d01d845 100644 --- a/source/assets/locales/en.json +++ b/source/assets/locales/en.json @@ -164,7 +164,8 @@ "titles": { "assetDetails": "ASSET DETAILS", "transactionDetails": "TRANSACTION DETAILS", - "importWallet": "Import wallet" + "importWallet": "Import wallet", + "congratulations": "CONGRATULATIONS!" }, "import": { "importingYourAccount": "Importing your wallet seed automatically import a wallet associated with this seed phrase.", @@ -313,12 +314,14 @@ "permissions": "Permissions", "viewTheAddresses": "View the addresses of your permitted accounts", "errorCreatingHardWallet": "Error creating hardware wallet.", - "hardwareWallet": "HARDWARE WALLET", - "selectTheHardware": "Select the hardware wallet you'd like", + "hardwareWallet": "CONNECT HARDWALLET", + "selectTheHardware": "SELECT HARDWALLET:", "toConnect": "to connect", "toAddAccount": "to add account", "toPali": "to Pali", "dontHaveWallet": "Don't have a hardware wallet?", + "connectYourWalletAndClick": "CONNECT YOUR {{hardwalletName}} AND CLICK TO CONNECT!", + "youCanUseAny": "You can use any {{hardwalletName}} device.", "orderTrezor": "Order a Trezor wallet and keep your funds in cold storage.", "orderLedger": "Order a Ledger wallet and keep your funds in cold storage.", "buyNow": "Buy now", diff --git a/source/assets/locales/es.json b/source/assets/locales/es.json index 5ab97c336..a014ce699 100644 --- a/source/assets/locales/es.json +++ b/source/assets/locales/es.json @@ -164,7 +164,8 @@ "titles": { "assetDetails": "DETALLES DEL ACTIVO", "transactionDetails": "DETALLES DE LA TRANSACCIÓN", - "importWallet": "Importar billetera" + "importWallet": "Importar billetera", + "congratulations": "FELICIDADES!" }, "import": { "importingYourAccount": "Importar tu frase semilla de billetera automáticamente importará una billetera asociada a esta frase semilla.", @@ -315,12 +316,14 @@ "addNewChain": "Agregar Nueva Cadena", "viewTheAddresses": "Ver las direcciones de tus cuentas permitidas", "errorCreatingHardWallet": "Error al crear monedero hardware.", - "hardwareWallet": "MONEDERO HARDWARE", - "selectTheHardware": "Selecciona el monedero hardware que desees", + "hardwareWallet": "CONECTAR HARDWALLET", + "selectTheHardware": "SELECCIONAR HARDWALLET:", "toConnect": "conectar", "toAddAccount": "para agregar una cuenta", "toPali": "a Pali", "dontHaveWallet": "¿No tienes un monedero hardware?", + "connectYourWalletAndClick": "CONECTA TU MONEDERO {{hardwalletName}} Y HAZ CLIC PARA CONECTAR", + "youCanUseAny": "Puedes usar cualquier dispositivo {{hardwalletName}}.", "orderTrezor": "Ordena un monedero Trezor y guarda tus fondos en almacenamiento en frío.", "orderLedger": "Ordena un monedero Ledger y guarda tus fondos en almacenamiento en frío.", "buyNow": "Comprar ahora", diff --git a/source/assets/locales/pt-br.json b/source/assets/locales/pt-br.json index 143ac2e93..ac3892caa 100644 --- a/source/assets/locales/pt-br.json +++ b/source/assets/locales/pt-br.json @@ -289,7 +289,9 @@ "allYourSettings": "All your settings, like custom tokens and imported accounts, will get lost, however, your funds it’s saved!", "setAutoLockTime": "Configurar tempo de bloqueio automático", "defaultMinutes": "Padrão: 5 minutos após inatividade.", - "maximumMinutes": "Máximo: 120 minutos." + "maximumMinutes": "Máximo: 120 minutos.", + "connectYourWalletAndClick": "CONECTE SUA {{hardwalletName}} E CLIQUE PARA CONECTAR!", + "youCanUseAny": "Você pode usar qualquer dispositivo {{hardwalletName}}." }, "start": { "getStarted": "Get started", @@ -379,5 +381,11 @@ "walletSeedPhrasePage": { "keepSeedPhrase": "Mantenha sua seed em segredo!", "anyoneWithThisInfo": "Qualquer pessoa com estas informações pode roubar seus fundos." + }, + "titles": { + "assetDetails": "DETALLES DEL ACTIVO", + "transactionDetails": "DETALLES DE LA TRANSACCIÓN", + "importWallet": "Importar billetera", + "congratulations": "PARABÉNS!" } } diff --git a/source/assets/styles/custom-input-normal.css b/source/assets/styles/custom-input-normal.css index 119c6425d..08ac895c5 100644 --- a/source/assets/styles/custom-input-normal.css +++ b/source/assets/styles/custom-input-normal.css @@ -27,8 +27,8 @@ font-weight: 400; line-height: normal; color: #fff; - top: 55%; - right: 40px; + top: 52%; + right: 23px; transform: translateY(-50%); } @@ -42,7 +42,16 @@ font-weight: 400; line-height: normal; color: #fff; - top: 55%; - right: 40px; + top: 51%; + right: 23px; transform: translateY(-50%); } + +.custom-input-normal .ant-input-suffix .anticon-loading { + position: absolute; + top: 35%; + right: 28px; + cursor: pointer; + font-size: 14px; + line-height: 14px; +} diff --git a/source/components/Modal/WarningBaseModal.tsx b/source/components/Modal/WarningBaseModal.tsx index ca9ce4af9..906447432 100644 --- a/source/components/Modal/WarningBaseModal.tsx +++ b/source/components/Modal/WarningBaseModal.tsx @@ -322,3 +322,35 @@ export const CreatedAccountSuccessfully = ({ ); }; + +export const RPCSuccessfullyAdded = ({ + phraseOne, + onClose, + show = true, + title, +}: IDefaultModal) => { + const { t } = useTranslation(); + const navigate = useNavigate(); + + return ( + +
+
+

{title}

+
+
+

{phraseOne}

+
+ + +
+
+ ); +}; diff --git a/source/components/TransactionOptions/TransactionOptions.tsx b/source/components/TransactionOptions/TransactionOptions.tsx index c5ada26e7..736f3f903 100644 --- a/source/components/TransactionOptions/TransactionOptions.tsx +++ b/source/components/TransactionOptions/TransactionOptions.tsx @@ -1,5 +1,5 @@ import { Menu, Transition } from '@headlessui/react'; -import React from 'react'; +import React, { useCallback } from 'react'; import { Fragment } from 'react'; import { useTranslation } from 'react-i18next'; @@ -19,6 +19,7 @@ export const TransactionOptions: React.FC = ({ }) => { const isLegacyTransaction = transaction.type === 0 || String(transaction.type) === '0x0'; + const { t } = useTranslation(); const { navigate } = useUtils(); @@ -70,6 +71,16 @@ export const TransactionOptions: React.FC = ({ break; } }; + + const handleGoTxDetails = useCallback(() => { + navigate('/home/details', { + state: { + id: null, + hash: transaction.hash, + }, + }); + }, [transaction.hash]); + return ( <> = ({ - + @@ -98,87 +107,82 @@ export const TransactionOptions: React.FC = ({ leaveFrom="transform opacity-100 scale-100" leaveTo="transform opacity-0 scale-95" > - + -

- PENDING TRANSACTION -

- - {({ active }) => ( -
  • +

    + PENDING TRANSACTION +

    + + {({ active }) => ( +
  • - navigate('/home/details', { - state: { - id: null, - hash: transaction.hash, - }, - }) - } - > - - - - - See on the block explorer - -
  • - )} -
    - - {({ active }) => ( -
  • + + + + + See on the block explorer + +
  • + )} +
    + + {({ active }) => ( +
  • handleOnClick(UpdateTxAction.SpeedUp)} - > - - - - - {t('header.speedUp')} - -
  • - )} -
    - - {({ active }) => ( -
  • handleOnClick(UpdateTxAction.SpeedUp)} + > + + + + + {t('header.speedUp')} + +
  • + )} +
    + + {({ active }) => ( +
  • handleOnClick(UpdateTxAction.Cancel)} - > - - - - - {t('buttons.cancel')} - -
  • - )} -
    -
    + onClick={() => handleOnClick(UpdateTxAction.Cancel)} + > + + + + + {t('buttons.cancel')} + + + )} + +
    +
    diff --git a/source/pages/Home/Home.tsx b/source/pages/Home/Home.tsx index e65753733..1eebb5a6c 100755 --- a/source/pages/Home/Home.tsx +++ b/source/pages/Home/Home.tsx @@ -97,6 +97,7 @@ export const Home = () => { const closeModal = () => { setShowModal(false); }; + const formatFiatAmmount = useMemo(() => { if (isTestnet) { return null; diff --git a/source/pages/Home/Panel/ActivityPanel.tsx b/source/pages/Home/Panel/ActivityPanel.tsx index 86a02dcd8..ab92faed3 100644 --- a/source/pages/Home/Panel/ActivityPanel.tsx +++ b/source/pages/Home/Panel/ActivityPanel.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; @@ -25,7 +25,6 @@ export const TransactionsPanel = () => { const adjustedExplorer = useAdjustedExplorer(explorer); const [internalLoading, setInternalLoading] = useState(isLoadingTxs); - const [previousTransactions, setPreviousTransactions] = useState([]); const transactions = useMemo(() => { @@ -82,12 +81,12 @@ export const TransactionsPanel = () => { } }; - const OpenTransactionExplorer = useCallback(() => { + const OpenTransactionExplorer = useMemo(() => { const { xpub, address: userAddress } = accounts[activeAccount.type][activeAccount.id]; const openExplorer = () => window.open( - `${isBitcoinBased ? networkUrl : adjustedExplorer}${ + `${isBitcoinBased ? networkUrl : adjustedExplorer}/${ isBitcoinBased ? 'xpub' : 'address' }/${isBitcoinBased ? xpub : userAddress}`, '_blank' @@ -115,7 +114,10 @@ export const TransactionsPanel = () => { }; }, [isLoadingTxs]); - const allTransactions = hasTransactions ? transactions : previousTransactions; + const allTransactions = useMemo( + () => (hasTransactions ? transactions : previousTransactions), + [hasTransactions, transactions, previousTransactions] + ); return ( <> @@ -123,19 +125,19 @@ export const TransactionsPanel = () => { {!internalLoading && !hasTransactions && (
    - + {OpenTransactionExplorer} {/* */}
    )} {hasTransactions && ( -
    +
    {isBitcoinBased ? ( ) : ( )} - + {OpenTransactionExplorer}
    )} {/* */} diff --git a/source/pages/Home/Panel/components/Details.tsx b/source/pages/Home/Panel/components/Details.tsx index 719fd8ea0..312d32414 100644 --- a/source/pages/Home/Panel/components/Details.tsx +++ b/source/pages/Home/Panel/components/Details.tsx @@ -42,7 +42,7 @@ export const DetailsView = () => { const openSysExplorer = () => { window.open( - `${activeNetwork.url}${isAsset ? 'asset' : 'tx'}/${isAsset ? id : hash}`, + `${activeNetwork.url}${isAsset ? 'asset' : '/tx'}/${isAsset ? id : hash}`, '_blank' ); }; diff --git a/source/pages/Home/Panel/components/Transactions/EVM/EvmList.tsx b/source/pages/Home/Panel/components/Transactions/EVM/EvmList.tsx index 3597901b9..7ec6fa119 100644 --- a/source/pages/Home/Panel/components/Transactions/EVM/EvmList.tsx +++ b/source/pages/Home/Panel/components/Transactions/EVM/EvmList.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { useTransactionsListConfig } from '../utils/useTransactionsInfos'; @@ -16,6 +16,7 @@ import { handleUpdateTransaction, isERC20Transfer, } from 'utils/transactions'; + export const EvmTransactionsList = ({ userTransactions, }: { @@ -29,6 +30,7 @@ export const EvmTransactionsList = ({ activeNetwork: { chainId }, isLastTxConfirmed, } = useSelector((state: RootState) => state.vault); + const { filteredTransactions, formatTimeStamp, @@ -38,36 +40,24 @@ export const EvmTransactionsList = ({ getTxType, txId, } = useTransactionsListConfig(userTransactions); + const { navigate } = useUtils(); + const { getFiatAmount } = usePrice(); + const { wallet } = getController(); + const [modalData, setModalData] = useState(); const [isOpenModal, setIsOpenModal] = useState(false); const [showModal, setShowModal] = useState(false); const [groupedTransactions, setGroupedTransactions] = useState<{ [date: string]: ITransactionInfoEvm[]; }>({}); - const { navigate } = useUtils(); - const { getFiatAmount } = usePrice(); - const { wallet } = getController(); - useEffect(() => { - const grouped = {}; - filteredTransactions.forEach((tx) => { - const formattedDate = formatTimeStamp(tx.timestamp); - if (!grouped[formattedDate]) { - grouped[formattedDate] = []; - } - grouped[formattedDate].push(tx); - }); - setGroupedTransactions(grouped); - }, [filteredTransactions]); + const currentAccount = useMemo( () => accounts[activeAccount.type][activeAccount.id], [accounts, activeAccount] ); - const EvmTransactionsListComponent = ({ - tx, - }: { - tx: ITransactionInfoEvm; - }) => { - const getTxOptions = (isCanceled: boolean, isConfirmed: boolean) => { + + const getTxOptions = useCallback( + (isCanceled: boolean, isConfirmed: boolean, tx: ITransactionInfoEvm) => { if (!isCanceled && !isConfirmed) { return ( ); } - }; + return null; + }, + [ + handleUpdateTransaction, + alert, + chainId, + wallet, + setIsOpenModal, + setModalData, + ] + ); + + const EvmTransactionsListComponent = useCallback(({ tx }) => { const isTxCanceled = tx?.isCanceled === true; - const isConfirmed = tx.confirmations > 0; + const isConfirmed = tx?.confirmations > 0; const isErc20Tx = isERC20Transfer(tx as any); const isTxSent = isBitcoinBased ? false - : tx.from.toLowerCase() === currentAccount.address.toLowerCase(); + : tx?.from?.toLowerCase() === currentAccount?.address?.toLowerCase(); const tokenValue = !isConfirmed - ? typeof tx.value === 'string' - ? tx.value - : Number(tx.value.hex) / 1e18 - : Number(tx.value) / 1e18; + ? typeof tx?.value === 'string' + ? tx?.value + : Number(tx?.value?.hex) / 1e18 + : Number(tx?.value) / 1e18; const finalTxValue = isErc20Tx ? Number(getERC20TransferValue(tx as any)) / 1e18 : tokenValue; + + const handleGoTxDetails = () => { + navigate('/home/details', { + state: { id: null, hash: tx[txId] }, + }); + }; + return (
    @@ -115,7 +124,7 @@ export const EvmTransactionsList = ({ {getTokenSymbol(isErc20Tx, coinsList, tx)}
    - ${getFiatAmount(+tx.value / 1e18, 6)} + ${getFiatAmount(+tx?.value / 1e18, 6)}
    @@ -123,21 +132,32 @@ export const EvmTransactionsList = ({ - navigate('/home/details', { - state: { id: null, hash: tx[txId] }, - }) - } + onClick={handleGoTxDetails} /> ) : ( - getTxOptions(isTxCanceled, isConfirmed) + getTxOptions(isTxCanceled, isConfirmed, tx) )}
    ); - }; + }, []); + + useEffect(() => { + const grouped = {}; + + filteredTransactions.forEach((tx) => { + const formattedDate = formatTimeStamp(tx?.timestamp); + if (!grouped[formattedDate]) { + grouped[formattedDate] = []; + } + grouped[formattedDate].push(tx); + }); + + setGroupedTransactions(grouped); + }, [filteredTransactions]); + useEffect(() => { if (!currentAccount.transactions.ethereum?.[chainId]) { return; @@ -158,6 +178,7 @@ export const EvmTransactionsList = ({ wallet.setIsLastTxConfirmed(chainId, true); } }, [currentAccount]); + return ( <> setShowModal(false)} /> - {Object.entries(groupedTransactions).map(([date, transactions]: any) => ( -
    -
    {date}
    - {transactions.map((tx, idx) => ( - - ))} -
    - ))} + {Object?.entries(groupedTransactions)?.map( + ([date, transactions]: any) => ( +
    +
    {date}
    + {transactions?.map((tx) => ( + + ))} +
    + ) + )} ); }; diff --git a/source/pages/Home/TxsPanel.tsx b/source/pages/Home/TxsPanel.tsx index da98f62ec..3759689c5 100755 --- a/source/pages/Home/TxsPanel.tsx +++ b/source/pages/Home/TxsPanel.tsx @@ -11,7 +11,7 @@ export const TxsPanel: FC = () => { const { t } = useTranslation(); return ( -
    +
    @@ -455,7 +457,9 @@ export const SendEth = () => { : '/assets/icons/errorIcon.svg' } alt={isValidAmount === true ? 'Success' : 'Error'} - className="absolute right-[5.5rem] top-[-28.5px]" + className={`absolute right-[2rem] ${ + isValidAmount === true ? 'top-[-26.5px]' : 'top-[-25px]' + }`} /> )}
    diff --git a/source/pages/Send/SendSys.tsx b/source/pages/Send/SendSys.tsx index 848b10a98..409451efe 100644 --- a/source/pages/Send/SendSys.tsx +++ b/source/pages/Send/SendSys.tsx @@ -1,5 +1,4 @@ import { Switch, Menu, Transition } from '@headlessui/react'; -import { ChevronDoubleDownIcon } from '@heroicons/react/solid'; import { Form, Input } from 'antd'; import { toSvg } from 'jdenticon'; import { uniqueId } from 'lodash'; diff --git a/source/pages/Send/SendTransaction.tsx b/source/pages/Send/SendTransaction.tsx index 195ba4a1c..58cb55c9d 100644 --- a/source/pages/Send/SendTransaction.tsx +++ b/source/pages/Send/SendTransaction.tsx @@ -282,7 +282,7 @@ export const SendTransaction = () => { {tx?.from ? (
    -
    +
    { const [isTestnet, setIsTestnet] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [selectedHardwareWallet, setSelectedHardwareWallet] = - useState('trezor'); + const [selectedHardwareWallet, setSelectedHardwareWallet] = useState(); const [isReconnect, setIsReconnect] = useState(false); const { activeNetwork, isBitcoinBased, accounts, advancedSettings } = useSelector((state: RootState) => state.vault); @@ -36,15 +28,6 @@ const ConnectHardwareWalletView: FC = () => { const { slip44 } = activeNetwork; const isSysUTXOMainnet = isBitcoinBased && activeNetwork.chainId === 57; - const ledgerButtonColor = - selectedHardwareWallet === 'ledger' - ? 'bg-bkg-3 border-brand-deepPink cursor-pointer' - : 'bg-bkg-1 border-brand-royalblue cursor-pointer'; - - const trezorButtonColor = - selectedHardwareWallet === 'trezor' - ? 'bg-bkg-3 border-brand-deepPink' - : 'bg-bkg-1 border-brand-royalblue'; const modalTitle = isReconnect ? t('settings.ledgerConnected') @@ -56,6 +39,24 @@ const ConnectHardwareWalletView: FC = () => { const controller = getController(); + const trezorSelectedButtonStyle = `${ + selectedHardwareWallet === 'trezor' + ? 'bg-brand-blue400 border-2 border-brand-blue400 cursor-pointer' + : 'bg-transparent border-2 border-white ' + }`; + + const ledgerSelectedButtonStyle = `${ + selectedHardwareWallet === 'ledger' + ? 'bg-brand-blue400 border-2 border-brand-blue400 cursor-pointer' + : 'bg-transparent border-2 border-white ' + }`; + + const confirmButtonDisbledStyle = `${ + isTestnet || selectedHardwareWallet === undefined + ? 'opacity-60' + : 'opacity-100' + }`; + const { isInCooldown }: CustomJsonRpcProvider = controller.wallet.ethereumTransaction.web3Provider; const isLedger = selectedHardwareWallet === 'ledger'; @@ -157,6 +158,27 @@ const ConnectHardwareWalletView: FC = () => { } }; + const ledgerTooltipContent = useMemo( + () => + isSysUTXOMainnet || !isBitcoinBased + ? '' + : t('settings.ledgerOnlyAvailable'), + [isSysUTXOMainnet, isBitcoinBased] + ); + + const supportTooltipContent = useMemo( + () => + isTestnet && + (isLedger + ? t('settings.ledgerDoesntSupport') + : t('settings.trezorDoesntSupport')), + [isTestnet, isLedger] + ); + + const handleHardwalletBuyNow = useCallback(() => { + window.open(isLedger ? 'https://www.ledger.com/' : 'https://trezor.io/'); + }, [isLedger]); + useEffect(() => { verifyIfIsTestnet().then((isTestnetResponse) => setIsTestnet(isTestnetResponse) @@ -180,165 +202,98 @@ const ConnectHardwareWalletView: FC = () => { window.close(); }} /> -
    +
    +
    + +
    -

    - {t('settings.selectTheHardware')}{' '} - {!trezorAccounts.length - ? t('settings.toConnect') - : t('settings.toAddAccount')}{' '} - {t('settings.toPali')} -

    + {selectedHardwareWallet ? ( + <> +
    +

    + {t('settings.connectYourWalletAndClick', { + hardwalletName: + selectedHardwareWallet === HardWallets.LEDGER + ? 'LEDGER' + : 'TREZOR', + })} +

    +

    + {t('settings.youCanUseAny', { + hardwalletName: + selectedHardwareWallet === HardWallets.LEDGER + ? 'Ledger' + : 'Trezor', + })} +

    +
    + + ) : ( +
    +

    + {t('settings.selectTheHardware')}{' '} +

    -

    setSelectedHardwareWallet('trezor')} - id="trezor-btn" - > - Trezor -

    - {advancedSettings?.ledger && ( - -

    { - if (isSysUTXOMainnet || !isBitcoinBased) { - setSelectedHardwareWallet('ledger'); - } - return; - }} + + {advancedSettings?.ledger && ( + + + + )}

    )} - - {isLedger && ( -
    -

    - {isSysUTXOMainnet - ? t('settings.toUseLedger') - : t('settings.toUseLedgerEvm')} -

    - - {isSysUTXOMainnet && ( -

    - window.open( - 'https://github.com/osiastedian/ledger-app-syscoin' - ) - } - > - {t('settings.githubLink')} +

    +
    + {selectedHardwareWallet && ( +
    +

    {t('settings.dontHaveWallet')}

    +
    +

    + {isLedger + ? t('settings.orderLedger') + : t('settings.orderTrezor')} + + {t('settings.buyNow')} +

    - )} +
    )} - -
    -

    - {t('settings.dontHaveWallet')} -
    -
    - {isLedger ? t('settings.orderLedger') : t('settings.orderTrezor')} -

    - -

    - window.open( - isLedger ? 'https://www.ledger.com/' : 'https://trezor.io/' - ) - } - > - {t('settings.buyNow')} -

    -
    - - - {({ open }) => ( - <> - - {t('connections.learnMore')} - - - - -
    -

    - 1 - {t('settings.connectToAHardwareWallet')} -

    - - - {t('settings.connectYourHardwareWallet')} - - -

    - 2 - {t('settings.startUsingSys')} -

    - - - {t('settings.useYourHardwareAccount')} - -
    -
    - - )} -
    -
    - -
    - - + - +
    diff --git a/source/pages/Settings/CustomRPC.tsx b/source/pages/Settings/CustomRPC.tsx index e352de8ea..566387add 100644 --- a/source/pages/Settings/CustomRPC.tsx +++ b/source/pages/Settings/CustomRPC.tsx @@ -10,10 +10,13 @@ import { validateEthRpc, validateSysRpc } from '@pollum-io/sysweb3-network'; import checkAtIcon from 'assets/icons/checkAt.svg'; import { Button, Layout, Tooltip } from 'components/index'; +import { StatusModal } from 'components/Modal/StatusModal'; +import { RPCSuccessfullyAdded } from 'components/Modal/WarningBaseModal'; import { useUtils } from 'hooks/index'; import { RootState } from 'state/store'; import { ICustomRpcParams } from 'types/transactions'; import { getController } from 'utils/browser'; +import { NetworkType } from 'utils/types'; const CustomRPCView = () => { const { state }: { state: any } = useLocation(); @@ -22,6 +25,9 @@ const CustomRPCView = () => { const [loading, setLoading] = useState(false); const [isUrlValid, setIsUrlValid] = useState(false); const [urlFieldValue, setUrlFieldValue] = useState(''); + const [addedRpc, setAddedRpc] = useState(false); + const [showModal, setShowModal] = useState(false); + const [errorModalMessage, setErrorModalMessage] = useState(''); const [lastRpcChainIdSearched, setLastRpcChainIdSearched] = useState< number | null >(null); @@ -35,10 +41,24 @@ const CustomRPCView = () => { const [form] = useForm(); + const switchBallStyle = isSyscoinRpc + ? 'translate-x-6 bg-brand-deepPink100' + : 'translate-x-1 bg-brand-blue200'; + + const inputHiddenOrNotStyle = isSyscoinRpc ? 'hidden' : 'relative'; + + const modalMessageOnSuccessful = state + ? t('settings.rpcSucessfullyEdited') + : t('settings.rpcSucessfullyAdded'); + const populateForm = (field: string, value: number | string) => { if (!form.getFieldValue(field)) form.setFieldsValue({ [field]: value }); }; + const closeModal = () => { + setShowModal(false); + }; + const onSubmit = async (data: ICustomRpcParams) => { setLoading(true); @@ -50,28 +70,20 @@ const CustomRPCView = () => { try { if (!state) { await controller.wallet.addCustomRpc(customRpc); - - alert.success(t('settings.rpcSucessfullyAdded')); - setLoading(false); - - navigate('/settings/networks/edit'); - + setAddedRpc(true); return; } await controller.wallet.editCustomRpc(customRpc, state.selected); - - alert.success(t('settings.rpcSucessfullyEdited')); - setLoading(false); - - navigate('/settings/networks/edit'); + setAddedRpc(true); } catch (error: any) { alert.removeAll(); - alert.error(error.message); - + setAddedRpc(false); + setShowModal(true); setLoading(false); + setErrorModalMessage(error.message); } }; @@ -102,16 +114,28 @@ const CustomRPCView = () => { const fieldErrors = form.getFieldError('url'); if (urlFieldValue && fieldErrors.length > 0) { alert.removeAll(); - alert.error(t('settings.invalidRpcUrl')); + setErrorModalMessage(t('settings.invalidRpcUrl')); } }, [urlFieldValue]); const handleConnect = async (data: ICustomRpcParams) => { await wallet.setActiveNetwork(data, String(activeNetwork.chainId)); }; - return ( + navigate('/settings/networks/edit')} + /> +
    { isBitcoinBased ? 'text-brand-pink200' : 'text-brand-blue200' }`} > - {isBitcoinBased ? 'UTXO' : 'NEVM'} Network + {isBitcoinBased ? NetworkType.UTXO : NetworkType.EVM} Network

    ) : (
    -

    Ethereum

    +

    EVM

    { setIsSyscoinRpc(!isSyscoinRpc)} - className="relative inline-flex items-center w-9 h-4 border border-brand-royalblue rounded-full" + className="relative inline-flex items-center w-9 h-4 border border-white rounded-full" disabled={!!state} > Syscoin Network -

    Syscoin

    +

    UTXO

    )} @@ -189,7 +209,7 @@ const CustomRPCView = () => { placeholder={`${t('settings.label')} ${ isSyscoinRpc ? `(${t('settings.label')})` : '' }`} - className="custom-input-password relative" + className="custom-input-normal relative" /> @@ -308,7 +328,7 @@ const CustomRPCView = () => { @@ -327,9 +347,7 @@ const CustomRPCView = () => { type="text" disabled={isInputDisabled} placeholder="Chain ID" - className={`${ - isSyscoinRpc ? 'hidden' : 'relative' - } custom-input-password `} + className={`${inputHiddenOrNotStyle} custom-input-normal `} /> @@ -347,9 +365,7 @@ const CustomRPCView = () => { @@ -367,9 +383,7 @@ const CustomRPCView = () => { {state?.isEditing ? ( @@ -377,8 +391,15 @@ const CustomRPCView = () => { className="flex justify-center items-center gap-2 cursor-pointer" onClick={() => (window.location.href = 'https://chainlist.org/')} > - Check at chainlist -

    + Check at chainlist (window.location.href = 'https://chainlist.org/')} + /> +

    (window.location.href = 'https://chainlist.org/')} + > Check chainlist

    @@ -404,7 +425,7 @@ const CustomRPCView = () => {
    ) : ( -
    +
    */} diff --git a/source/pages/SwitchNetwork/SwitchNetwork.tsx b/source/pages/SwitchNetwork/SwitchNetwork.tsx index 61621976f..13ba70be2 100644 --- a/source/pages/SwitchNetwork/SwitchNetwork.tsx +++ b/source/pages/SwitchNetwork/SwitchNetwork.tsx @@ -14,7 +14,7 @@ import { NetworkList } from './NetworkList'; export const SwitchNetwork = () => { const { state }: { state: any } = useLocation(); const { t } = useTranslation(); - const { isBitcoinBased, activeNetwork, networks } = useSelector( + const { isBitcoinBased, activeNetwork } = useSelector( (rootState: RootState) => rootState.vault ); const { @@ -22,7 +22,7 @@ export const SwitchNetwork = () => { networkThatNeedsChanging, connectedColor, networkNeedsChangingColor, - } = useNetworkInfo({ isBitcoinBased, networks }); + } = useNetworkInfo({ isBitcoinBased }); const networkLabel = useMemo( () => ( diff --git a/source/scripts/Background/controllers/index.ts b/source/scripts/Background/controllers/index.ts index 2ee72a660..22a44422e 100755 --- a/source/scripts/Background/controllers/index.ts +++ b/source/scripts/Background/controllers/index.ts @@ -17,6 +17,7 @@ import { IPersistState } from 'state/types'; import { setAccountPropertyByIdAndType, setAccountTypeInAccountsObject, + setActiveNetwork, setAdvancedSettings, setIsLastTxConfirmed, setNetworks, @@ -152,6 +153,47 @@ const MasterController = ( ); } + const currentRpcSysUtxoMainnet = + store.getState().vault.networks[TransactionsType.Syscoin][57].url; + + const { activeNetwork } = store.getState().vault; + + if (currentRpcSysUtxoMainnet !== 'https://blockbook.syscoin.org') { + store.dispatch( + setNetworks({ + chain: 'syscoin' as INetworkType, + network: { + chainId: 57, + url: 'https://blockbook.syscoin.org', + label: 'Syscoin Mainnet', + default: true, + currency: 'sys', + slip44: 57, + isTestnet: false, + } as INetwork, + isEdit: true, + }) + ); + } + + const isSysUtxoMainnetWithWrongRpcUrl = + activeNetwork.chainId === 57 && + activeNetwork.url.includes('https://blockbook.elint.services'); + + if (isSysUtxoMainnetWithWrongRpcUrl) { + store.dispatch( + setActiveNetwork({ + chainId: 57, + url: 'https://blockbook.syscoin.org', + label: 'Syscoin Mainnet', + default: true, + currency: 'sys', + slip44: 57, + isTestnet: false, + } as INetwork) + ); + } + // if timer state is 5, it means that the user is coming from a previous version, with a default timer value of 5 minutes. if (Number(store.getState().vault.timer) === 5) { store.dispatch(setTimer(30)); diff --git a/source/scripts/Background/controllers/message-handler/types.ts b/source/scripts/Background/controllers/message-handler/types.ts index 4507c55b3..af875f982 100644 --- a/source/scripts/Background/controllers/message-handler/types.ts +++ b/source/scripts/Background/controllers/message-handler/types.ts @@ -4,6 +4,12 @@ export type Message = { id: string; type: string; }; + +export enum HardWallets { + LEDGER = 'LEDGER', + TREZOR = 'TREZOR', +} + //TODO: addtype for rpc subscription notifications here export enum PaliEvents { accountsChanged = 'pali_accountsChanged', diff --git a/source/state/vault/index.ts b/source/state/vault/index.ts index 6bee4dfa3..df2f6d0c5 100644 --- a/source/state/vault/index.ts +++ b/source/state/vault/index.ts @@ -61,7 +61,7 @@ export const initialState: IVaultState = { activeChain: INetworkType.Syscoin, activeNetwork: { chainId: 57, - url: 'https://blockbook.elint.services/', + url: 'https://blockbook.syscoin.org', label: 'Syscoin Mainnet', default: true, currency: 'sys', diff --git a/source/utils/i18n.ts b/source/utils/i18n.ts index 005c6c625..3cc3a27a2 100644 --- a/source/utils/i18n.ts +++ b/source/utils/i18n.ts @@ -53,7 +53,7 @@ i18next lowerCaseLng: true, fallbackLng: determineLngFn, keySeparator: '.', - interpolation: { escapeValue: false }, + interpolation: { escapeValue: true }, }); export { i18next }; diff --git a/yarn.lock b/yarn.lock index 81d0f2286..7d1636768 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2273,10 +2273,10 @@ resolved "https://registry.yarnpkg.com/@pollum-io/sysweb3-core/-/sysweb3-core-1.0.26.tgz#57a1fd60942b6d2261fb74f73807698205ecb344" integrity sha512-6NG2s0PLEMVQyMQnC8voZOKWh+MAp6SX9B4Dseg79Xtfi/flWp2FV/uVg7WzY9C3bTpHJ+mqtLWeWRgG63dQ/w== -"@pollum-io/sysweb3-keyring@^1.0.478": - version "1.0.478" - resolved "https://registry.yarnpkg.com/@pollum-io/sysweb3-keyring/-/sysweb3-keyring-1.0.478.tgz#c1b9c85c29c8266bb0ed0ec1b00f73a988cb34a5" - integrity sha512-JYvQgHDVK5hxYf2touwyMYaQh6ddpf84oPDwduN54GM043O8ClOa6VWo1oQM9AHGbhnek1J2s3Z6Tggt7SOkgg== +"@pollum-io/sysweb3-keyring@^1.0.479": + version "1.0.479" + resolved "https://registry.yarnpkg.com/@pollum-io/sysweb3-keyring/-/sysweb3-keyring-1.0.479.tgz#0dd20786426c9d8ed8bb3f328f8bf8ecae133338" + integrity sha512-LvRUH2jZh2Pr4Dt/rsA2GWOVHeWNlFjBfsdVu7ijWMP0D+8bSUoamapX8PRvzHU7A6D5JzpzAN4/KrR7p1iIXg== dependencies: "@bitcoinerlab/descriptors" "^2.0.1" "@bitcoinerlab/secp256k1" "^1.0.5"