From 609be9eb6439390374fbf3f92572c3e72c86f094 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Mon, 11 Sep 2023 10:35:13 +0200 Subject: [PATCH] feat: refactored the toast responses (#442) * feat: refactored the toast responses * fix: fixed the map return * feat: added a recent transaction center * tidy: removed logs * fix: fixed autolend * feat: added global lending on first account funding * fix: added endOfLine setting * feat: added eslint warnings for lineEnds * fix: made the vault message generic --- .eslintrc.json | 1 + .prettierrc | 3 +- .../AccountFund/AccountFundContent.tsx | 17 +- .../AccountFund/AccountFundFullPage.tsx | 6 +- src/components/Modals/BorrowModal.tsx | 4 +- .../Modals/Vault/VaultBorrowings.tsx | 4 +- src/components/Modals/Vault/VaultDeposits.tsx | 8 +- src/components/Toaster.tsx | 68 +++-- src/components/Wallet/RecentTransactions.tsx | 81 ++++++ .../Wallet/WalletConnectedButton.tsx | 2 + src/constants/localStore.ts | 1 + src/hooks/useAutoLend.ts | 1 + src/hooks/useTransactionStore.ts | 21 ++ src/store/slices/broadcast.ts | 269 +++++++++++++----- src/types/interfaces/store/broadcast.d.ts | 33 ++- src/utils/formatters.ts | 7 +- 16 files changed, 418 insertions(+), 108 deletions(-) create mode 100644 src/components/Wallet/RecentTransactions.tsx create mode 100644 src/hooks/useTransactionStore.ts diff --git a/.eslintrc.json b/.eslintrc.json index 740bc29a..4685aed2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,7 @@ { "extends": "next/core-web-vitals", "rules": { + "linebreak-style": ["warn", "unix"], "sort-imports": [ "warn", { diff --git a/.prettierrc b/.prettierrc index 8c32ca31..bda09680 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,6 @@ "jsxSingleQuote": true, "semi": false, "printWidth": 100, - "trailingComma": "all" + "trailingComma": "all", + "endOfLine": "lf" } diff --git a/src/components/Account/AccountFund/AccountFundContent.tsx b/src/components/Account/AccountFund/AccountFundContent.tsx index a1ba56bb..43d352a8 100644 --- a/src/components/Account/AccountFund/AccountFundContent.tsx +++ b/src/components/Account/AccountFund/AccountFundContent.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames' -import React, { useCallback, useEffect, useMemo, useState } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' import Button from 'components/Button' import DepositCapMessage from 'components/DepositCapMessage' @@ -8,8 +8,11 @@ import SwitchAutoLend from 'components/Switch/SwitchAutoLend' import Text from 'components/Text' import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider' import WalletBridges from 'components/Wallet/WalletBridges' +import { DEFAULT_SETTINGS } from 'constants/defaultSettings' +import { LEND_ASSETS_KEY } from 'constants/localStore' import { BN_ZERO } from 'constants/math' import useAutoLend from 'hooks/useAutoLend' +import useLocalStorage from 'hooks/useLocalStorage' import useMarketAssets from 'hooks/useMarketAssets' import useToggle from 'hooks/useToggle' import { useUpdatedAccount } from 'hooks/useUpdatedAccount' @@ -31,8 +34,12 @@ interface Props { export default function AccountFundContent(props: Props) { const deposit = useStore((s) => s.deposit) + const accounts = useStore((s) => s.accounts) const walletAssetModal = useStore((s) => s.walletAssetsModal) - + const [lendAssets, setLendAssets] = useLocalStorage( + LEND_ASSETS_KEY, + DEFAULT_SETTINGS.lendAssets, + ) const [isFunding, setIsFunding] = useToggle(false) const [fundingAssets, setFundingAssets] = useState([]) const { data: marketAssets } = useMarketAssets() @@ -124,6 +131,10 @@ export default function AccountFundContent(props: Props) { toggleIsLending(autoLendEnabledAccountIds.includes(props.accountId)) }, [props.accountId, autoLendEnabledAccountIds, toggleIsLending]) + useEffect(() => { + if (accounts?.length === 1 && isLending && !lendAssets) setLendAssets(true) + }, [isLending, accounts, lendAssets, setLendAssets]) + const depositCapReachedCoins = useMemo(() => { const depositCapReachedCoins: BNCoin[] = [] fundingAssets.forEach((asset) => { @@ -180,7 +191,7 @@ export default function AccountFundContent(props: Props) { (null) useEffect(() => { - if (accounts && !selectedAccountId && accountId) - setSelectedAccountId(currentAccount?.id ?? accountId) + if (accounts && !selectedAccountId && accountId) setSelectedAccountId(accountId) + if (accountId && selectedAccountId !== accountId) setSelectedAccountId(accountId) }, [accounts, selectedAccountId, accountId, currentAccount]) if (!selectedAccountId || !address) return null diff --git a/src/components/Modals/BorrowModal.tsx b/src/components/Modals/BorrowModal.tsx index 10d94faf..eaa5f857 100644 --- a/src/components/Modals/BorrowModal.tsx +++ b/src/components/Modals/BorrowModal.tsx @@ -121,7 +121,7 @@ function BorrowModal(props: Props) { simulateRepay(repayCoin) } }, - [asset, amount, isRepay, simulateRepay], + [asset, amount, isRepay, simulateRepay, modal], ) useEffect(() => { @@ -145,7 +145,7 @@ function BorrowModal(props: Props) { ) setMax(BigNumber.min(maxBorrowAmount, modal.marketData?.liquidity?.amount || 0)) - }, [account, isRepay, modal, asset.denom, computeMaxBorrowAmount, borrowToWallet]) + }, [account, isRepay, modal, asset.denom, computeMaxBorrowAmount, borrowToWallet, apr]) useEffect(() => { if (amount.isGreaterThan(max)) { diff --git a/src/components/Modals/Vault/VaultBorrowings.tsx b/src/components/Modals/Vault/VaultBorrowings.tsx index 7fcac368..296cb820 100644 --- a/src/components/Modals/Vault/VaultBorrowings.tsx +++ b/src/components/Modals/Vault/VaultBorrowings.tsx @@ -149,6 +149,8 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { const isSuccess = await depositIntoVault({ accountId: updatedAccount.id, actions: props.depositActions, + deposits: props.deposits, + borrowings: props.borrowings, }) setIsConfirming(false) if (isSuccess) { @@ -237,4 +239,4 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { /> ) -} \ No newline at end of file +} diff --git a/src/components/Modals/Vault/VaultDeposits.tsx b/src/components/Modals/Vault/VaultDeposits.tsx index 115ad549..1a34c29e 100644 --- a/src/components/Modals/Vault/VaultDeposits.tsx +++ b/src/components/Modals/Vault/VaultDeposits.tsx @@ -1,9 +1,9 @@ import BigNumber from 'bignumber.js' import { useMemo, useState } from 'react' -import DisplayCurrency from 'components/DisplayCurrency' import Button from 'components/Button' import DepositCapMessage from 'components/DepositCapMessage' +import DisplayCurrency from 'components/DisplayCurrency' import Divider from 'components/Divider' import { Gauge } from 'components/Gauge' import { ArrowRight, ExclamationMarkCircled } from 'components/Icons' @@ -11,14 +11,13 @@ import Slider from 'components/Slider' import Switch from 'components/Switch' import Text from 'components/Text' import TokenInput from 'components/TokenInput' -import { ASSETS } from 'constants/assets' import { BN_ZERO } from 'constants/math' +import { ORACLE_DENOM } from 'constants/oracle' import usePrices from 'hooks/usePrices' import { BNCoin } from 'types/classes/BNCoin' import { accumulateAmounts } from 'utils/accounts' import { byDenom } from 'utils/array' import { BN, getValueFromBNCoins } from 'utils/helpers' -import { ORACLE_DENOM } from 'constants/oracle' interface Props { deposits: BNCoin[] @@ -36,7 +35,6 @@ interface Props { export default function VaultDeposit(props: Props) { const { deposits, primaryAsset, secondaryAsset, account, onChangeDeposits, displayCurrency } = props - const displayCurrencyAsset = ASSETS.find(byDenom(displayCurrency)) ?? ASSETS[0] const [availablePrimaryAmount, availableSecondaryAmount] = useMemo( () => [ accumulateAmounts(primaryAsset.denom, [...account.deposits, ...account.lends]), @@ -160,7 +158,7 @@ export default function VaultDeposit(props: Props) { return (
-
+
( +
+ {item.coins.length > 0 && ( + <> + + {item.text} + +
    + {item.coins.map((coin) => ( +
  • + {formatAmountWithSymbol(coin)} +
  • + ))} +
+ + )} +
+ )) +} export default function Toaster() { const [reduceMotion] = useLocalStorage(REDUCE_MOTION_KEY, DEFAULT_SETTINGS.reduceMotion) const toast = useStore((s) => s.toast) const isError = toast?.isError + const { addTransaction } = useTransactionStore() if (toast) { + if (!isError) addTransaction(toast) const Msg = () => (
- {toast.title ? toast.title : isError ? 'Error' : 'Success'} + {isError ? (toast.title ? toast.title : 'Error') : 'Success'}
- - - {toast.message} - + {!isError && toast.accountId && ( + {`Credit Account ${toast.accountId}`} + )} + {toast.message && ( + + {toast.message} + + )} + {!isError && toast.content?.length > 0 && generateToastContent(toast.content)} {toast.hash && ( - - {`View on ${EXPLORER_NAME}`} - - +
+ + {`View on ${EXPLORER_NAME}`} + + +
)}
diff --git a/src/components/Wallet/RecentTransactions.tsx b/src/components/Wallet/RecentTransactions.tsx new file mode 100644 index 00000000..72bc7068 --- /dev/null +++ b/src/components/Wallet/RecentTransactions.tsx @@ -0,0 +1,81 @@ +import classNames from 'classnames' +import moment from 'moment' + +import Card from 'components/Card' +import Divider from 'components/Divider' +import Text from 'components/Text' +import { TextLink } from 'components/TextLink' +import { generateToastContent } from 'components/Toaster' +import { EXPLORER_TX_URL } from 'constants/explorer' +import { TRANSACTIONS_KEY } from 'constants/localStore' +import useLocalStorage from 'hooks/useLocalStorage' +import useStore from 'store' + +export default function RecentTransactions() { + const address = useStore((s) => s.address) + const [transactions, setTransactions] = useLocalStorage(TRANSACTIONS_KEY, { + recent: [], + }) + const recentTransactions = transactions.recent + .filter((tx) => tx.address === address) + .sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1)) + return ( +
+ + + Recent Transactions + + {recentTransactions.length === 0 ? ( + + No recent transactions + + ) : ( + <> +
+
+ {recentTransactions.map((tx) => { + const { accountId, hash, content, message, timestamp } = tx + return ( + { + if (hash) window.open(`${EXPLORER_TX_URL}${hash}`, '_blank') + }} + key={hash} + > +
+ Credit Account {accountId} + + {moment.unix(timestamp).format('lll')} + +
+ {message && ( + + {message} + + )} + {content?.length > 0 && generateToastContent(content)} +
+ ) + })} +
+
+
+ { + setTransactions({ recent: [] }) + }} + className='underline text-white/70 hover:no-underline' + > + Clear all Transactions + +
+ + )} +
+ ) +} diff --git a/src/components/Wallet/WalletConnectedButton.tsx b/src/components/Wallet/WalletConnectedButton.tsx index 5ef53440..f8b443dd 100644 --- a/src/components/Wallet/WalletConnectedButton.tsx +++ b/src/components/Wallet/WalletConnectedButton.tsx @@ -11,6 +11,7 @@ import { FormattedNumber } from 'components/FormattedNumber' import { Check, Copy, ExternalLink, Osmo } from 'components/Icons' import Overlay from 'components/Overlay' import Text from 'components/Text' +import RecentTransactions from 'components/Wallet/RecentTransactions' import { CHAINS } from 'constants/chains' import { IS_TESTNET } from 'constants/env' import { BN_ZERO } from 'constants/math' @@ -171,6 +172,7 @@ export default function WalletConnectedButton() {
+
) diff --git a/src/constants/localStore.ts b/src/constants/localStore.ts index 2e80bb29..fd0c07cd 100644 --- a/src/constants/localStore.ts +++ b/src/constants/localStore.ts @@ -7,3 +7,4 @@ export const AUTO_LEND_ENABLED_ACCOUNT_IDS_KEY = 'autoLendEnabledAccountIds' export const SLIPPAGE_KEY = 'slippage' export const TERMS_OF_SERVICE_KEY = 'termsOfService' export const TUTORIAL_KEY = 'tutorial' +export const TRANSACTIONS_KEY = 'transactions' diff --git a/src/hooks/useAutoLend.ts b/src/hooks/useAutoLend.ts index 259e51a9..edd77773 100644 --- a/src/hooks/useAutoLend.ts +++ b/src/hooks/useAutoLend.ts @@ -40,6 +40,7 @@ export default function useAutoLend(): { const setOfAccountIds = new Set(autoLendEnabledAccountIds) if (!setOfAccountIds.has(accountId)) setOfAccountIds.add(accountId) + setAutoLendEnabledAccountIds(Array.from(setOfAccountIds)) } return { diff --git a/src/hooks/useTransactionStore.ts b/src/hooks/useTransactionStore.ts new file mode 100644 index 00000000..ef099dd0 --- /dev/null +++ b/src/hooks/useTransactionStore.ts @@ -0,0 +1,21 @@ +import { TRANSACTIONS_KEY } from 'constants/localStore' +import useLocalStorage from 'hooks/useLocalStorage' + +export default function useTransactionStore(): { + transactions: ToastStore + addTransaction: (transaction: ToastSuccess) => void +} { + const [transactions, setTransactions] = useLocalStorage(TRANSACTIONS_KEY, { + recent: [], + }) + const recentTransactions = transactions.recent + const addTransaction = (transaction: ToastSuccess) => { + recentTransactions.push(transaction) + setTransactions({ recent: recentTransactions }) + } + + return { + transactions, + addTransaction, + } +} diff --git a/src/store/slices/broadcast.ts b/src/store/slices/broadcast.ts index 470418f0..33a45694 100644 --- a/src/store/slices/broadcast.ts +++ b/src/store/slices/broadcast.ts @@ -1,4 +1,5 @@ import { MsgExecuteContract } from '@delphi-labs/shuttle-react' +import moment from 'moment' import { isMobile } from 'react-device-detect' import { GetState, SetState } from 'zustand' @@ -20,6 +21,27 @@ import { formatAmountWithSymbol } from 'utils/formatters' import getTokenOutFromSwapResponse from 'utils/getTokenOutFromSwapResponse' import { BN } from 'utils/helpers' +interface HandleResponse { + response: BroadcastResult + action: + | 'deposit' + | 'withdraw' + | 'borrow' + | 'repay' + | 'vault' + | 'lend' + | 'create' + | 'delete' + | 'claim' + | 'unlock' + | 'swap' + lend?: boolean + accountId?: string + changes?: { debts?: BNCoin[]; deposits?: BNCoin[]; lends?: BNCoin[] } + target?: 'wallet' | 'account' + message?: string +} + function generateExecutionMessage( sender: string | undefined = '', contract: string, @@ -38,28 +60,93 @@ export default function createBroadcastSlice( set: SetState, get: GetState, ): BroadcastSlice { - const handleResponseMessages = ( - response: BroadcastResult, - successMessage: string, - errorMessage?: string, - ) => { - if (response.result?.response.code === 0) { + const handleResponseMessages = (props: HandleResponse) => { + const { accountId, response, action, lend, changes, target, message } = props + + if (response.error || response.result?.response.code !== 0) { set({ toast: { - message: successMessage, - hash: response.result.hash, - }, - }) - } else { - set({ - toast: { - message: generateErrorMessage(response, errorMessage), + message: generateErrorMessage(response), isError: true, hash: response.result?.hash, }, }) + return } + + const toast: ToastResponse = { + accountId: accountId, + isError: false, + hash: response?.result?.hash, + content: [], + timestamp: moment().unix(), + address: get().address ?? '', + } + + if (message) { + toast.message = message + set({ toast }) + return + } + + if (!changes) return + + switch (action) { + case 'borrow': + const borrowCoin = changes.debts ? [changes.debts[0].toCoin()] : [] + const action = lend ? 'Borrowed and lend' : 'Borrowed' + toast.content.push({ + coins: borrowCoin, + text: target === 'wallet' ? 'Borrowed to wallet' : action, + }) + break + + case 'withdraw': + toast.content.push({ + coins: changes.deposits?.map((deposit) => deposit.toCoin()) ?? [], + text: target === 'wallet' ? 'Withdrew to Wallet' : 'Withdrew from lend', + }) + break + + case 'deposit': + toast.content.push({ + coins: changes.deposits?.map((deposit) => deposit.toCoin()) ?? [], + text: lend ? 'Deposited and lent' : 'Deposited', + }) + break + + case 'lend': + const lendCoin = changes.lends ? [changes.lends[0].toCoin()] : [] + toast.content.push({ + coins: lendCoin, + text: 'Lent', + }) + break + + case 'repay': + const repayCoin = changes.deposits ? [changes.deposits[0].toCoin()] : [] + toast.content.push({ + coins: repayCoin, + text: 'Repayed', + }) + break + + case 'vault': + toast.message = 'Add to Vault Position' + toast.content.push({ + coins: changes.debts?.map((debt) => debt.toCoin()) ?? [], + text: 'Borrowed for the Vault Position', + }) + toast.content.push({ + coins: changes.deposits?.map((deposit) => deposit.toCoin()) ?? [], + text: 'Withdrew for the Vault Position', + }) + } + + set({ toast }) + return } + const getEstimatedFee = async (messages: MsgExecuteContract[]) => { if (!get().client) { return defaultFee @@ -115,12 +202,15 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages( + handleResponseMessages({ response, - `Borrowed ${formatAmountWithSymbol(options.coin.toCoin())} to ${ - options.borrowToWallet ? 'Wallet' : `Credit Account ${options.accountId}` - }`, - ) + action: 'borrow', + lend: checkAutoLendEnabled(options.accountId), + target: options.borrowToWallet ? 'wallet' : 'account', + accountId: options.accountId, + changes: { debts: [options.coin] }, + }) + return !!response.result }, createAccount: async () => { @@ -132,25 +222,24 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - if (response.result && !response.error) { - set({ createAccountModal: false }) - const id = getSingleValueFromBroadcastResult(response.result, 'wasm', 'token_id') + set({ createAccountModal: false }) + const id = response.result + ? getSingleValueFromBroadcastResult(response.result, 'wasm', 'token_id') + : null + + handleResponseMessages({ + response, + action: 'create', + accountId: id ?? undefined, + message: id ? `Created the Credit Account` : undefined, + }) + + if (id) set({ fundAccountModal: true, - toast: { message: `Credit Account ${id} created`, hash: response.result.hash }, }) - return id - } else { - set({ - createAccountModal: false, - toast: { - message: generateErrorMessage(response), - hash: response?.result?.hash, - isError: true, - }, - }) - return null - } + + return id }, deleteAccount: async (options: { accountId: string; lends: BNCoin[] }) => { const reclaimMsg = options.lends.map((coin) => { @@ -179,7 +268,12 @@ export default function createBroadcastSlice( ], }) - handleResponseMessages(response, `Credit Account ${options.accountId} deleted`) + handleResponseMessages({ + response, + action: 'delete', + accountId: options.accountId, + message: `Deleted the Credit Account`, + }) return !!response.result }, @@ -205,9 +299,13 @@ export default function createBroadcastSlice( messages, }) - const successMessage = `Claimed rewards for, ${options.accountId}` + handleResponseMessages({ + response, + action: 'create', + accountId: options.accountId, + message: `Claimed rewards`, + }) - handleResponseMessages(response, successMessage) return !!response.result } @@ -237,15 +335,14 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, funds)], }) - const depositString = options.coins - .map((coin) => formatAmountWithSymbol(coin.toCoin())) - .join(' and ') - handleResponseMessages( + handleResponseMessages({ response, - `Deposited ${options.lend ? 'and lent ' : ''}${depositString} to Credit Account ${ - options.accountId - }`, - ) + action: 'deposit', + lend: options.lend, + accountId: options.accountId, + changes: { deposits: options.coins }, + }) + return !!response.result }, unlock: async (options: { accountId: string; vault: DepositedVault; amount: string }) => { @@ -267,7 +364,12 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages(response, `Requested unlock for ${options.vault.name}`) + handleResponseMessages({ + response, + action: 'unlock', + accountId: options.accountId, + message: `Requested unlock for ${options.vault.name}`, + }) return !!response.result }, @@ -307,13 +409,20 @@ export default function createBroadcastSlice( }) const vaultsString = options.vaults.length === 1 ? 'vault' : 'vaults' - handleResponseMessages( + handleResponseMessages({ response, - `You successfully withdrew ${options.vaults.length} unlocked ${vaultsString} to your account`, - ) + action: 'withdraw', + accountId: options.accountId, + message: `Withdrew ${options.vaults.length} unlocked ${vaultsString} to the account`, + }) return !!response.result }, - depositIntoVault: async (options: { accountId: string; actions: Action[] }) => { + depositIntoVault: async (options: { + accountId: string + actions: Action[] + deposits: BNCoin[] + borrowings: BNCoin[] + }) => { const msg: CreditManagerExecuteMsg = { update_credit_account: { account_id: options.accountId, @@ -325,7 +434,13 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages(response, `Deposited into vault`) + handleResponseMessages({ + response, + action: 'vault', + accountId: options.accountId, + changes: { deposits: options.deposits, debts: options.borrowings }, + }) + return !!response.result }, withdraw: async (options: { @@ -355,13 +470,14 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - const withdrawString = options.coins - .map(({ coin }) => formatAmountWithSymbol(coin.toCoin())) - .join('and ') - handleResponseMessages( + handleResponseMessages({ response, - `Withdrew ${withdrawString} from Credit Account ${options.accountId}`, - ) + action: 'withdraw', + target: 'wallet', + accountId: options.accountId, + changes: { deposits: options.coins.map((coin) => coin.coin) }, + }) + return !!response.result }, repay: async (options: { @@ -392,12 +508,13 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages( + handleResponseMessages({ response, - `Repayed ${formatAmountWithSymbol(options.coin.toCoin())} to Credit Account ${ - options.accountId - }`, - ) + action: 'repay', + accountId: options.accountId, + changes: { deposits: [options.coin] }, + }) + return !!response.result }, lend: async (options: { accountId: string; coin: BNCoin; isMax?: boolean }) => { @@ -416,10 +533,13 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages( + handleResponseMessages({ response, - `Successfully lent ${formatAmountWithSymbol(options.coin.toCoin())}`, - ) + action: 'lend', + accountId: options.accountId, + changes: { lends: [options.coin] }, + }) + return !!response.result }, reclaim: async (options: { accountId: string; coin: BNCoin; isMax?: boolean }) => { @@ -438,10 +558,14 @@ export default function createBroadcastSlice( messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, [])], }) - handleResponseMessages( + handleResponseMessages({ response, - `Successfully withdrew ${formatAmountWithSymbol(options.coin.toCoin())}`, - ) + action: 'withdraw', + target: 'account', + accountId: options.accountId, + changes: { deposits: [options.coin] }, + }) + return !!response.result }, swap: (options: { @@ -495,7 +619,12 @@ export default function createBroadcastSlice( options.coinIn.toCoin(), )} for ${formatAmountWithSymbol(coinOut)}` - handleResponseMessages(response, successMessage) + handleResponseMessages({ + response, + action: 'swap', + message: successMessage, + accountId: options.accountId, + }) return !!response.result } diff --git a/src/types/interfaces/store/broadcast.d.ts b/src/types/interfaces/store/broadcast.d.ts index 8735812a..88018224 100644 --- a/src/types/interfaces/store/broadcast.d.ts +++ b/src/types/interfaces/store/broadcast.d.ts @@ -11,6 +11,30 @@ interface ExecutableTx { estimateFee: () => Promise } +type ToastResponse = { + hash?: string + title?: string +} & (ToastSuccess | ToastError) + +interface ToastSuccess { + accountId?: string + content: { coins: Coin[]; text: string }[] + isError: false + message?: string + timestamp: number + address: string + hash: string +} + +interface ToastError { + message: string + isError: true +} + +interface ToastStore { + recent: ToastSuccess[] +} + interface BroadcastSlice { borrow: (options: { accountId: string @@ -21,7 +45,12 @@ interface BroadcastSlice { createAccount: () => Promise deleteAccount: (options: { accountId: string; lends: BNCoin[] }) => Promise deposit: (options: { accountId: string; coins: BNCoin[]; lend: boolean }) => Promise - depositIntoVault: (options: { accountId: string; actions: Action[] }) => Promise + depositIntoVault: (options: { + accountId: string + actions: Action[] + deposits: BNCoin[] + borrowings: BNCoin[] + }) => Promise executeMsg: (options: { messages: MsgExecuteContract[] }) => Promise lend: (options: { accountId: string; coin: BNCoin; isMax?: boolean }) => Promise reclaim: (options: { accountId: string; coin: BNCoin; isMax?: boolean }) => Promise @@ -40,7 +69,7 @@ interface BroadcastSlice { slippage: number isMax?: boolean }) => ExecutableTx - toast: { message: string; isError?: boolean; title?: string; hash?: string } | null + toast: ToastResponse | null unlock: (options: { accountId: string vault: DepositedVault diff --git a/src/utils/formatters.ts b/src/utils/formatters.ts index ba5d8c40..b7ba0518 100644 --- a/src/utils/formatters.ts +++ b/src/utils/formatters.ts @@ -1,6 +1,7 @@ import BigNumber from 'bignumber.js' import moment from 'moment' +import { ASSETS } from 'constants/assets' import { BN_ZERO } from 'constants/math' import { ORACLE_DENOM } from 'constants/oracle' import { BNCoin } from 'types/classes/BNCoin' @@ -149,12 +150,12 @@ export function formatPercent(percent: number | string, minDecimals?: number) { } export function formatAmountWithSymbol(coin: Coin) { - const marketAssets = getEnabledMarketAssets() - - const asset = marketAssets.find((asset) => asset.denom === coin.denom) + const asset = ASSETS.find((asset) => asset.denom === coin.denom) return formatValue(coin.amount, { decimals: asset?.decimals, + maxDecimals: asset?.decimals, + minDecimals: 0, suffix: ` ${asset?.symbol}`, abbreviated: true, rounded: true,