Skip to content

Commit 4669b29

Browse files
authored
Rekey badge for transactions (#75)
* feat: add rekey badge to transaction page
1 parent 3c8ba3d commit 4669b29

File tree

6 files changed

+87
-11
lines changed

6 files changed

+87
-11
lines changed

src/features/blocks/data/latest-blocks.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,21 +141,15 @@ const subscribeToBlocksEffect = atomEffect((get, set) => {
141141
})
142142
.map((bc) => bc.address)
143143
.filter(distinct((x) => x)) ?? []
144-
const addressesStaleDueToAppChanges = flattenTransactionResult(t)
144+
145+
const addressesStaleDueToTransactions = flattenTransactionResult(t)
145146
.filter((t) => {
146-
if (t['tx-type'] !== algosdk.TransactionType.appl) {
147-
return false
148-
}
149-
const appCallTransaction = t['application-transaction']!
150-
const isAppCreate =
151-
appCallTransaction['on-completion'] === ApplicationOnComplete.noop && !appCallTransaction['application-id']
152-
const isAppOptIn =
153-
appCallTransaction['on-completion'] === ApplicationOnComplete.optin && appCallTransaction['application-id']
154-
return isAppCreate || isAppOptIn
147+
const accountIsStaleDueToRekey = t['rekey-to']
148+
return accountIsStaleDueToAppChanges(t) || accountIsStaleDueToRekey
155149
})
156150
.map((t) => t.sender)
157151
.filter(distinct((x) => x))
158-
const staleAddresses = Array.from(new Set(addressesStaleDueToBalanceChanges.concat(addressesStaleDueToAppChanges)))
152+
const staleAddresses = Array.from(new Set(addressesStaleDueToBalanceChanges.concat(addressesStaleDueToTransactions)))
159153
acc[4].push(...staleAddresses)
160154

161155
// Accumulate stale application ids
@@ -256,3 +250,13 @@ const subscribeToBlocksEffect = atomEffect((get, set) => {
256250
export const useSubscribeToBlocksEffect = () => {
257251
useAtom(subscribeToBlocksEffect)
258252
}
253+
254+
const accountIsStaleDueToAppChanges = (txn: TransactionResult) => {
255+
if (txn['tx-type'] !== algosdk.TransactionType.appl) {
256+
return false
257+
}
258+
const appCallTransaction = txn['application-transaction']!
259+
const isAppCreate = appCallTransaction['on-completion'] === ApplicationOnComplete.noop && !appCallTransaction['application-id']
260+
const isAppOptIn = appCallTransaction['on-completion'] === ApplicationOnComplete.optin && appCallTransaction['application-id']
261+
return isAppCreate || isAppOptIn
262+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Badge } from '@/features/common/components/badge'
99
import { BlockLink } from '@/features/blocks/components/block-link'
1010
import { GroupLink } from '@/features/groups/components/group-link'
1111
import { useAtomValue } from 'jotai'
12+
import { AccountLink } from '@/features/accounts/components/account-link'
1213

1314
type Props = {
1415
transaction: Transaction | InnerTransaction
@@ -20,6 +21,7 @@ export const transactionTimestampLabel = 'Timestamp'
2021
export const transactionBlockLabel = 'Block'
2122
export const transactionGroupLabel = 'Group'
2223
export const transactionFeeLabel = 'Fee'
24+
export const transactionRekeyToLabel = 'Rekey To'
2325

2426
export function TransactionInfo({ transaction }: Props) {
2527
const subType = useAtomValue(transaction.subType)
@@ -37,6 +39,7 @@ export function TransactionInfo({ transaction }: Props) {
3739
{subType && <Badge variant="outline">{subType}</Badge>}
3840
{transaction.signature?.type === SignatureType.Multi && <Badge variant="outline">Multisig</Badge>}
3941
{transaction.signature?.type === SignatureType.Logic && <Badge variant="outline">LogicSig</Badge>}
42+
{transaction.rekeyTo && <Badge variant="outline">Rekey</Badge>}
4043
</>
4144
),
4245
},
@@ -60,13 +63,22 @@ export function TransactionInfo({ transaction }: Props) {
6063
dt: transactionFeeLabel,
6164
dd: transaction.fee ? <DisplayAlgo amount={transaction.fee} /> : 'N/A',
6265
},
66+
...(transaction.rekeyTo
67+
? [
68+
{
69+
dt: transactionRekeyToLabel,
70+
dd: <AccountLink address={transaction.rekeyTo} />,
71+
},
72+
]
73+
: []),
6374
],
6475
[
6576
subType,
6677
transaction.confirmedRound,
6778
transaction.fee,
6879
transaction.group,
6980
transaction.id,
81+
transaction.rekeyTo,
7082
transaction.roundTime,
7183
transaction.signature?.type,
7284
transaction.type,

src/features/transactions/mappers/transaction-common-properties-mappers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const mapCommonTransactionProperties = (transactionResult: TransactionRes
2020
signature: transformSignature(transactionResult.signature),
2121
note: transactionResult.note,
2222
json: transactionResult,
23+
rekeyTo: transactionResult['rekey-to'],
2324
}
2425
}
2526

src/features/transactions/models/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type CommonTransactionProperties = {
1515
note?: string
1616
signature?: Singlesig | Multisig | Logicsig
1717
json: object
18+
rekeyTo?: Address
1819
}
1920

2021
export enum TransactionType {

src/features/transactions/pages/transaction-page.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
transactionFeeLabel,
2828
transactionGroupLabel,
2929
transactionIdLabel,
30+
transactionRekeyToLabel,
3031
transactionTimestampLabel,
3132
transactionTypeLabel,
3233
} from '../components/transaction-info'
@@ -1137,3 +1138,31 @@ describe('transaction-page', () => {
11371138
})
11381139
})
11391140
})
1141+
1142+
describe('when rendering a rekey transaction', () => {
1143+
const transaction = transactionResultMother['testnet-24RAYAOGMJ45BL6A7RYQOKZNECCA3VFXQUAM5X64BEDBVFNLPIPQ']().build()
1144+
1145+
it('should be rendered with the correct data', () => {
1146+
vi.mocked(useParams).mockImplementation(() => ({ transactionId: transaction.id }))
1147+
const myStore = createStore()
1148+
myStore.set(transactionResultsAtom, new Map([[transaction.id, atom(transaction)]]))
1149+
1150+
return executeComponentTest(
1151+
() => {
1152+
return render(<TransactionPage />, undefined, myStore)
1153+
},
1154+
async (component) => {
1155+
await waitFor(() => {
1156+
descriptionListAssertion({
1157+
container: component.container,
1158+
items: [
1159+
{ term: transactionIdLabel, description: transaction.id },
1160+
{ term: transactionTypeLabel, description: 'PaymentRekey' },
1161+
{ term: transactionRekeyToLabel, description: 'QUANSC2GTZQ7GL5CA42CMOYIX2LHJ2E7QD2ZDZKQJG2WAKGWOYBMNADHSA' },
1162+
],
1163+
})
1164+
})
1165+
}
1166+
)
1167+
})
1168+
})

