Skip to content

Commit

Permalink
update activities to include events coinBalance (#6953)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jibz1 authored Jan 14, 2023
1 parent 3f8f5c9 commit 293d455
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 165 deletions.
104 changes: 104 additions & 0 deletions apps/wallet/src/ui/app/helpers/getAmount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import {
getPaySuiTransaction,
getPayTransaction,
getTransferSuiTransaction,
getTransferObjectTransaction,
getTransactionKindName,
} from '@mysten/sui.js';

import type {
SuiTransactionKind,
TransactionEffects,
SuiEvent,
} from '@mysten/sui.js';

const getCoinType = (
txEffects: TransactionEffects,
address: string
): string | null => {
const events = txEffects?.events || [];
const coinType = events
?.map((event: SuiEvent) => {
const data = Object.values(event).find(
(itm) => itm?.owner?.AddressOwner === address
);
return data?.coinType;
})
.filter(Boolean);
return coinType?.[0] ? coinType[0] : null;
};

type FormattedBalance = {
amount?: number | null;
coinType?: string | null;
recipientAddress: string;
}[];

export function getAmount(
txnData: SuiTransactionKind,
txnEffect: TransactionEffects
): FormattedBalance | null {
const txKindName = getTransactionKindName(txnData);
if (txKindName === 'TransferObject') {
const txn = getTransferObjectTransaction(txnData);
return txn?.recipient
? [
{
recipientAddress: txn?.recipient,
},
]
: null;
}

if (txKindName === 'TransferSui') {
const txn = getTransferSuiTransaction(txnData);
return txn?.recipient
? [
{
recipientAddress: txn.recipient,
amount: txn?.amount,
coinType:
txnEffect && getCoinType(txnEffect, txn.recipient),
},
]
: null;
}

const paySuiData =
getPaySuiTransaction(txnData) ?? getPayTransaction(txnData);

const amountByRecipient = paySuiData?.recipients.reduce(
(acc, value, index) => {
return {
...acc,
[value]: {
amount:
paySuiData.amounts[index] +
(value in acc ? acc[value].amount : 0),
coinType: txnEffect
? getCoinType(
txnEffect,
paySuiData.recipients[index] ||
paySuiData.recipients[0]
)
: null,
recipientAddress:
paySuiData.recipients[index] ||
paySuiData.recipients[0],
},
};
},
{} as {
[key: string]: {
amount: number;
coinType: string | null;
recipientAddress: string;
};
}
);

return amountByRecipient ? Object.values(amountByRecipient) : null;
}
63 changes: 63 additions & 0 deletions apps/wallet/src/ui/app/helpers/getEventsSummary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import type { TransactionEffects } from '@mysten/sui.js';

export type CoinsMetaProps = {
amount: number;
coinType: string;
receiverAddress: string;
};

export type TxnMetaResponse = {
objectIDs: string[];
coins: CoinsMetaProps[];
};

export function getEventsSummary(
txEffects: TransactionEffects,
address: string
): TxnMetaResponse {
const events = txEffects?.events || [];
const coinsMeta = {} as { [coinType: string]: CoinsMetaProps };
const objectIDs: string[] = [];

events.forEach((event) => {
// Aggregate coinBalanceChange by coinType and address
// A net positive amount means the user received coins
// A net negative amount means the user sent coins
if (
'coinBalanceChange' in event &&
event?.coinBalanceChange?.changeType &&
['Receive', 'Pay'].includes(event?.coinBalanceChange?.changeType)
) {
const { coinBalanceChange } = event;
const { coinType, amount, owner } = coinBalanceChange;
const { AddressOwner } = owner as { AddressOwner: string };

coinsMeta[`${AddressOwner}${coinType}`] = {
amount:
(coinsMeta[`${AddressOwner}${coinType}`]?.amount || 0) +
amount,
coinType: coinType,
receiverAddress: AddressOwner,
};
}

// return objectIDs of the transfer objects
if ('transferObject' in event) {
const { transferObject } = event;
const { AddressOwner } = transferObject.recipient as {
AddressOwner: string;
};
if (AddressOwner === address) {
objectIDs.push(transferObject?.objectId);
}
}
});

return {
objectIDs,
coins: Object.values(coinsMeta),
};
}
2 changes: 2 additions & 0 deletions apps/wallet/src/ui/app/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
export { default as formatDate } from './formatDate';
export { default as notEmpty } from './notEmptyCheck';
export { parseAmount } from './parseAmount';
export { getEventsSummary } from './getEventsSummary';
export { getAmount } from './getAmount';
91 changes: 2 additions & 89 deletions apps/wallet/src/ui/app/hooks/useTransactionSummary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,96 +8,9 @@ import {
useTransactionDryRun,
type TransactionDryRun,
} from './useTransactionDryRun';
import { notEmpty } from '_helpers';
import { getEventsSummary } from '_helpers';

import type { TransactionEffects } from '@mysten/sui.js';

export type CoinsMetaProps = {
amount: number;
coinType: string;
receiverAddress: string;
};

export type TxnMetaResponse = {
objectIDs: string[];
coins: CoinsMetaProps[];
};

export function getEventsSummary(
txEffects: TransactionEffects,
address: string
): TxnMetaResponse {
const events = txEffects?.events || [];

const coinsMeta = events
.map((event) => {
if (
'coinBalanceChange' in event &&
['Receive', 'Pay'].includes(
event?.coinBalanceChange?.changeType
)
) {
/// A net positive amount means the user received coins
/// A net negative amount means the user sent coins
const { coinBalanceChange } = event;
const { coinType, amount, coinObjectId, owner } =
coinBalanceChange;
const { AddressOwner } = owner as { AddressOwner: string };
const { ObjectOwner } = owner as { ObjectOwner: string };

if (ObjectOwner) {
// TODO - update once the issue with the ObjectOwner is fixed
return null;
}

return {
amount: amount,
coinType: coinType,
coinObjectId: coinObjectId,
receiverAddress: AddressOwner,
};
}
return null;
})
.filter(notEmpty);
const objectIDs: string[] = events

.map((event) => {
if (!('transferObject' in event)) {
return null;
}
const { transferObject } = event;
const { AddressOwner } = transferObject.recipient as {
AddressOwner: string;
};
if (AddressOwner !== address) {
return null;
}
return transferObject?.objectId;
})
.filter(notEmpty);

/// Group coins by receiverAddress
// sum coins by coinType for each receiverAddress
const meta = coinsMeta.reduce((acc, value, _) => {
return {
...acc,
[`${value.receiverAddress}${value.coinType}`]: {
amount:
value.amount +
(acc[`${value.receiverAddress}${value.coinType}`]?.amount ||
0),
coinType: value.coinType,
receiverAddress: value.receiverAddress,
},
};
}, {} as { [coinType: string]: CoinsMetaProps });

return {
objectIDs,
coins: Object.values(meta),
};
}
import type { TxnMetaResponse } from '../helpers/getEventsSummary';

type ExecuteDryRunTransactionRequestProps = {
txData: TransactionDryRun;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
} from '_hooks';
import { GAS_TYPE_ARG } from '_redux/slices/sui-objects/Coin';

import type { CoinsMetaProps } from '../../helpers/getEventsSummary';
import type { TransactionDryRun } from '../../hooks/useTransactionDryRun';
import type { CoinsMetaProps } from '../../hooks/useTransactionSummary';
import type { TransactionRequest } from '_payloads/transactions';

import st from './DappTxApprovalPage.module.scss';
Expand Down Expand Up @@ -178,13 +178,14 @@ export function TransactionSummaryCard({
txRequest: TransactionRequest;
address: string;
}) {
const txData: TransactionDryRun =
const txData: TransactionDryRun = (
txRequest.tx.type === 'move-call'
? {
kind: 'moveCall',
data: txRequest.tx.data,
}
: txRequest.tx.data;
: txRequest.tx.data
) as TransactionDryRun;

const txReqData = {
txData: txData,
Expand Down
Loading

2 comments on commit 293d455

@vercel
Copy link

@vercel vercel bot commented on 293d455 Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 293d455 Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

explorer – ./apps/explorer

explorer.sui.io
explorer-topaz.vercel.app
explorer-git-main-mysten-labs.vercel.app
explorer-mysten-labs.vercel.app

Please sign in to comment.