Skip to content

Commit

Permalink
feat: generate activities from noves persisted transaction (#2870)
Browse files Browse the repository at this point in the history
* feat: generate basic evm activity from persisted noves transaction

* pr improvements and review comments

Co-authored-by: Jean Ribeiro <[email protected]>

* fix: reuse existing function

---------

Co-authored-by: Nicole O'Brien <[email protected]>
  • Loading branch information
jeeanribeiro and nicole-obrien authored Oct 16, 2024
1 parent 21c2bd4 commit 25f66a2
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -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<EvmActivity | undefined> {
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<BaseEvmActivity> {
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: '',
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<EvmActivity | undefined> {
const { local, blockscout, tokenTransfer } = persistedTransaction
const { local, noves, blockscout, tokenTransfer } = persistedTransaction

if (tokenTransfer) {
return generateEvmTokenTransferActivityFromBlockscoutTokenTransfer(
Expand All @@ -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)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/shared/src/lib/core/activity/utils/evm/index.ts
Original file line number Diff line number Diff line change
@@ -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'

0 comments on commit 25f66a2

Please sign in to comment.