src/tests/object-mother/transaction-result.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,4 +1354,33 @@ export const transactionResultMother = {
13541354
'tx-type': 'appl',
13551355
} as unknown as TransactionResult)
13561356
},
1357+
['testnet-24RAYAOGMJ45BL6A7RYQOKZNECCA3VFXQUAM5X64BEDBVFNLPIPQ']: () => {
1358+
return new TransactionResultBuilder({
1359+
'close-rewards': 0,
1360+
'closing-amount': 0,
1361+
'confirmed-round': 28236256,
1362+
fee: 1000,
1363+
'first-valid': 28236253,
1364+
'genesis-hash': 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=',
1365+
'genesis-id': 'testnet-v1.0',
1366+
id: '24RAYAOGMJ45BL6A7RYQOKZNECCA3VFXQUAM5X64BEDBVFNLPIPQ',
1367+
'intra-round-offset': 0,
1368+
'last-valid': 28237253,
1369+
note: 'UmVrZXkgdG8gUVVBTlNDMkdUWlE3R0w1Q0E0MkNNT1lJWDJMSEoyRTdRRDJaRFpLUUpHMldBS0dXT1lCTU5BREhTQQ==',
1370+
'payment-transaction': {
1371+
amount: 0,
1372+
'close-amount': 0,
1373+
receiver: 'WK3LE77YNSRUC3GVNP6FA7PF67GWAOLAGTNKOII4YBFSRQ3DW7C72MD4TM',
1374+
},
1375+
'receiver-rewards': 0,
1376+
'rekey-to': 'QUANSC2GTZQ7GL5CA42CMOYIX2LHJ2E7QD2ZDZKQJG2WAKGWOYBMNADHSA',
1377+
'round-time': 1678206268,
1378+
sender: 'WK3LE77YNSRUC3GVNP6FA7PF67GWAOLAGTNKOII4YBFSRQ3DW7C72MD4TM',
1379+
'sender-rewards': 0,
1380+
signature: {
1381+
sig: 'G9NwYqLXA8L92cauKXyHeY/Jp5cBUTWwL+Ri2w5ex18mIsWQBq7gNg1EU07mzfKU6i93EqkcVZLyVmA2HJkmDg==',
1382+
},
1383+
'tx-type': TransactionType.pay,
1384+
} as unknown as TransactionResult)
1385+
},
13571386
}

0 commit comments

Comments
 (0)