- {multipleRecipientsList.map((recipient) => (
-
-
- {recipient?.coin && (
-
-
-
- )}
-
- ))}
+ {multipleRecipientsList.map(
+ ({ address, amount, coinType }) => (
+
+
+ {amount ? (
+
+
+
+ ) : null}
+
+ )
+ )}
) : null}
diff --git a/apps/explorer/src/ui/stories/SenderRecipient.stories.tsx b/apps/explorer/src/ui/stories/SenderRecipient.stories.tsx
index d6a0e76e41f4b..6a423302238dd 100644
--- a/apps/explorer/src/ui/stories/SenderRecipient.stories.tsx
+++ b/apps/explorer/src/ui/stories/SenderRecipient.stories.tsx
@@ -13,30 +13,26 @@ const data = {
recipients: [
{
address: '0x955d8ddc4a17670bda6b949cbdbc8f5aac820cc7',
- coin: {
- amount: 1000,
- symbol: '0x2::sui::SUI',
- },
+
+ amount: 1000,
+ coinType: '0x2::sui::SUI',
},
{
address: '0x9798852b55fcbf352052c9414920ebf7811ce05e',
- coin: {
- amount: 120_030,
- symbol: 'COIN',
- },
+
+ amount: 120_030,
+ coinType: 'COIN',
},
{
address: '0xc4173a804406a365e69dfb297d4eaaf002546ebd',
- coin: {
- amount: 10_050_504,
- symbol: 'MIST',
- },
+
+ amount: 10_050_504,
+ coinType: 'MIST',
},
{
address: '0xca1e11744de126dd1b116c6a16df4715caea56a3',
- coin: {
- amount: '1000002',
- },
+
+ amount: 1000002,
},
{
address: '0x49e095bc33fda565c07937478f201f4344941f03',
diff --git a/apps/explorer/src/utils/getAmount.ts b/apps/explorer/src/utils/getAmount.ts
index 764a7459abc35..d77d2f89a5e5d 100644
--- a/apps/explorer/src/utils/getAmount.ts
+++ b/apps/explorer/src/utils/getAmount.ts
@@ -7,11 +7,15 @@ import {
getTransferSuiTransaction,
getTransferObjectTransaction,
getTransactionKindName,
+ getTransactionSender,
+ getTransactions,
+ SUI_TYPE_ARG,
} from '@mysten/sui.js';
import type {
SuiTransactionKind,
TransactionEffects,
+ SuiTransactionResponse,
SuiEvent,
} from '@mysten/sui.js';
@@ -32,23 +36,23 @@ const getCoinType = (
};
type FormattedBalance = {
- amount?: number | bigint | null;
+ amount?: number | null;
coinType?: string | null;
- isCoin?: boolean;
- recipientAddress: string;
-}[];
+ address: string;
+};
-export function getAmount(
+// For TransferObject, TransferSui, Pay, PaySui, transactions get the amount from the transfer data
+export function getTransfersAmount(
txnData: SuiTransactionKind,
txnEffect?: TransactionEffects
-): FormattedBalance | null {
+): FormattedBalance[] | null {
const txKindName = getTransactionKindName(txnData);
if (txKindName === 'TransferObject') {
const txn = getTransferObjectTransaction(txnData);
return txn?.recipient
? [
{
- recipientAddress: txn?.recipient,
+ address: txn?.recipient,
},
]
: null;
@@ -59,11 +63,10 @@ export function getAmount(
return txn?.recipient
? [
{
- recipientAddress: txn.recipient,
+ address: txn.recipient,
amount: txn?.amount,
coinType:
txnEffect && getCoinType(txnEffect, txn.recipient),
- isCoin: true,
},
]
: null;
@@ -87,10 +90,9 @@ export function getAmount(
paySuiData.recipients[0]
)
: null,
- recipientAddress:
+ address:
paySuiData.recipients[index] ||
paySuiData.recipients[0],
- isCoin: true,
},
};
},
@@ -98,10 +100,64 @@ export function getAmount(
[key: string]: {
amount: number;
coinType: string | null;
- recipientAddress: string;
+ address: string;
};
}
);
-
return amountByRecipient ? Object.values(amountByRecipient) : null;
}
+
+// Get transaction amount from coinBalanceChange event for Call Txn
+// Aggregate coinBalanceChange by coinType and address
+function getTxnAmountFromCoinBalanceEvent(
+ txEffects: TransactionEffects,
+ address: string
+): FormattedBalance[] {
+ const events = txEffects?.events || [];
+ const coinsMeta = {} as { [coinType: string]: FormattedBalance };
+
+ events.forEach((event) => {
+ if (
+ 'coinBalanceChange' in event &&
+ event?.coinBalanceChange?.changeType &&
+ ['Receive', 'Pay'].includes(event?.coinBalanceChange?.changeType) &&
+ event?.coinBalanceChange?.transactionModule !== 'gas'
+ ) {
+ const { coinBalanceChange } = event;
+ const { coinType, amount, owner, sender } = coinBalanceChange;
+ const { AddressOwner } = owner as { AddressOwner: string };
+ if (AddressOwner === address || address === sender) {
+ coinsMeta[`${AddressOwner}${coinType}`] = {
+ amount:
+ (coinsMeta[`${AddressOwner}${coinType}`]?.amount || 0) +
+ amount,
+ coinType: coinType,
+ address: AddressOwner,
+ };
+ }
+ }
+ });
+ return Object.values(coinsMeta);
+}
+
+// Get the amount from events and transfer data
+// optional flag to get only SUI coin type for table view
+export function getAmount({
+ txnData,
+ suiCoinOnly = false,
+}: {
+ txnData: SuiTransactionResponse;
+ suiCoinOnly?: boolean;
+}) {
+ const { effects, certificate } = txnData;
+ const txnDetails = getTransactions(certificate)[0];
+ const sender = getTransactionSender(certificate);
+ const suiTransfer = getTransfersAmount(txnDetails, effects);
+ const coinBalanceChange = getTxnAmountFromCoinBalanceEvent(effects, sender);
+ const transfers = suiTransfer || coinBalanceChange;
+ if (suiCoinOnly) {
+ return transfers?.filter(({ coinType }) => coinType === SUI_TYPE_ARG);
+ }
+
+ return transfers;
+}