sui-explorer-local
Version:
Local Sui Explorer
81 lines (70 loc) • 2.43 kB
text/typescript
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
import {
type DryRunTransactionBlockResponse,
type ObjectOwner,
type SuiTransactionBlockResponse,
} from '@mysten/sui.js/client';
import { normalizeSuiObjectId, parseStructTag } from '@mysten/sui.js/utils';
export type BalanceChange = {
coinType: string;
amount: string;
recipient?: string;
owner?: string;
unRecognizedToken: boolean;
};
export type BalanceChangeByOwner = Record<string, BalanceChange[]>;
export type BalanceChangeSummary = BalanceChangeByOwner | null;
function getOwnerAddress(owner: ObjectOwner): string {
if (typeof owner === 'object') {
if ('AddressOwner' in owner) {
return owner.AddressOwner;
} else if ('ObjectOwner' in owner) {
return owner.ObjectOwner;
} else if ('Shared' in owner) {
return 'Shared';
}
}
return '';
}
export const getBalanceChangeSummary = (
transaction: DryRunTransactionBlockResponse | SuiTransactionBlockResponse,
recognizedPackagesList: string[],
) => {
const { balanceChanges, effects } = transaction;
if (!balanceChanges || !effects) return null;
const normalizedRecognizedPackages = recognizedPackagesList.map((itm) =>
normalizeSuiObjectId(itm),
);
const balanceChangeByOwner = {};
return balanceChanges.reduce((acc, balanceChange) => {
const amount = BigInt(balanceChange.amount);
const owner = getOwnerAddress(balanceChange.owner);
const recipient = balanceChanges.find(
(bc) => balanceChange.coinType === bc.coinType && amount === BigInt(bc.amount) * -1n,
);
const { address: packageId } = parseStructTag(balanceChange.coinType);
const recipientAddress = recipient?.owner ? getOwnerAddress(recipient?.owner) : undefined;
const summary = {
coinType: balanceChange.coinType,
amount: amount.toString(),
recipient: recipientAddress,
owner,
unRecognizedToken: !normalizedRecognizedPackages.includes(packageId),
};
acc[owner] = (acc[owner] ?? []).concat(summary);
return acc;
}, balanceChangeByOwner as BalanceChangeByOwner);
};
export const getRecognizedUnRecognizedTokenChanges = (changes: BalanceChange[]) => {
const recognizedTokenChanges = [];
const unRecognizedTokenChanges = [];
for (let change of changes) {
if (change.unRecognizedToken) {
unRecognizedTokenChanges.push(change);
} else {
recognizedTokenChanges.push(change);
}
}
return { recognizedTokenChanges, unRecognizedTokenChanges };
};