Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update activities to include events coinBalance #6953

Merged
merged 13 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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