diff --git a/packages/desktop/lib/electron/managers/transak.manager.ts b/packages/desktop/lib/electron/managers/transak.manager.ts index 121500f845..7ea3f87052 100644 --- a/packages/desktop/lib/electron/managers/transak.manager.ts +++ b/packages/desktop/lib/electron/managers/transak.manager.ts @@ -5,6 +5,9 @@ import { ITransakManager, ITransakWindowData } from '@core/app' import path from 'path' import { TRANSAK_WIDGET_URL } from '@auxiliary/transak/constants' import { buildQueryParametersFromObject } from '@core/utils/url' +import { Currency } from '@core/utils/enums' +import { validateBech32Address } from '@core/utils/crypto' +import { IOTA_BECH32_HRP } from '@core/network' export default class TransakManager implements ITransakManager { private rect: Electron.Rectangle @@ -165,6 +168,16 @@ export default class TransakManager implements ITransakManager { const { address, currency, service } = data const apiKey = process.env.TRANSAK_API_KEY + validateBech32Address(IOTA_BECH32_HRP, address) + + if (Object.values(Currency).includes(currency as Currency)) { + throw new Error('Invalid Transak currency') + } + + if (service !== 'BUY' && service !== 'SELL') { + throw new Error('Invalid Transak service') + } + const queryParams = buildQueryParametersFromObject({ apiKey, defaultFiatCurrency: currency, diff --git a/packages/shared/src/lib/auxiliary/blockscout/enums/blockscout-transaction-status.enum.ts b/packages/shared/src/lib/auxiliary/blockscout/enums/blockscout-transaction-status.enum.ts new file mode 100644 index 0000000000..bc97c5cef1 --- /dev/null +++ b/packages/shared/src/lib/auxiliary/blockscout/enums/blockscout-transaction-status.enum.ts @@ -0,0 +1,4 @@ +export enum BlockscoutTransactionStatus { + Ok = 'ok', + Error = 'error', +} diff --git a/packages/shared/src/lib/auxiliary/blockscout/enums/index.ts b/packages/shared/src/lib/auxiliary/blockscout/enums/index.ts new file mode 100644 index 0000000000..e79f70a7b6 --- /dev/null +++ b/packages/shared/src/lib/auxiliary/blockscout/enums/index.ts @@ -0,0 +1 @@ +export * from './blockscout-transaction-status.enum' diff --git a/packages/shared/src/lib/auxiliary/blockscout/index.ts b/packages/shared/src/lib/auxiliary/blockscout/index.ts new file mode 100644 index 0000000000..eeed63100a --- /dev/null +++ b/packages/shared/src/lib/auxiliary/blockscout/index.ts @@ -0,0 +1,2 @@ +export * from './enums' +export * from './interfaces' diff --git a/packages/shared/src/lib/auxiliary/blockscout/interfaces/blockscout-transaction.interface.ts b/packages/shared/src/lib/auxiliary/blockscout/interfaces/blockscout-transaction.interface.ts index 8bcd877195..8f43b97b74 100644 --- a/packages/shared/src/lib/auxiliary/blockscout/interfaces/blockscout-transaction.interface.ts +++ b/packages/shared/src/lib/auxiliary/blockscout/interfaces/blockscout-transaction.interface.ts @@ -1,3 +1,4 @@ +import { BlockscoutTransactionStatus } from '../enums' import { IBlockscoutAssetMetadata } from './blockscout-asset-metadata.interface' interface IFee { @@ -51,11 +52,6 @@ enum BlockscoutTransactionType { CoinTransfer = 'coin_transfer', } -enum BlockscoutTransactionStatus { - Ok = 'ok', - Error = 'error', -} - export interface IBlockscoutTransaction { timestamp: string fee: IFee diff --git a/packages/shared/src/lib/core/activity/utils/generateActivitiesFromChains.ts b/packages/shared/src/lib/core/activity/utils/generateActivitiesFromChains.ts index b814d9ddd4..14401e029d 100644 --- a/packages/shared/src/lib/core/activity/utils/generateActivitiesFromChains.ts +++ b/packages/shared/src/lib/core/activity/utils/generateActivitiesFromChains.ts @@ -3,7 +3,7 @@ import { network } from '@core/network' import { getPersistedTransactionsForChain } from '@core/transactions/stores' import { get } from 'svelte/store' import { Activity } from '../types' -import { generateActivityFromEvmTransaction } from './generateActivityFromEvmTransaction' +import { generateActivityFromPersistedTransaction } from './generateActivityFromPeristedTransaction' export async function generateActivitiesFromChains(profileId: string, account: IAccountState): Promise { const activities: Activity[] = [] @@ -11,14 +11,11 @@ export async function generateActivitiesFromChains(profileId: string, account: I const chains = get(network)?.getChains() ?? [] for (const chain of chains) { const persistedTransactions = getPersistedTransactionsForChain(profileId, account.index, chain) - for (const transaction of persistedTransactions) { + for (const persistedTransaction of persistedTransactions) { try { - if (transaction.local) { - // TODO: build activities from persisted transactions - const activity = await generateActivityFromEvmTransaction(transaction.local, chain, account) - if (activity) { - activities.push(activity) - } + const activity = await generateActivityFromPersistedTransaction(persistedTransaction, chain, account) + if (activity) { + activities.push(activity) } } catch (error) { console.error(error) diff --git a/packages/shared/src/lib/core/activity/utils/generateActivityFromPeristedTransaction.ts b/packages/shared/src/lib/core/activity/utils/generateActivityFromPeristedTransaction.ts new file mode 100644 index 0000000000..7a10a4f3e4 --- /dev/null +++ b/packages/shared/src/lib/core/activity/utils/generateActivityFromPeristedTransaction.ts @@ -0,0 +1,37 @@ +import { IAccountState } from '@core/account/interfaces' +import { getTransferInfoFromTransactionData } from '@core/layer-2/utils/getTransferInfoFromTransactionData' +import { IChain } from '@core/network' +import { PersistedTransaction, buildPersistedEvmTransactionFromBlockscoutTransaction } from '@core/transactions' +import { ActivityType } from '../enums' +import { Activity, PersistedEvmTransaction } from '../types' +import { generateNftActivity } from './evm/generateNftActivity' +import { generateSmartContractActivity } from './evm/generateSmartContractActivity' +import { generateTokenActivity } from './evm/generateTokenActivity' + +export async function generateActivityFromPersistedTransaction( + persistedTransaction: PersistedTransaction, + chain: IChain, + account: IAccountState +): Promise { + const transaction = persistedTransaction.blockscout + ? buildPersistedEvmTransactionFromBlockscoutTransaction(persistedTransaction.blockscout) + : (persistedTransaction.local as PersistedEvmTransaction) + const transferInfo = getTransferInfoFromTransactionData(transaction, chain) + if (transferInfo?.type === ActivityType.SmartContract) { + return generateSmartContractActivity(transaction, chain, account) + } else if (transferInfo?.type === ActivityType.Basic) { + const { tokenId, rawAmount, additionalBaseTokenAmount, recipientAddress } = transferInfo + return generateTokenActivity( + transaction, + chain, + tokenId, + rawAmount, + additionalBaseTokenAmount, + recipientAddress, + account + ) + } else if (transferInfo?.type === ActivityType.Nft) { + const { nftId, additionalBaseTokenAmount, recipientAddress } = transferInfo + return generateNftActivity(transaction, chain, nftId, additionalBaseTokenAmount, recipientAddress, account) + } +} diff --git a/packages/shared/src/lib/core/transactions/index.ts b/packages/shared/src/lib/core/transactions/index.ts new file mode 100644 index 0000000000..ce4acb574a --- /dev/null +++ b/packages/shared/src/lib/core/transactions/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export * from './utils' diff --git a/packages/shared/src/lib/core/transactions/stores/transactions.store.ts b/packages/shared/src/lib/core/transactions/stores/transactions.store.ts index 9e93583963..36833c1b59 100644 --- a/packages/shared/src/lib/core/transactions/stores/transactions.store.ts +++ b/packages/shared/src/lib/core/transactions/stores/transactions.store.ts @@ -5,20 +5,7 @@ import { IChain } from '@core/network/interfaces' import { activeProfileId } from '@core/profile/stores' import { persistent } from '@core/utils/store' import { get } from 'svelte/store' - -type PersistedTransaction = - | { - blockscout: IBlockscoutTransaction - local: PersistedEvmTransaction - } - | { - blockscout?: IBlockscoutTransaction - local: PersistedEvmTransaction - } - | { - blockscout: IBlockscoutTransaction - local?: PersistedEvmTransaction - } +import { PersistedTransaction } from '../types/' type PersistedTransactions = { [profileId: string]: { @@ -30,7 +17,7 @@ type PersistedTransactions = { } } -export const persistedTransactions = persistent('transactions', {}) +export const persistedTransactions = persistent('', {}) export function getPersistedTransactionsForChain( profileId: string, diff --git a/packages/shared/src/lib/core/transactions/types/index.ts b/packages/shared/src/lib/core/transactions/types/index.ts new file mode 100644 index 0000000000..70393aef19 --- /dev/null +++ b/packages/shared/src/lib/core/transactions/types/index.ts @@ -0,0 +1 @@ +export * from './persisted-transaction.type' diff --git a/packages/shared/src/lib/core/transactions/types/persisted-transaction.type.ts b/packages/shared/src/lib/core/transactions/types/persisted-transaction.type.ts new file mode 100644 index 0000000000..bea7cb573b --- /dev/null +++ b/packages/shared/src/lib/core/transactions/types/persisted-transaction.type.ts @@ -0,0 +1,16 @@ +import { IBlockscoutTransaction } from '@auxiliary/blockscout/interfaces' +import { PersistedEvmTransaction } from '@core/activity' + +export type PersistedTransaction = + | { + blockscout: IBlockscoutTransaction + local: PersistedEvmTransaction + } + | { + blockscout?: IBlockscoutTransaction + local: PersistedEvmTransaction + } + | { + blockscout: IBlockscoutTransaction + local?: PersistedEvmTransaction + } diff --git a/packages/shared/src/lib/core/transactions/utils/buildPersistedEvmTransactionFromBlockscoutTransaction.ts b/packages/shared/src/lib/core/transactions/utils/buildPersistedEvmTransactionFromBlockscoutTransaction.ts new file mode 100644 index 0000000000..ea5d508ff4 --- /dev/null +++ b/packages/shared/src/lib/core/transactions/utils/buildPersistedEvmTransactionFromBlockscoutTransaction.ts @@ -0,0 +1,45 @@ +import { IBlockscoutTransaction, BlockscoutTransactionStatus } from '@auxiliary/blockscout' +import { PersistedEvmTransaction } from '@core/activity' +import { LegacyTxData, TransactionType } from '@ethereumjs/tx' +import { TransactionReceipt } from 'web3-core' + +export function buildPersistedEvmTransactionFromBlockscoutTransaction( + blockscoutTransaction: IBlockscoutTransaction +): PersistedEvmTransaction { + const transactionReceipt: TransactionReceipt = { + status: blockscoutTransaction.status === BlockscoutTransactionStatus.Ok ? true : false, + transactionHash: blockscoutTransaction.hash, + transactionIndex: blockscoutTransaction.position, + blockHash: '', // Unknown + blockNumber: blockscoutTransaction.block, + from: blockscoutTransaction.from.hash.toLowerCase(), + to: blockscoutTransaction.to.hash.toLowerCase(), + // contractAddress?: string, + cumulativeGasUsed: Number(blockscoutTransaction.gas_used), // Not sure if this is the right field + gasUsed: Number(blockscoutTransaction.gas_used), + effectiveGasPrice: Number(blockscoutTransaction.gas_price), + logs: [], + logsBloom: '', + // events?: { + // [eventName: string]: EventLog, + // }, + } + + const transactionData: LegacyTxData & { estimatedGas?: number; timestamp?: number } = { + type: TransactionType.Legacy, + ...(blockscoutTransaction.nonce && { nonce: blockscoutTransaction.nonce }), + ...(blockscoutTransaction.gas_price && { gasPrice: blockscoutTransaction.gas_price }), + ...(blockscoutTransaction.gas_limit && { gasLimit: blockscoutTransaction.gas_limit }), + // to?: AddressLike, // already set in transactionReceipt + ...(blockscoutTransaction.value && { value: blockscoutTransaction.value }), + ...(blockscoutTransaction.raw_input && + blockscoutTransaction.raw_input !== '0x' && { data: blockscoutTransaction.raw_input }), // Not sure if this is the right field + + // estimatedGas?: number, // No way to know this for fetched transactions + ...(blockscoutTransaction.timestamp && { timestamp: new Date(blockscoutTransaction.timestamp).getTime() }), + } + return { + ...transactionReceipt, + ...transactionData, + } as PersistedEvmTransaction +} diff --git a/packages/shared/src/lib/core/transactions/utils/index.ts b/packages/shared/src/lib/core/transactions/utils/index.ts new file mode 100644 index 0000000000..72ca9303db --- /dev/null +++ b/packages/shared/src/lib/core/transactions/utils/index.ts @@ -0,0 +1 @@ +export * from './buildPersistedEvmTransactionFromBlockscoutTransaction'