Skip to content

Commit 15cc8a1

Browse files
feat: support asset freeze transaction (#33)
* feat: show asset freeze transactions --------- Co-authored-by: Neil Campbell <[email protected]>
1 parent 4f8448e commit 15cc8a1

19 files changed

+410
-32
lines changed

src/features/accounts/components/account-link.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { cn } from '@/features/common/utils'
2+
import { TemplatedNavLink } from '@/features/routing/components/templated-nav-link/templated-nav-link'
3+
import { Urls } from '@/routes/urls'
24
import { ellipseAddress } from '@/utils/ellipse-address'
35
import { PropsWithChildren } from 'react'
46

@@ -10,8 +12,12 @@ type Props = PropsWithChildren<{
1012

1113
export function AccountLink({ address, short, className, children }: Props) {
1214
return (
13-
<a href="#" className={cn(!children && 'text-primary underline', className)}>
15+
<TemplatedNavLink
16+
className={cn(!children && 'text-primary underline', className)}
17+
urlTemplate={Urls.Explore.Account.ById}
18+
urlParams={{ address }}
19+
>
1420
{children ? children : short ? ellipseAddress(address) : address}
15-
</a>
21+
</TemplatedNavLink>
1622
)
1723
}

src/features/blocks/components/transactions.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const columns: ColumnDef<Transaction>[] = [
3232
return ellipseAddress(transaction.receiver)
3333
if (transaction.type === TransactionType.ApplicationCall) return transaction.applicationId
3434
if (transaction.type === TransactionType.AssetConfig) return transaction.assetId
35+
if (transaction.type === TransactionType.AssetFreeze) return transaction.assetId
3536
},
3637
},
3738
{

src/features/transactions/components/app-call-transaction-info.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { DataTable } from '@/features/common/components/data-table'
77
import { transactionSenderLabel } from './transaction-view-table'
88
import { DescriptionList } from '@/features/common/components/description-list'
99
import { ellipseAddress } from '@/utils/ellipse-address'
10+
import { AccountLink } from '@/features/accounts/components/account-link'
1011

1112
type Props = {
1213
transaction: AppCallTransaction | InnerAppCallTransaction
@@ -36,11 +37,7 @@ export function AppCallTransactionInfo({ transaction }: Props) {
3637
() => [
3738
{
3839
dt: transactionSenderLabel,
39-
dd: (
40-
<a href="#" className={cn('text-primary underline')}>
41-
{transaction.sender}
42-
</a>
43-
),
40+
dd: <AccountLink address={transaction.sender}></AccountLink>,
4441
},
4542
{
4643
dt: applicationIdLabel,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Card, CardContent } from '@/features/common/components/card'
2+
import { cn } from '@/features/common/utils'
3+
import { TransactionInfo } from './transaction-info'
4+
import { TransactionNote } from './transaction-note'
5+
import { TransactionJson } from './transaction-json'
6+
import { AssetFreezeTransaction, InnerAssetFreezeTransaction, SignatureType } from '../models'
7+
import { MultisigDetails } from './multisig-details'
8+
import { LogicsigDetails } from './logicsig-details'
9+
import { AssetFreezeTransactionInfo } from './asset-freeze-transaction-info'
10+
import { TransactionViewTabs } from './transaction-view-tabs'
11+
12+
type AssetFreezeTransactionProps = {
13+
transaction: AssetFreezeTransaction | InnerAssetFreezeTransaction
14+
}
15+
16+
export function AssetFreezeTransactionDetails({ transaction }: AssetFreezeTransactionProps) {
17+
return (
18+
<div className={cn('space-y-6 pt-7')}>
19+
<TransactionInfo transaction={transaction} />
20+
<Card className={cn('p-4')}>
21+
<CardContent className={cn('text-sm space-y-4')}>
22+
<AssetFreezeTransactionInfo transaction={transaction} />
23+
<TransactionViewTabs transaction={transaction} />
24+
{transaction.note && <TransactionNote note={transaction.note} />}
25+
<TransactionJson json={transaction.json} />
26+
{transaction.signature?.type === SignatureType.Multi && <MultisigDetails signature={transaction.signature} />}
27+
{transaction.signature?.type === SignatureType.Logic && <LogicsigDetails signature={transaction.signature} />}
28+
</CardContent>
29+
</Card>
30+
</div>
31+
)
32+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { cn } from '@/features/common/utils'
2+
import { useMemo } from 'react'
3+
import { AssetFreezeTransaction, InnerAssetFreezeTransaction } from '../models'
4+
import { DescriptionList } from '@/features/common/components/description-list'
5+
import { transactionSenderLabel } from './transaction-view-table'
6+
import { AccountLink } from '@/features/accounts/components/account-link'
7+
8+
type Props = {
9+
transaction: AssetFreezeTransaction | InnerAssetFreezeTransaction
10+
}
11+
12+
export const assetLabel = 'Asset'
13+
export const assetFreezeAddressLabel = 'Freeze Address'
14+
export const assetFreezeStatusLabel = 'Freeze Status'
15+
16+
export function AssetFreezeTransactionInfo({ transaction }: Props) {
17+
const items = useMemo(
18+
() => [
19+
{
20+
dt: transactionSenderLabel,
21+
dd: <AccountLink address={transaction.sender}></AccountLink>,
22+
},
23+
{
24+
dt: assetLabel,
25+
dd: (
26+
<a href="#" className={cn('text-primary underline')}>
27+
{transaction.assetId}
28+
{`${transaction.assetName ? `(${transaction.assetName})` : ''}`}
29+
</a>
30+
),
31+
},
32+
{
33+
dt: assetFreezeAddressLabel,
34+
dd: <AccountLink address={transaction.address}></AccountLink>,
35+
},
36+
{
37+
dt: assetFreezeStatusLabel,
38+
dd: transaction.freezeStatus,
39+
},
40+
],
41+
[transaction.address, transaction.assetId, transaction.assetName, transaction.freezeStatus, transaction.sender]
42+
)
43+
44+
return (
45+
<div className={cn('space-y-2')}>
46+
<div className={cn('flex items-center justify-between')}>
47+
<h1 className={cn('text-2xl text-primary font-bold')}>Asset Freeze</h1>
48+
</div>
49+
<DescriptionList items={items} />
50+
</div>
51+
)
52+
}

src/features/transactions/components/asset-transfer-transaction-info.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { AssetTransferTransaction, AssetTransferTransactionSubType, InnerAssetTr
44
import { DescriptionList } from '@/features/common/components/description-list'
55
import { transactionSenderLabel, transactionReceiverLabel, transactionAmountLabel } from './transaction-view-table'
66
import { DisplayAssetAmount } from '@/features/common/components/display-asset-amount'
7+
import { AccountLink } from '@/features/accounts/components/account-link'
78

89
type Props = {
910
transaction: AssetTransferTransaction | InnerAssetTransferTransaction
@@ -19,11 +20,7 @@ export function AssetTransferTransactionInfo({ transaction }: Props) {
1920
() => [
2021
{
2122
dt: transactionSenderLabel,
22-
dd: (
23-
<a href="#" className={cn('text-primary underline')}>
24-
{transaction.sender}
25-
</a>
26-
),
23+
dd: <AccountLink address={transaction.sender}></AccountLink>,
2724
},
2825
{
2926
dt: transactionReceiverLabel,

src/features/transactions/components/payment-transaction-info.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useMemo } from 'react'
44
import { InnerPaymentTransaction, PaymentTransaction } from '../models'
55
import { transactionAmountLabel, transactionReceiverLabel, transactionSenderLabel } from './transaction-view-table'
66
import { DescriptionList } from '@/features/common/components/description-list'
7+
import { AccountLink } from '@/features/accounts/components/account-link'
78

89
type Props = {
910
transaction: PaymentTransaction | InnerPaymentTransaction
@@ -17,11 +18,7 @@ export function PaymentTransactionInfo({ transaction }: Props) {
1718
() => [
1819
{
1920
dt: transactionSenderLabel,
20-
dd: (
21-
<a href="#" className={cn('text-primary underline')}>
22-
{transaction.sender}
23-
</a>
24-
),
21+
dd: <AccountLink address={transaction.sender}></AccountLink>,
2522
},
2623
{
2724
dt: transactionReceiverLabel,

src/features/transactions/components/transaction-details.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AssetTranserTransactionDetails } from './asset-transfer-transaction-det
33
import { InnerTransaction, Transaction, TransactionType } from '../models'
44
import { AppCallTransactionDetails } from './app-call-transaction-details'
55
import { AssetConfigTransactionDetails } from './asset-config-transaction-details'
6+
import { AssetFreezeTransactionDetails } from './asset-freeze-transaction-details'
67

78
type Props = {
89
transaction: Transaction | InnerTransaction
@@ -18,6 +19,8 @@ export function TransactionDetails({ transaction }: Props) {
1819
return <AppCallTransactionDetails transaction={transaction} />
1920
case TransactionType.AssetConfig:
2021
return <AssetConfigTransactionDetails transaction={transaction} />
22+
case TransactionType.AssetFreeze:
23+
return <AssetFreezeTransactionDetails transaction={transaction} />
2124
default:
2225
return <></>
2326
}

src/features/transactions/components/transaction-view-table.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const tableColumns: ColumnDef<FlattenedTransaction>[] = [
5656
if (transaction.type === TransactionType.Payment || transaction.type === TransactionType.AssetTransfer)
5757
return ellipseAddress(transaction.receiver)
5858
if (transaction.type === TransactionType.ApplicationCall) return transaction.applicationId
59+
if (transaction.type === TransactionType.AssetConfig || transaction.type === TransactionType.AssetFreeze) return transaction.assetId
5960
},
6061
},
6162
{

src/features/transactions/components/transaction-view-visual.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import { useMemo } from 'react'
99
import {
1010
AppCallTransaction,
1111
AssetConfigTransaction,
12+
AssetFreezeTransaction,
1213
AssetTransferTransaction,
1314
InnerAppCallTransaction,
1415
InnerAssetConfigTransaction,
16+
InnerAssetFreezeTransaction,
1517
InnerAssetTransferTransaction,
1618
InnerPaymentTransaction,
1719
InnerTransaction,
@@ -29,6 +31,7 @@ import { transactionAmountLabel, transactionReceiverLabel, transactionSenderLabe
2931
import { DisplayAssetAmount } from '@/features/common/components/display-asset-amount'
3032
import { InnerTransactionLink } from './inner-transaction-link'
3133
import { assetIdLabel } from './asset-config-transaction-info'
34+
import { assetFreezeAddressLabel, assetFreezeStatusLabel } from './asset-freeze-transaction-info'
3235

3336
const graphConfig = {
3437
rowHeight: 40,
@@ -180,6 +183,7 @@ const DisplayArrow = fixedForwardRef(
180183
)}
181184
{transaction.type === TransactionType.ApplicationCall && <>App Call</>}
182185
{transaction.type === TransactionType.AssetConfig && <>Asset Config</>}
186+
{transaction.type === TransactionType.AssetFreeze && <>Asset Freeze</>}
183187
</div>
184188

185189
<SvgCircle width={graphConfig.circleDimension} height={graphConfig.circleDimension}></SvgCircle>
@@ -370,6 +374,44 @@ function AssetConfigTransactionToolTipContent({ transaction }: { transaction: As
370374
)
371375
}
372376

377+
function AssetFreezeTransactionToolTipContent({ transaction }: { transaction: AssetFreezeTransaction | InnerAssetFreezeTransaction }) {
378+
const items = useMemo(
379+
() => [
380+
{
381+
dt: transactionIdLabel,
382+
dd: transaction.id,
383+
},
384+
{
385+
dt: transactionTypeLabel,
386+
dd: TransactionType.AssetFreeze,
387+
},
388+
{
389+
dt: transactionSenderLabel,
390+
dd: transaction.sender,
391+
},
392+
{
393+
dt: assetIdLabel,
394+
dd: transaction.assetId,
395+
},
396+
{
397+
dt: assetFreezeAddressLabel,
398+
dd: transaction.address,
399+
},
400+
{
401+
dt: assetFreezeStatusLabel,
402+
dd: transaction.freezeStatus,
403+
},
404+
],
405+
[transaction.address, transaction.assetId, transaction.freezeStatus, transaction.id, transaction.sender]
406+
)
407+
408+
return (
409+
<div className={cn('p-4')}>
410+
<DescriptionList items={items} />
411+
</div>
412+
)
413+
}
414+
373415
type TransactionRowProps = {
374416
transaction: Transaction | InnerTransaction
375417
hasParent?: boolean
@@ -421,6 +463,7 @@ function TransactionRow({
421463
{transaction.type === TransactionType.AssetTransfer && <AssetTransferTransactionToolTipContent transaction={transaction} />}
422464
{transaction.type === TransactionType.ApplicationCall && <AppCallTransactionToolTipContent transaction={transaction} />}
423465
{transaction.type === TransactionType.AssetConfig && <AssetConfigTransactionToolTipContent transaction={transaction} />}
466+
{transaction.type === TransactionType.AssetFreeze && <AssetFreezeTransactionToolTipContent transaction={transaction} />}
424467
</TooltipContent>
425468
</Tooltip>
426469
)
@@ -457,6 +500,10 @@ function calcArrow(transaction: Transaction | InnerTransaction, collaborators: C
457500
return collaborators.findIndex((a) => transaction.assetId.toString() === a.id)
458501
}
459502

503+
if (transaction.type === TransactionType.AssetFreeze) {
504+
return collaborators.findIndex((a) => transaction.assetId.toString() === a.id)
505+
}
506+
460507
throw new Error('Not supported transaction type')
461508
}
462509

@@ -576,6 +623,12 @@ const getTransactionCollaborators = (transaction: Transaction | InnerTransaction
576623
id: transaction.assetId.toString(),
577624
})
578625
}
626+
if (transaction.type === TransactionType.AssetFreeze) {
627+
collaborators.push({
628+
type: 'Asset',
629+
id: transaction.assetId.toString(),
630+
})
631+
}
579632
return collaborators
580633
}
581634

0 commit comments

Comments
 (0)