diff --git a/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromNovesTransaction.ts b/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromNovesTransaction.ts new file mode 100644 index 0000000000..a6ad015f0e --- /dev/null +++ b/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromNovesTransaction.ts @@ -0,0 +1,169 @@ +import { NovesTxResponse } from '@auxiliary/noves' +import { IAccountState } from '@core/account' +import { EvmActivityType } from '@core/activity/enums/evm' +import { BaseEvmActivity, EvmActivity, EvmCoinTransferActivity, EvmTokenTransferActivity } from '@core/activity/types' +import { IEvmNetwork } from '@core/network' +import { BASE_TOKEN_ID, convertToRawAmount, IErc20Metadata, TokenStandard } from '@core/token' +import { Converter } from '@core/utils' +import { IAccountSubject, SubjectType } from '@core/wallet' +import { ActivityDirection } from '@core/activity/enums' +import { generateBaseEvmActivity } from './generateBaseEvmActivity' +import { LocalEvmTransaction } from '@core/transactions/types' +import { generateEvmActivityFromLocalEvmTransaction } from './generateEvmActivityFromLocalEvmTransaction' + +export async function generateEvmActivityFromNovesTransaction( + novesTx: NovesTxResponse, + localTransaction: LocalEvmTransaction | undefined, + evmNetwork: IEvmNetwork, + account: IAccountState +): Promise { + const baseActivity = await generateBaseEvmActivityFromNovesTransaction( + novesTx, + localTransaction, + evmNetwork, + account + ) + + switch ( + novesTx.classificationData.type // What are all the types and interfaces for this? + ) { + case 'sendToken': // TODO: this string should be an enum + return generateEvmActivityFromSendTokenClassification(baseActivity, novesTx, account) + case 'receiveToken': + return generateEvmActivityFromReceiveTokenClassification(baseActivity, novesTx, account) + default: + return localTransaction + ? generateEvmActivityFromLocalEvmTransaction(localTransaction, evmNetwork, account) + : undefined + } +} + +async function generateBaseEvmActivityFromNovesTransaction( + novesTx: NovesTxResponse, + localTransaction: LocalEvmTransaction | undefined, + evmNetwork: IEvmNetwork, + account: IAccountState +): Promise { + const newTransaction = { + recipient: novesTx.rawTransactionData.toAddress.toLowerCase(), + from: novesTx.rawTransactionData.fromAddress.toLowerCase(), + gasUsed: novesTx.rawTransactionData.gasUsed, + gasPrice: BigInt(novesTx.rawTransactionData.gasPrice), + transactionHash: novesTx.rawTransactionData.transactionHash, + timestamp: novesTx.rawTransactionData.timestamp, + blockNumber: novesTx.rawTransactionData.blockNumber, + confirmations: localTransaction?.confirmations ?? 0, + status: localTransaction?.status ?? true, + transactionIndex: localTransaction?.transactionIndex ?? 0, + to: novesTx.rawTransactionData.toAddress.toLowerCase(), + } + + const baseActivity = await generateBaseEvmActivity(newTransaction, evmNetwork, account) + + const received = novesTx.classificationData.received[0] + + if (received) { + baseActivity.recipient = { + type: SubjectType.Account, + address: received.to.address?.toLowerCase() ?? '', + account: account, + } + } + + baseActivity.subject = + baseActivity.direction === ActivityDirection.Outgoing ? baseActivity.recipient : baseActivity.sender + + return baseActivity +} + +function generateEvmActivityFromSendTokenClassification( + baseActivity: BaseEvmActivity, + novesTx: NovesTxResponse, + account: IAccountState +): EvmTokenTransferActivity | EvmCoinTransferActivity { + const sent = novesTx.classificationData.sent[0] + + const sender: IAccountSubject = { + type: SubjectType.Account, + address: sent.from.address?.toLowerCase() ?? '', + account: account, + } + + const amountString = sent.amount + const rawAmount = convertToRawAmount(amountString, { + ...sent.token, + standard: TokenStandard.Erc20, + } as IErc20Metadata) + + const isBaseTokenTransfer = Converter.isHex(sent.token.address ?? '') + + if (isBaseTokenTransfer) { + return { + ...baseActivity, + type: EvmActivityType.CoinTransfer, + sender, + baseTokenTransfer: { + tokenId: BASE_TOKEN_ID, + rawAmount: rawAmount ?? BigInt(0), + }, + } + } else { + return { + ...baseActivity, + type: EvmActivityType.TokenTransfer, + sender, + tokenTransfer: { + standard: TokenStandard.Erc20, + tokenId: sent.token.address?.toLowerCase() ?? '', + rawAmount: rawAmount ?? BigInt(0), + }, + rawData: '', + } + } +} + +function generateEvmActivityFromReceiveTokenClassification( + baseActivity: BaseEvmActivity, + novesTx: NovesTxResponse, + account: IAccountState +): EvmTokenTransferActivity | EvmCoinTransferActivity { + const received = novesTx.classificationData.received[0] + + const recipient: IAccountSubject = { + type: SubjectType.Account, + address: received.from.address?.toLowerCase() ?? '', + account: account, + } + + const amountString = received.amount + const rawAmount = convertToRawAmount(amountString, { + ...received.token, + standard: TokenStandard.Erc20, + } as IErc20Metadata) + + const isBaseTokenTransfer = Converter.isHex(received.token.address ?? '') + + if (isBaseTokenTransfer) { + return { + ...baseActivity, + type: EvmActivityType.CoinTransfer, + recipient, + baseTokenTransfer: { + tokenId: BASE_TOKEN_ID, + rawAmount: rawAmount ?? BigInt(0), + }, + } + } else { + return { + ...baseActivity, + type: EvmActivityType.TokenTransfer, + recipient, + tokenTransfer: { + standard: TokenStandard.Erc20, + tokenId: received.token.address?.toLowerCase() ?? '', + rawAmount: rawAmount ?? BigInt(0), + }, + rawData: '', + } + } +} diff --git a/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromPersistedTransaction.ts b/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromPersistedTransaction.ts index 22963f5a1b..4c62a96976 100644 --- a/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromPersistedTransaction.ts +++ b/packages/shared/src/lib/core/activity/utils/evm/generateEvmActivityFromPersistedTransaction.ts @@ -5,13 +5,14 @@ import { EvmActivity } from '../../types' import { generateEvmActivityFromBlockscoutTransaction } from './generateEvmActivityFromBlockscoutTransaction' import { generateEvmActivityFromLocalEvmTransaction } from './generateEvmActivityFromLocalEvmTransaction' import { generateEvmTokenTransferActivityFromBlockscoutTokenTransfer } from './generateEvmTokenTransferActivityFromBlockscoutTokenTransfer' +import { generateEvmActivityFromNovesTransaction } from './generateEvmActivityFromNovesTransaction' export async function generateEvmActivityFromPersistedTransaction( persistedTransaction: PersistedTransaction, evmNetwork: IEvmNetwork, account: IAccountState ): Promise { - const { local, blockscout, tokenTransfer } = persistedTransaction + const { local, noves, blockscout, tokenTransfer } = persistedTransaction if (tokenTransfer) { return generateEvmTokenTransferActivityFromBlockscoutTokenTransfer( @@ -22,6 +23,8 @@ export async function generateEvmActivityFromPersistedTransaction( ) } else if (blockscout) { return generateEvmActivityFromBlockscoutTransaction(blockscout, local, evmNetwork, account) + } else if (noves) { + return generateEvmActivityFromNovesTransaction(noves, local, evmNetwork, account) } else if (local) { return generateEvmActivityFromLocalEvmTransaction(local, evmNetwork, account) } diff --git a/packages/shared/src/lib/core/activity/utils/evm/index.ts b/packages/shared/src/lib/core/activity/utils/evm/index.ts index 521a149a32..5a7c45671a 100644 --- a/packages/shared/src/lib/core/activity/utils/evm/index.ts +++ b/packages/shared/src/lib/core/activity/utils/evm/index.ts @@ -1,8 +1,8 @@ -export * from './generateEvmActivitiesFromEvmChain' -export * from './generateEvmActivityFromPersistedTransaction' -export * from './generateEvmTokenTransferActivityFromBlockscoutTokenTransfer' export * from './generateBaseEvmActivity' +export * from './generateEvmActivitiesFromEvmChain' export * from './generateEvmActivityFromLocalEvmTransaction' +export * from './generateEvmActivityFromPersistedTransaction' export * from './generateEvmBalanceChangeActivity' export * from './generateEvmNftBalanceChangeActivity' export * from './generateEvmTokenBalanceChangeActivity' +export * from './generateEvmTokenTransferActivityFromBlockscoutTokenTransfer'