Skip to content
8 changes: 8 additions & 0 deletions public/locales/en-US/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,9 @@
"assets_maximum": "Assets Maximum",
"mptoken_metadata": "MPToken Metadata",
"withdrawal_policy": "Withdrawal Policy",
"vault_kind": "Vault Kind",
"subscription_date": "Subscription Date",
"redemption_date": "Redemption Date",
"account_creates_vault": "<Account/> created a vault for <Asset/>",
"vault_id": "Vault ID",
"single_asset_vault": "Single Asset Vault",
Expand Down Expand Up @@ -674,6 +677,8 @@
"account_clawbacks_from_vault": "<Account/> clawbacks<Amount/> from <Holder/>",
"account_clawbacks_from_vault_amount_omitted": "<Account/> clawbacks all remaining funds from <Holder/>",
"account_deletes_vault": "<Account/> deleted a vault with ID <VaultID/>",
"vault_delete_memo_data": "It sets the Vault deletion MemoData to <MemoData/>",
"memo_data": "Memo Data",
"vault_create_table_detail": "vault for <Asset/>",
"withdraws": "withdraws",
"deletes": "deletes",
Expand Down Expand Up @@ -834,6 +839,7 @@
"check_vault_id": "Please check the vault ID",
"get_vault_failed": "Unable to load vault information at this time. Please try again later.",
"private_vault": "Private Vault",
"deposits_allowed": "Deposits Allowed",
"perm_domain_id": "Permissioned Domain ID",
"total_value_locked": "Total Value Locked (TVL)",
"shares": "Shares",
Expand All @@ -844,6 +850,8 @@
"available_to_borrow": "Available to Borrow",
"not_available": "Not available",
"first_come_first_served": "First Come First Served",
"open_ended": "Open Ended",
"closed_ended": "Closed Ended",
"loans": "Loans",
"loan_broker": "Loan Broker",
"total_debt": "Total Debt",
Expand Down
3 changes: 2 additions & 1 deletion src/containers/Transactions/simpleTab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ $subdued-color: $black-40;
&.condition,
&.fulfillment,
&.tx,
&.channel {
&.channel,
&.vault-id {
width: calc(100% - 120px);
color: $subdued-color;
font-size: 14px;
Expand Down
80 changes: 71 additions & 9 deletions src/containers/Vault/VaultHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import SocketContext from '../../shared/SocketContext'
import { getMPTIssuance } from '../../../rippled/lib/rippled'
import { parseVaultWebsite } from '../utils'
import {
shortenVaultID,
shortenAccount,
getCurrencySymbol,
isCurrencyExoticSymbol,
localizeDate,
} from '../../shared/utils'
import './styles.scss'
import { useAnalytics } from '../../shared/analytics'
Expand All @@ -23,6 +22,10 @@ import { convertHexToString } from '../../../rippled/lib/utils'
import { Metadata } from '../../Token/MPT/Header/Metadata'
import Currency from '../../shared/components/Currency'
import { parseMPTokenMetadata } from '../../shared/mptUtils'
import { VAULT_KINDS } from '../../shared/vaultUtils'
import { convertRippleDate } from '../../../rippled/lib/convertRippleDate'
import { DATE_OPTIONS } from '../../shared/transactionUtils'
import { useLanguage } from '../../shared/hooks'

interface VaultData {
Owner?: string
Expand All @@ -41,6 +44,9 @@ interface VaultData {
WithdrawalPolicy?: number
Data?: string
ShareMPTID?: string
VaultKind?: number
SubscriptionDate?: number
RedemptionDate?: number
}

interface Props {
Expand All @@ -52,6 +58,8 @@ interface Props {
// Vault flags from XLS-65d spec
const VAULT_FLAGS = {
lsfVaultPrivate: 0x00010000,
lsfVaultDepositBlocked: 0x00020000,
lsfVaultOwnerCanBlockDeposit: 0x00040000,
}

// Withdrawal policy values from XLS-65d spec
Expand All @@ -61,6 +69,7 @@ const WITHDRAWAL_POLICIES: { [key: number]: string } = {

export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
const { t } = useTranslation()
const language = useLanguage()
const { trackException } = useAnalytics()
const rippledSocket = useContext(SocketContext)
const { rate: tokenToUsdRate } = useTokenToUSDRate(
Expand All @@ -80,6 +89,9 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
WithdrawalPolicy: withdrawalPolicy,
Data: vaultDataRaw,
ShareMPTID: vaultShareMptId,
VaultKind: vaultKind,
SubscriptionDate: subscriptionDate,
RedemptionDate: redemptionDate,
} = data

// Converts amount to USD if displayCurrency is 'USD', otherwise returns as-is
Expand Down Expand Up @@ -146,6 +158,11 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {

const isPrivate =
flags !== undefined && (flags & VAULT_FLAGS.lsfVaultPrivate) !== 0
const canBlockDeposit =
flags !== undefined &&
(flags & VAULT_FLAGS.lsfVaultOwnerCanBlockDeposit) !== 0
const isDepositAllowed =
flags === undefined || (flags & VAULT_FLAGS.lsfVaultDepositBlocked) === 0

const decodedData = convertHexToString(vaultDataRaw)
const vaultWebsite = parseVaultWebsite(vaultDataRaw)
Expand All @@ -158,6 +175,19 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
return t(policyKey as 'first_come_first_served')
}

const getVaultKindText = () => {
if (vaultKind === undefined) return '-'
const kindKey = VAULT_KINDS[vaultKind]
if (!kindKey) return String(vaultKind)
// Use type assertion for dynamic translation keys
return t(kindKey as 'open_ended')
}

const formatVaultDate = (date: number) =>
`${localizeDate(new Date(convertRippleDate(date)), language, DATE_OPTIONS)} ${
DATE_OPTIONS.timeZone
}`

const renderMPTSharesLink = () => {
if (!vaultShareMptId) return '-'
return (
Expand Down Expand Up @@ -185,20 +215,15 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
value={
<CopyableText
text={vaultId}
displayText={`${shortenVaultID(vaultId)}`}
displayText={vaultId}
showCopyIcon
/>
}
/>
{owner && (
<TokenTableRow
label={t('owner')}
value={
<Account
account={owner}
displayText={`${shortenAccount(owner)}`}
/>
}
value={<Account account={owner} displayText={owner} />}
/>
)}
<TokenTableRow
Expand All @@ -218,6 +243,25 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
</div>
}
/>
{canBlockDeposit && (
<TokenTableRow
label={t('deposits_allowed')}
value={
<div className="private-vault-toggle">
<span
className={`toggle-pill ${isDepositAllowed ? 'active' : ''}`}
>
{t('yes')}
</span>
<span
className={`toggle-pill ${!isDepositAllowed ? 'active' : ''}`}
>
{t('no')}
</span>
</div>
}
/>
)}
{vaultCredential && (
<TokenTableRow
label={t('perm_domain_id')}
Expand Down Expand Up @@ -262,6 +306,24 @@ export const VaultHeader = ({ data, vaultId, displayCurrency }: Props) => {
label={t('withdrawal_policy')}
value={getWithdrawalPolicyText()}
/>
{vaultKind !== undefined && (
<TokenTableRow
label={t('vault_kind')}
value={getVaultKindText()}
/>
)}
{subscriptionDate !== undefined && (
<TokenTableRow
label={t('subscription_date')}
value={formatVaultDate(subscriptionDate)}
/>
)}
{redemptionDate !== undefined && (
<TokenTableRow
label={t('redemption_date')}
value={formatVaultDate(redemptionDate)}
/>
)}
</tbody>
</table>
</div>
Expand Down
12 changes: 12 additions & 0 deletions src/containers/Vault/VaultHeader/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@
flex: 1;

.token-table {
width: 100%;
margin-top: 0;
table-layout: fixed;

// Values like Vault ID and Owner are long identifiers; let them use the
// full remaining width of the row instead of the shared table's fixed
// 230px column, wrapping only if the viewport is too narrow to fit
// them on one line.
.col2 {
display: block;
width: auto;
max-width: 100%;
}
}
}
}
Expand Down
Loading
Loading