diff --git a/src/components/Send/ShowUtxos.module.css b/src/components/Send/ShowUtxos.module.css
index 97d512a17..50bea0e8c 100644
--- a/src/components/Send/ShowUtxos.module.css
+++ b/src/components/Send/ShowUtxos.module.css
@@ -1,84 +1,36 @@
-.joinedUtxoAndCjout {
- background-color: #27ae600d !important;
- color: #27ae60 !important;
-}
-
-.frozenUtxo {
- background-color: #2d9cdb0d !important;
- color: #2d9cdb !important;
-}
-
-.depositUtxo {
- background-color: var(--bs-body-bg) !important;
- color: var(--bs-modal-color) !important;
-}
-
-.changeAndReuseUtxo {
- background-color: #eb57570d !important;
- color: #eb5757 !important;
-}
-
-.utxoTagDeposit {
- color: #999999;
- border: 1px solid #bbbbbb;
- background-color: #dedede !important;
- border-radius: 0.35rem;
- padding: 0rem 0.25rem;
-}
-
-.utxoTagJoinedAndCjout {
- border: 1px solid #27ae60;
- background-color: #c6eed7 !important;
- border-radius: 0.35rem;
- padding: 0rem 0.25rem;
-}
-
-.utxoTagFreeze {
- border: 1px solid #2d9cdb;
- background-color: #bce7ff !important;
- border-radius: 0.35rem;
- padding: 0rem 0.25rem;
+.utxoListDisplayHeight {
+ max-height: 17.6rem;
}
-.utxoTagChangeAndReuse {
- border: 1px solid #eb5757;
- background-color: #fac7c7 !important;
- border-radius: 0.35rem;
- padding: 0rem 0.25rem;
+.row.row-normal {
+ background-color: transparent !important;
}
-.squareToggleButton {
- appearance: none;
- width: 22px;
- height: 22px;
- border-radius: 3px;
- border: 1px solid var(--bs-body-color);
- margin-top: 0.45rem;
+.row.row-success {
+ background-color: #27ae600d !important;
+ color: #27ae60 !important;
}
-.selected {
- visibility: visible !important;
- background-color: var(--bs-body-color);
+.row.row-warning {
+ background-color: #bb97200d !important;
+ color: #ebc957 !important;
}
-.squareFrozenToggleButton {
- appearance: none;
- width: 22px;
- height: 22px;
- border-radius: 3px;
- border: 1px solid #2d9cdb;
- margin-top: 0.45rem;
+.row.row-danger {
+ background-color: #eb57570d !important;
+ color: #eb5757 !important;
}
-.utxoListDisplayHeight {
- max-height: 17.6rem;
+.row.row-frozen {
+ background-color: #2d9cdb0d !important;
+ color: #2d9cdb !important;
}
-.customHeaderClass {
- background-color: var(--bs-gray-800) !important;
- padding: var(--bs-modal-header-padding) !important;
+.checkbox {
+ width: 24px;
+ height: 24px;
}
-.customTitleClass {
- color: var(--bs-heading-color) !important;
+.checkbox:checked {
+ accent-color: var(--bs-black);
}
diff --git a/src/components/Send/ShowUtxos.tsx b/src/components/Send/ShowUtxos.tsx
index 8714de224..b7100ab49 100755
--- a/src/components/Send/ShowUtxos.tsx
+++ b/src/components/Send/ShowUtxos.tsx
@@ -13,7 +13,10 @@ import Balance from '../Balance'
import Divider from '../Divider'
import { BaseModal } from '../Modal'
import Sprite from '../Sprite'
-import { utxoTags } from '../jar_details/UtxoList'
+import { utxoTags } from '../utxo/utils'
+import { UtxoConfirmations } from '../utxo/Confirmations'
+import UtxoIcon from '../utxo/UtxoIcon'
+import UtxoTags from '../utxo/UtxoTags'
import { shortenStringMiddle } from '../../utils'
import styles from './ShowUtxos.module.css'
@@ -42,81 +45,15 @@ interface UtxoListDisplayProps {
showBackgroundColor: boolean
}
-// Utility function to Identifies Icons
-const utxoIcon = (tag: string, isFrozen: boolean) => {
- if (isFrozen && tag === 'bond') return 'timelock'
- if (isFrozen) return 'snowflake'
- if (tag === 'bond') return 'timelock'
- if (tag === 'cj-out') return 'mixed'
- if (tag === 'deposit' || tag === 'non-cj-change' || tag === 'reused') return 'unmixed'
- return 'unmixed' // fallback
-}
-
-// Utility function to allot classes
-const allotClasses = (tag: string, isFrozen: boolean) => {
- if (isFrozen) return { row: styles.frozenUtxo, tag: styles.utxoTagFreeze }
- if (tag === 'deposit') return { row: styles.depositUtxo, tag: styles.utxoTagDeposit }
- if (tag === 'joined' || tag === 'cj-out') return { row: styles.joinedUtxoAndCjout, tag: styles.utxoTagJoinedAndCjout }
- if (tag === 'non-cj-change' || tag === 'reused')
- return { row: styles.changeAndReuseUtxo, tag: styles.utxoTagChangeAndReuse }
- return { row: styles.depositUtxo, tag: styles.utxoTagDeposit }
-}
-
-interface ConfirmationFormat {
- symbol: string
- display: string
- confirmations: number
-}
-
-const formatConfirmations = (confirmations: number): ConfirmationFormat => ({
- symbol: `confs-${confirmations >= 6 ? 'full' : confirmations}`,
- display: confirmations > 9999 ? `${Number(9999).toLocaleString()}+` : confirmations.toLocaleString(),
- confirmations,
-})
-
-const Confirmations = ({ value }: { value: ConfirmationFormat }) =>
- value.confirmations > 9999 ? (
- {value.confirmations.toLocaleString()}}
- >
-
-
- {value.display}
-
-
- ) : (
-
-
- {value.display}
-
- )
-
const UtxoRow = ({ utxo, onToggle, showBackgroundColor, settings, walletInfo, t }: UtxoRowProps) => {
- const address = useMemo(() => shortenStringMiddle(utxo.address, 16), [utxo.address])
- const confFormat = useMemo(() => formatConfirmations(utxo.confirmations), [utxo.confirmations])
- const tag = useMemo(() => utxoTags(utxo, walletInfo, t), [utxo, walletInfo, t])
-
- const { icon, rowAndTagClass } = useMemo(() => {
- if (tag.length === 0) {
- return { icon: 'unmixed', rowAndTagClass: { row: styles.depositUtxo, tag: styles.utxoTagDeposit } }
- }
- return { icon: utxoIcon(tag[0].tag, utxo.frozen), rowAndTagClass: allotClasses(tag[0].tag, utxo.frozen) }
- }, [tag, utxo.frozen])
+ const displayAddress = useMemo(() => shortenStringMiddle(utxo.address, 24), [utxo.address])
+ const tags = useMemo(() => utxoTags(utxo, walletInfo, t), [utxo, walletInfo, t])
return (
{utxo.selectable && (
- utxo.selectable && onToggle(utxo)}
- className={classNames(utxo.frozen ? styles.squareFrozenToggleButton : styles.squareToggleButton, {
- [styles.selected]: utxo.checked,
- })}
- />
+
+ utxo.selectable && onToggle(utxo)}
+ className={styles.checkbox}
+ />
+
)}
|
-
+
+ |
+
+ (
+
+ {utxo.address}
+
+ )}
+ >
+ {displayAddress}
+
|
- {address} |
-
+
|
|
- {tag.length ? tag[0].tag : ''}
+
|
)
}
-type SelectableUtxoTableRowData = SelectableUtxo & {
- // TODO: add "tags" here and remove from "Utxo" type
- // tags?: { tag: string; color: string }[]
-} & Pick
+type SelectableUtxoTableRowData = SelectableUtxo & Pick
const UtxoListDisplay = ({ utxos, onToggle, settings, showBackgroundColor = true }: UtxoListDisplayProps) => {
const { t } = useTranslation()
@@ -172,14 +116,16 @@ const UtxoListDisplay = ({ utxos, onToggle, settings, showBackgroundColor = true
const TABLE_THEME = {
Table: `
- --data-table-library_grid-template-columns: 3.5rem 2.5rem 12rem 2fr 3fr 10rem;
- @media only screen and (min-width: 768px) {
- --data-table-library_grid-template-columns: 3.5rem 2.5rem 14rem 5fr 3fr 10rem};
- }
+ --data-table-library_grid-template-columns: 2.5rem 2.5rem 17rem 3rem 12rem 1fr};
`,
BaseCell: `
padding: 0.35rem 0.25rem !important;
margin: 0.15rem 0px !important;
+ `,
+ Cell: `
+ &:nth-of-type(5) {
+ text-align: right;
+ }
`,
}
const tableTheme = useTheme(TABLE_THEME)
@@ -265,8 +211,8 @@ const ShowUtxos = ({ isOpen, onCancel, onConfirm, isLoading, utxos, alert }: Sho
backdrop={true}
title={t('show_utxos.show_utxo_title')}
closeButton
- headerClassName={styles.customHeaderClass}
- titleClassName={styles.customTitleClass}
+ headerClassName=""
+ titleClassName=""
>
{isLoading ? (
diff --git a/src/components/jar_details/UtxoList.module.css b/src/components/jar_details/UtxoList.module.css
index 81a0d1648..79a0f6f05 100644
--- a/src/components/jar_details/UtxoList.module.css
+++ b/src/components/jar_details/UtxoList.module.css
@@ -7,10 +7,6 @@
margin-bottom: 1px;
}
-.utxoList .utxoIcon > .iconFrozen {
- margin-bottom: 1px;
-}
-
.utxoList tr.frozen td {
--bs-code-color: var(--bs-blue);
color: var(--bs-blue);
@@ -36,65 +32,6 @@
display: none !important;
}
-.utxoList .utxoIcon > .iconLocked {
- margin-bottom: 3px;
-}
-
-.utxoList .utxoTagList {
- display: flex;
- gap: 0.5rem;
- color: var(--bs-body-color);
-}
-
-.utxoList .utxoConfirmations {
- width: 2rem;
- display: flex;
- gap: 0.1rem;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- padding: 0.1rem 0.2rem;
- border-radius: 0.2rem;
- color: var(--bs-success);
- font-size: 0.6rem;
-}
-
-.utxoList .utxoConfirmations-0 {
- color: var(--bs-info);
-}
-
-.utxoList .utxoTagList > .utxoTag {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 0.3rem;
- font-size: 0.7rem;
- border: 1px solid var(--bs-body-color);
- border-radius: 0.2rem;
- padding: 0.1rem 0.3rem;
-}
-
-.utxoList .utxoTagList > .utxoTag.utxoTag-success {
- color: var(--bs-success);
- background-color: rgba(var(--bs-success-rgb), 0.1);
- border-color: var(--bs-success);
-}
-.utxoList .utxoTagList > .utxoTag.utxoTag-warning {
- color: var(--bs-warning);
- background-color: rgba(var(--bs-warning-rgb), 0.1);
- border-color: var(--bs-warning);
-}
-.utxoList .utxoTagList > .utxoTag.utxoTag-danger {
- color: var(--bs-danger);
- background-color: rgba(var(--bs-danger-rgb), 0.1);
- border-color: var(--bs-danger);
-}
-.utxoList .utxoTagList > .utxoTag.utxoTag-dark {
- color: var(--bs-white);
- background-color: var(--bs-dark);
- border-color: var(--bs-dark);
-}
-
.utxoList .utxoListButtonDetails {
font-size: 0.9rem;
}
diff --git a/src/components/jar_details/UtxoList.tsx b/src/components/jar_details/UtxoList.tsx
index e782f0800..891ab4330 100644
--- a/src/components/jar_details/UtxoList.tsx
+++ b/src/components/jar_details/UtxoList.tsx
@@ -2,7 +2,6 @@ import { useMemo } from 'react'
import * as rb from 'react-bootstrap'
import classNames from 'classnames'
import { useTranslation } from 'react-i18next'
-import { TFunction } from 'i18next'
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'
import { usePagination } from '@table-library/react-table-library/pagination'
import { useRowSelect, HeaderCellSelect, CellSelect, SelectTypes } from '@table-library/react-table-library/select'
@@ -13,11 +12,15 @@ import { useTheme } from '@table-library/react-table-library/theme'
import { useSettings } from '../../context/SettingsContext'
import { Utxo, WalletInfo } from '../../context/WalletContext'
import * as fb from '../fb/utils'
+import { utxoTags, UtxoTag } from '../utxo/utils'
import { shortenStringMiddle } from '../../utils'
import Sprite from '../Sprite'
import Balance from '../Balance'
import TablePagination from '../TablePagination'
import styles from './UtxoList.module.css'
+import UtxoIcon from '../utxo/UtxoIcon'
+import { UtxoConfirmations } from '../utxo/Confirmations'
+import UtxoTags from '../utxo/UtxoTags'
const withTooltip = ({ node, tooltip }: { node: React.ReactElement; tooltip: React.ReactElement }) => {
return (
@@ -25,74 +28,6 @@ const withTooltip = ({ node, tooltip }: { node: React.ReactElement; tooltip: Rea
)
}
-const ADDRESS_STATUS_COLORS: { [key: string]: string } = {
- new: 'normal',
- used: 'normal',
- reused: 'danger',
- 'cj-out': 'success',
- 'change-out': 'warning',
- 'non-cj-change': 'normal',
- deposit: 'normal',
-}
-
-type Tag = { tag: string; color: string }
-
-export const utxoTags = (utxo: Utxo, walletInfo: WalletInfo, t: TFunction): Tag[] => {
- const rawStatus = walletInfo.addressSummary[utxo.address]?.status
-
- let status: string | null = null
-
- // If a UTXO is locked, it's `status` will be the locktime, with other states
- // appended in brackets, e.g. `2099-12-01 [LOCKED] [FROZEN]`
- if (rawStatus && !utxo.locktime) {
- const indexOfOtherTag = rawStatus.indexOf('[')
-
- if (indexOfOtherTag !== -1) {
- status = rawStatus.substring(0, indexOfOtherTag).trim()
- } else {
- status = rawStatus
- }
- }
-
- const tags: Tag[] = []
-
- if (utxo.label) tags.push({ tag: utxo.label, color: 'normal' })
- if (status) tags.push({ tag: status, color: ADDRESS_STATUS_COLORS[status] || 'normal' })
- if (fb.utxo.isFidelityBond(utxo)) tags.push({ tag: t('jar_details.utxo_list.utxo_tag_fb'), color: 'dark' })
- return tags
-}
-
-const utxoIcon = (utxo: Utxo, t: TFunction) => {
- if (fb.utxo.isFidelityBond(utxo)) {
- return withTooltip({
- node: (
-
-
-
- ),
- tooltip: {t('jar_details.utxo_list.utxo_tooltip_locktime', { locktime: utxo.locktime })}
,
- })
- } else if (utxo.frozen) {
- return (
-
-
-
- )
- }
- return <>>
-}
-
-const utxoConfirmations = (utxo: Utxo) => {
- const symbol = `confs-${utxo.confirmations >= 6 ? 'full' : utxo.confirmations}`
-
- return (
-
-
-
{utxo.confirmations}
-
- )
-}
-
const SORT_KEYS = {
frozenOrLocked: 'FROZEN_OR_LOCKED',
value: 'VALUE',
@@ -158,7 +93,7 @@ const toUtxo = (tableNode: TableTypes.TableNode): Utxo => {
interface UtxoTableRow extends Utxo, TableTypes.TableNode {
_icon: JSX.Element
- _tags: Tag[]
+ _tags: UtxoTag[]
_confs: JSX.Element
}
@@ -187,9 +122,9 @@ const UtxoList = ({
nodes: utxos.map((utxo: Utxo) => ({
...utxo,
id: utxo.utxo,
- _icon: utxoIcon(utxo, t),
+ _icon: ,
_tags: utxoTags(utxo, walletInfo, t),
- _confs: utxoConfirmations(utxo),
+ _confs: ,
})),
}),
[utxos, walletInfo, t],
@@ -254,7 +189,9 @@ const UtxoList = ({
[SORT_KEYS.value]: (array) => array.sort((a, b) => a.value - b.value),
[SORT_KEYS.confirmations]: (array) => array.sort((a, b) => a.confirmations - b.confirmations),
[SORT_KEYS.tags]: (array) =>
- array.sort((a, b) => (String(a._tags[0]?.tag) || 'z').localeCompare(String(b._tags[0]?.tag) || 'z')),
+ array.sort((a, b) =>
+ (String(a._tags[0]?.displayValue) || 'z').localeCompare(String(b._tags[0]?.displayValue) || 'z'),
+ ),
},
},
)
@@ -327,6 +264,7 @@ const UtxoList = ({
convertToUnit={settings.unit}
showBalance={settings.showBalance}
frozen={item.frozen}
+ colored={!item.locktime}
/>
@@ -348,13 +286,7 @@ const UtxoList = ({
|
{item._confs} |
-
- {item._tags.map((tag: Tag, index: number) => (
-
- {tag.tag}
-
- ))}
-
+
|
({
+ symbol: `confs-${confirmations >= 6 ? 'full' : confirmations}`,
+ display: confirmations > 9999 ? `${Number(9999).toLocaleString()}+` : confirmations.toLocaleString(),
+ tooltip: confirmations > 9999 ? confirmations.toLocaleString() : undefined,
+ confirmations,
+})
+
+export function Confirmations({ className, value }: { className?: string; value: ConfirmationFormat }) {
+ return value.tooltip !== undefined ? (
+ {value.tooltip}}
+ >
+
+
+ ) : (
+
+ )
+}
+
+export function UtxoConfirmations({ className, value }: { className?: string; value: Utxo }) {
+ return
+}
diff --git a/src/components/utxo/UtxoIcon.module.css b/src/components/utxo/UtxoIcon.module.css
new file mode 100644
index 000000000..23ad93d30
--- /dev/null
+++ b/src/components/utxo/UtxoIcon.module.css
@@ -0,0 +1,5 @@
+.utxoIcon {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
diff --git a/src/components/utxo/UtxoIcon.tsx b/src/components/utxo/UtxoIcon.tsx
new file mode 100644
index 000000000..af3458668
--- /dev/null
+++ b/src/components/utxo/UtxoIcon.tsx
@@ -0,0 +1,59 @@
+import { PropsWithChildren, useMemo } from 'react'
+import * as rb from 'react-bootstrap'
+import { useTranslation } from 'react-i18next'
+import { Utxo } from '../../context/WalletContext'
+import * as fb from '../fb/utils'
+import { UtxoTag, UtxoStatus } from './utils'
+import Sprite from '../Sprite'
+import styles from './UtxoIcon.module.css'
+
+const toIcon = (utxo: Utxo, tags?: UtxoStatus[]) => {
+ if (fb.utxo.isFidelityBond(utxo)) return 'timelock'
+ if (utxo.frozen) return 'snowflake'
+ if (tags?.includes('cj-out')) return 'mixed'
+ if (tags) return 'unmixed'
+ return undefined
+}
+
+function LockedIconTooltip({ utxo, children }: PropsWithChildren<{ utxo: Utxo }>) {
+ const { t } = useTranslation()
+
+ return (
+ (
+
+ {t('jar_details.utxo_list.utxo_tooltip_locktime', { locktime: utxo.locktime })}
+
+ )}
+ >
+ {children}
+
+ )
+}
+
+interface UtxoIconProps {
+ value: Utxo
+ tags?: UtxoTag[]
+ size?: 20 | 24
+}
+
+export default function UtxoIcon({ value, tags, size = 24 }: UtxoIconProps) {
+ const symbol = useMemo(
+ () =>
+ toIcon(
+ value,
+ tags?.map((it) => it.value),
+ ),
+ [value, tags],
+ )
+
+ const element = (
+ {symbol && }
+ )
+
+ if (fb.utxo.isFidelityBond(value)) {
+ return {element}
+ }
+
+ return element
+}
diff --git a/src/components/utxo/UtxoTags.module.css b/src/components/utxo/UtxoTags.module.css
new file mode 100644
index 000000000..6bffdd1fb
--- /dev/null
+++ b/src/components/utxo/UtxoTags.module.css
@@ -0,0 +1,37 @@
+.utxoTagList {
+ display: flex;
+ gap: 0.5rem;
+ color: var(--bs-body-color);
+}
+
+.utxoTagList > .utxoTag {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.7rem;
+ border: 1px solid var(--bs-body-color);
+ border-radius: 0.2rem;
+ padding: 0.1rem 0.3rem;
+}
+
+.utxoTagList > .utxoTag.utxoTag-success {
+ color: var(--bs-success);
+ background-color: rgba(var(--bs-success-rgb), 0.1);
+ border-color: var(--bs-success);
+}
+.utxoTagList > .utxoTag.utxoTag-warning {
+ color: var(--bs-warning);
+ background-color: rgba(var(--bs-warning-rgb), 0.1);
+ border-color: var(--bs-warning);
+}
+.utxoTagList > .utxoTag.utxoTag-danger {
+ color: var(--bs-danger);
+ background-color: rgba(var(--bs-danger-rgb), 0.1);
+ border-color: var(--bs-danger);
+}
+.utxoTagList > .utxoTag.utxoTag-dark {
+ color: var(--bs-white);
+ background-color: var(--bs-dark);
+ border-color: var(--bs-dark);
+}
diff --git a/src/components/utxo/UtxoTags.tsx b/src/components/utxo/UtxoTags.tsx
new file mode 100644
index 000000000..a0ad39864
--- /dev/null
+++ b/src/components/utxo/UtxoTags.tsx
@@ -0,0 +1,19 @@
+import classNames from 'classnames'
+import { UtxoTag } from '../utxo/utils'
+import styles from './UtxoTags.module.css'
+
+interface UtxoTagsProps {
+ value: UtxoTag[]
+}
+
+export default function UtxoTags({ value }: UtxoTagsProps) {
+ return (
+
+ {value.map((tag: UtxoTag, index: number) => (
+
+ {tag.displayValue}
+
+ ))}
+
+ )
+}
diff --git a/src/components/utxo/utils.ts b/src/components/utxo/utils.ts
new file mode 100644
index 000000000..32b46c075
--- /dev/null
+++ b/src/components/utxo/utils.ts
@@ -0,0 +1,44 @@
+import { TFunction } from 'i18next'
+import { Utxo, WalletInfo } from '../../context/WalletContext'
+import * as fb from '../fb/utils'
+
+export type UtxoStatus = 'new' | 'used' | 'reused' | 'cj-out' | 'non-cj-change' | 'change-out' | 'deposit' | string
+
+const UTXO_STATUS_COLORS: { [key in UtxoStatus]: string } = {
+ new: 'normal',
+ used: 'normal',
+ reused: 'danger',
+ 'cj-out': 'success',
+ 'change-out': 'warning',
+ 'non-cj-change': 'warning',
+ deposit: 'normal',
+}
+
+export type UtxoTag = { value: UtxoStatus; displayValue: string; color: string }
+
+export const utxoTags = (utxo: Utxo, walletInfo: WalletInfo, t: TFunction): UtxoTag[] => {
+ const rawStatus = walletInfo.addressSummary[utxo.address]?.status
+
+ let status: string | null = null
+
+ // If a UTXO is locked, it's `status` will be the locktime, with other states
+ // appended in brackets, e.g. `2099-12-01 [LOCKED] [FROZEN]`
+ // other possible values include `cj-out`, `reused [FROZEN]`, etc.
+ if (rawStatus && !utxo.locktime) {
+ const indexOfOtherTag = rawStatus.indexOf('[')
+
+ if (indexOfOtherTag !== -1) {
+ status = rawStatus.substring(0, indexOfOtherTag).trim()
+ } else {
+ status = rawStatus
+ }
+ }
+
+ const tags: UtxoTag[] = []
+
+ if (fb.utxo.isFidelityBond(utxo))
+ tags.push({ value: 'bond', displayValue: t('jar_details.utxo_list.utxo_tag_fb'), color: 'dark' })
+ if (status) tags.push({ value: status, displayValue: status, color: UTXO_STATUS_COLORS[status] || 'normal' })
+ if (utxo.label) tags.push({ value: utxo.label, displayValue: utxo.label, color: 'normal' })
+ return tags
+}
diff --git a/src/context/WalletContext.tsx b/src/context/WalletContext.tsx
index 080df1ae4..5bfce6abc 100644
--- a/src/context/WalletContext.tsx
+++ b/src/context/WalletContext.tsx
@@ -53,8 +53,6 @@ export type Utxo = {
// `locktime` in format "yyyy-MM-dd 00:00:00"
// NOTE: it is unparsable with safari Date constructor
locktime?: string
- // TODO: remove 'tags' prop
- tags?: { tag: string; color: string }[]
}
export type Utxos = Utxo[]
|