Skip to content

Commit f4fde86

Browse files
committed
refactor: update transaction operation bidirectional info handling
1 parent ecb5f6d commit f4fde86

File tree

8 files changed

+62
-102
lines changed

8 files changed

+62
-102
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,5 @@ act-actions
8888
playwright-results
8989
playwright-html
9090

91-
packages/e2e-contract-tests/src/contract-ids.json
91+
packages/e2e-contract-tests/src/contract-ids.json
92+
.vscode/settings.json

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@
1515
"typescript.suggest.paths": true,
1616
"typescript.suggest.enabled": true,
1717
"typescript.suggest.completeFunctionCalls": true,
18+
"[typescriptreact]": {
19+
"editor.defaultFormatter": "biomejs.biome"
20+
},
1821
}

packages/app/src/systems/Transaction/components/TxContent/TxOperationsSimple/TxOperationsGroup.tsx

+1-28
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,6 @@ type TxOperationsGroupProps = {
1212
numberLabel?: string;
1313
};
1414

15-
export type BidirectionalInfo = 'atob' | 'btoa' | null;
16-
17-
function getBidirectionalInfo(
18-
current: SimplifiedOperation,
19-
next: SimplifiedOperation
20-
): BidirectionalInfo {
21-
if (
22-
current?.to?.address === next?.from?.address &&
23-
current?.from?.address === next?.to?.address
24-
) {
25-
return 'atob';
26-
}
27-
28-
if (
29-
current?.from?.address === next?.from?.address &&
30-
current?.to?.address === next?.to?.address
31-
) {
32-
return 'btoa';
33-
}
34-
35-
return null;
36-
}
37-
3815
export function TxOperationsGroup({
3916
title,
4017
operations,
@@ -83,10 +60,6 @@ export function TxOperationsGroup({
8360
<TxOperation
8461
key={`${operation.type}-${operation.from}-${operation.to}-${index}`}
8562
operation={operation}
86-
bidirectionalInfo={getBidirectionalInfo(
87-
operation,
88-
operations[index + 1]
89-
)}
9063
/>
9164
) : null
9265
)}
@@ -128,7 +101,7 @@ const styles = {
128101
content: cssObj({
129102
display: 'flex',
130103
flexDirection: 'column',
131-
gap: '4px 0',
104+
gap: '0',
132105
}),
133106
numberLabel: cssObj({
134107
backgroundColor: '$gray1',

packages/app/src/systems/Transaction/components/TxOperation/TxOperation.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ import { Box, Icon, Text } from '@fuel-ui/react';
33
import { useState } from 'react';
44
import { MotionBox, MotionStack, animations } from '~/systems/Core';
55
import { useAssetsAmount } from '../../hooks/useAssetsAmount';
6-
import type { SimplifiedOperation } from '../../types';
7-
import type { BidirectionalInfo } from '../TxContent/TxOperationsSimple/TxOperationsGroup';
6+
import type { BidirectionalInfo, SimplifiedOperation } from '../../types.tsx';
87
import { TxOperationCard } from './TxOperationCard';
98

109
export type TxOperationProps = {
1110
operation: SimplifiedOperation;
12-
bidirectionalInfo?: BidirectionalInfo;
1311
};
1412

1513
type IdenticalOpsProps = {
@@ -53,10 +51,7 @@ function IdenticalOperations({ count, instances }: IdenticalOpsProps) {
5351
);
5452
}
5553

56-
export function TxOperation({
57-
operation,
58-
bidirectionalInfo,
59-
}: TxOperationProps) {
54+
export function TxOperation({ operation }: TxOperationProps) {
6055
const { metadata, assets } = operation;
6156
const amounts = useAssetsAmount({
6257
operationsCoin: assets,
@@ -70,7 +65,6 @@ export function TxOperation({
7065
<TxOperationCard
7166
operation={operation}
7267
assetsAmount={amounts}
73-
bidirectionalInfo={bidirectionalInfo}
7468
css={styles.card}
7569
/>
7670
{metadata.childOperations && metadata.childOperations.length > 1 && (

packages/app/src/systems/Transaction/components/TxOperation/TxOperationCard.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ import { useProvider } from '~/systems/Network/hooks/useProvider';
99
import { type SimplifiedOperation, TxCategory } from '../../types';
1010
import type { BidirectionalInfo } from '../TxContent/TxOperationsSimple/TxOperationsGroup';
1111
import { TxOperationAssets } from './TxOperationAssets';
12-
type TxOperationCardProps = {
12+
13+
export type TxOperationCardProps = {
1314
operation: SimplifiedOperation;
1415
assetsAmount?: AssetFuelAmount[];
15-
bidirectionalInfo?: BidirectionalInfo;
16-
css?: ThemeUtilsCSS;
16+
css?: CSS;
1717
};
1818

1919
export function TxOperationCard({
2020
operation,
2121
assetsAmount,
22-
bidirectionalInfo = null,
2322
css,
2423
}: TxOperationCardProps) {
24+
const { bidirectionalInfo } = operation;
2525
const { accounts } = useAccounts();
2626
const provider = useProvider();
2727
const [baseAsset, setBaseAsset] = useState<AssetFuelData | undefined>();

packages/app/src/systems/Transaction/components/TxOperations/TxOperationsDrawer.tsx

+1-39
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,6 @@ export function TxOperationsDrawer({ operations }: TxOperationsDrawerProps) {
2424
setIsExpanded(!isExpanded);
2525
};
2626

27-
function getBidirectionalInfo(
28-
previous: SimplifiedOperation,
29-
current: SimplifiedOperation,
30-
next: SimplifiedOperation
31-
) {
32-
console.log('previous', previous);
33-
console.log('current', current);
34-
console.log('next', next);
35-
// if next operation is the reverse of the current operation, return 'atob'
36-
// if previous operation is the reverse of the current operation, return 'btoa'
37-
// otherwise return null
38-
if (
39-
next &&
40-
next.from.address === current.to.address &&
41-
next.to.address === current.from.address &&
42-
(!next.metadata?.identicalOps || next.metadata.identicalOps.size === 0)
43-
) {
44-
return 'atob';
45-
}
46-
if (
47-
previous &&
48-
previous.from.address === current.to.address &&
49-
previous.to.address === current.from.address &&
50-
(!previous.metadata?.identicalOps ||
51-
previous.metadata.identicalOps.size === 0)
52-
) {
53-
return 'btoa';
54-
}
55-
return null;
56-
}
57-
5827
return (
5928
<Box css={styles.drawer} data-expanded={isExpanded}>
6029
{operations.length > 1 && (
@@ -91,14 +60,7 @@ export function TxOperationsDrawer({ operations }: TxOperationsDrawerProps) {
9160
key={`${operation.type}-${operation.from}-${operation.to}-${index}`}
9261
css={styles.operation}
9362
>
94-
<TxOperation
95-
operation={operation}
96-
bidirectionalInfo={getBidirectionalInfo(
97-
operations[index - 1],
98-
operation,
99-
operations[index + 1]
100-
)}
101-
/>
63+
<TxOperation operation={operation} />
10264
</Box.Flex>
10365
) : null
10466
)}

packages/app/src/systems/Transaction/types.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export type ContractCallMetadata = {
8080
operationCount?: number;
8181
groupedAssets?: Record<string, SimplifiedOperation['assets'][0]>;
8282
childOperations?: SimplifiedOperation[];
83-
identicalOps?: Map<string, IdenticalOpsGroup>;
83+
identicalOps?: Array<IdenticalOpsGroup>;
8484
};
8585

8686
export type SwapMetadata = {
@@ -99,6 +99,8 @@ export type SimplifiedAddress = {
9999
type: number; // 0 for contract, 1 for account
100100
};
101101

102+
export type BidirectionalInfo = 'atob' | 'btoa' | null;
103+
102104
export type SimplifiedOperation = {
103105
type: TxCategory;
104106
from: SimplifiedAddress;
@@ -111,6 +113,7 @@ export type SimplifiedOperation = {
111113
}>;
112114
metadata: ContractCallMetadata;
113115
assetAmount?: AssetFuelAmount;
116+
bidirectionalInfo?: BidirectionalInfo;
114117
};
115118

116119
export type SimplifiedFee = {

packages/app/src/systems/Transaction/utils/simplifyTransaction.ts

+45-21
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ import {
1111
ReceiptType,
1212
type TransactionResultReceipt,
1313
} from 'fuels';
14-
import type { ContractCallMetadata, SimplifiedOperation } from '../types';
14+
import type {
15+
BidirectionalInfo,
16+
ContractCallMetadata,
17+
SimplifiedOperation,
18+
} from '../types';
1519
import { TxCategory } from '../types';
16-
import type { CategorizedOperations } from '../types';
17-
import type { SimplifiedTransaction } from '../types.tsx';
20+
import type { CategorizedOperations, SimplifiedTransaction } from '../types';
1821

1922
type TransactionRequestWithOrigin = TransactionRequest & {
2023
origin?: string;
@@ -116,6 +119,33 @@ function transformOperation(
116119
return baseOperation;
117120
}
118121

122+
function calculateBidirectionalInfo(
123+
operations: SimplifiedOperation[],
124+
currentIndex: number
125+
): BidirectionalInfo {
126+
const current = operations[currentIndex];
127+
const next = operations[currentIndex + 1];
128+
const previous = operations[currentIndex - 1];
129+
130+
if (
131+
next &&
132+
next.from.address === current.to.address &&
133+
next.to.address === current.from.address
134+
) {
135+
return 'atob';
136+
}
137+
138+
if (
139+
previous &&
140+
previous.from.address === current.to.address &&
141+
previous.to.address === current.from.address
142+
) {
143+
return 'btoa';
144+
}
145+
146+
return null;
147+
}
148+
119149
export function transformOperations(
120150
summary: TransactionSummary,
121151
currentAccount?: string
@@ -155,18 +185,11 @@ export function transformOperations(
155185
(a, b) => (a.metadata?.depth || 0) - (b.metadata?.depth || 0)
156186
);
157187

158-
return operations;
159-
}
160-
161-
// Helper to create a unique key for identical operations
162-
function getOperationKey(op: SimplifiedOperation) {
163-
return JSON.stringify({
164-
type: op.type,
165-
from: op.from.address,
166-
to: op.to.address,
167-
// Sort assets to ensure consistent key regardless of array order
168-
assets: (op.assets || []).map((a) => `${a.assetId}-${a.amount}`).sort(),
169-
});
188+
// Calculate bidirectional info for each operation
189+
return operations.map((op, index) => ({
190+
...op,
191+
bidirectionalInfo: calculateBidirectionalInfo(operations, index),
192+
}));
170193
}
171194

172195
function groupSimilarOperations(
@@ -187,7 +210,7 @@ function groupSimilarOperations(
187210
groupedAssets: {},
188211
childOperations: [op],
189212
// New: track identical operations within group
190-
identicalOps: new Map(),
213+
identicalOps: [],
191214
},
192215
};
193216
} else {
@@ -196,17 +219,18 @@ function groupSimilarOperations(
196219
acc[key].metadata.childOperations!.push(op);
197220

198221
// Group identical operations
199-
const identicalKey = getOperationKey(op);
200-
const identicalGroup = acc[key].metadata?.identicalOps?.get(
201-
identicalKey
222+
const identicalGroup = acc[key].metadata?.identicalOps?.find(
223+
(g) =>
224+
g.operation.from.address === op.from.address &&
225+
g.operation.to.address === op.to.address
202226
) || {
203227
operation: op,
204228
count: 0,
205229
instances: [],
206230
};
207231
identicalGroup.count += 1;
208232
identicalGroup.instances.push(op);
209-
acc[key].metadata?.identicalOps?.set(identicalKey, identicalGroup);
233+
acc[key].metadata?.identicalOps?.push(identicalGroup);
210234

211235
// Combine assets as before
212236
for (const asset of op.assets || []) {
@@ -232,7 +256,7 @@ function groupSimilarOperations(
232256
metadata: {
233257
...group.metadata,
234258
// Only include groups with multiple identical operations
235-
identicalOps: Array.from(group.metadata.identicalOps.values()).filter(
259+
identicalOps: Array.from(group.metadata?.identicalOps || []).filter(
236260
(g) => g.count > 1
237261
),
238262
},

0 commit comments

Comments
 (0)