Merge pull request #170 from ArtemKolodko/refactor_export_to_csv

Use etherscan format to export transactions to CSV
pull/176/head
Artem 3 years ago committed by GitHub
commit 3d238c572d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      src/components/ui/utils.tsx
  2. 50
      src/pages/ExportData/export-utils.ts
  3. 11
      src/pages/ExportData/index.tsx
  4. 4
      src/types/blockchain.ts
  5. 21
      src/utils/fee.ts

@ -1,6 +1,7 @@
import Big from "big.js";
import React from "react";
import { useONEExchangeRate } from "src/hooks/useONEExchangeRate";
import { calculateFee } from "../../utils/fee";
export function formatNumber(
num: number,
@ -67,23 +68,12 @@ export function CalculateFee(transaction: any) {
}
export function CalculateTransactionFee(transaction: any) {
const { lastPrice } = useONEExchangeRate();
const fee =
isNaN(transaction.gas) || isNaN(transaction.gasPrice)
? 0
: (Number(transaction.gas) * Number(transaction.gasPrice)) /
10 ** 14 /
10000;
const { lastPrice: price } = useONEExchangeRate();
const normalizedFee = Intl.NumberFormat("en-US", {
maximumFractionDigits: 18,
}).format(fee);
const price = lastPrice;
const fee = calculateFee(transaction.gas, transaction.gasPrice)
const bi =
(Big(normalizedFee) as unknown as number) /
(Big(fee) as unknown as number) /
(Big(10 ** 14) as unknown as any);
const v = parseInt(bi.toString()) / 10000;
let USDValue = "";
@ -98,7 +88,7 @@ export function CalculateTransactionFee(transaction: any) {
return (
<>
{normalizedFee} ONE
{fee} ONE
{!USDValue || USDValue === "0.00" || USDValue == "0" ? null : (
<>($ {USDValue})</>
)}

@ -1,5 +1,9 @@
const downloadBlob = (content: any, filename: string, contentType: string) => {
const blob = new Blob([content], { type: contentType });
import { RelatedTransaction } from "../../types";
import dayjs from "dayjs";
import { calculateFee, calculateFeePriceUSD } from "../../utils/fee";
const downloadBlob = (content: any, filename: string) => {
const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
// Create a link to download it
@ -9,9 +13,43 @@ const downloadBlob = (content: any, filename: string, contentType: string) => {
pom.click();
}
export const downloadCSV = (data: any[], filename: string) => {
const header= data.filter((_, index) => index === 0).map(item => Object.keys(item))
const body = data
const mapRelatedTxToExport = (ownerAddress: string, tx: RelatedTransaction, onePrice: number) => {
const txDate = dayjs(tx.timestamp)
const convertValue = (value: string | number, n = 4) => {
const precision = 18
const bigIntValue = BigInt(parseInt(value.toString())) / BigInt(10 ** (precision - n))
return parseInt(bigIntValue.toString()) / (10 ** n);
}
const isSender = ownerAddress === tx.from
return {
Txhash: tx.hash,
Blockno: tx.blockNumber,
UnixTimestamp: txDate.unix(),
DateTime: txDate.format('YYYY-MM-DD HH:MM:ss'),
From: tx.from,
To: tx.to,
['Value_IN(ONE)']: convertValue(isSender ? '0': tx.value),
['Value_OUT(ONE)']: convertValue(isSender ? tx.value : '0'),
[`CurrentValue @ $${onePrice}/ONE`]: convertValue(onePrice * +tx.value),
['TxnFee(ONE)']: calculateFee(tx.gas, tx.gasPrice),
['TxnFee(USD)']: calculateFeePriceUSD(tx.gas, tx.gasPrice, onePrice),
Method: tx.input.slice(0, 10)
}
}
export interface IDownloadCsvParams {
address: string
txs: RelatedTransaction[]
onePrice: number
}
export const downloadCSV = (params: IDownloadCsvParams, filename: string) => {
const { address, txs, onePrice} = params
const mappedTxs = txs.map((tx) => mapRelatedTxToExport(address, tx, onePrice))
const header = mappedTxs.filter((_, index) => index === 0).map(item => Object.keys(item))
const body = mappedTxs
.map((item) => Object.values(item))
const csv = [...header, ...body]
@ -23,5 +61,5 @@ export const downloadCSV = (data: any[], filename: string) => {
.join(', ') // comma-separated
).join('\r\n'); // rows starting on new lines
downloadBlob(csv, filename, 'text/csv;charset=utf-8;')
downloadBlob(csv, filename)
}

@ -8,6 +8,7 @@ import { getRelatedTransactionsByType } from "../../api/client";
import { downloadCSV } from "./export-utils";
import dayjs from "dayjs";
import { toaster } from "../../App";
import { useONEExchangeRate } from "../../hooks/useONEExchangeRate";
const IconError = styled(StatusCritical)`
margin-right: 5px;
@ -39,6 +40,7 @@ export const ExportData = () => {
const initialDateFrom = dayjs().startOf('month').format(dateFormat)
const initialDateTo = dayjs().format(dateFormat)
const { lastPrice } = useONEExchangeRate();
const [isDownloading, setIsDownloading] = useState(false)
const [dateFrom, setDateFrom] = useState(initialDateFrom)
const [dateTo, setDateTo] = useState(initialDateTo)
@ -46,7 +48,10 @@ export const ExportData = () => {
const dateInputProps = {
format: 'mm/dd/yyyy',
value: (new Date()).toISOString(),
calendarProps: { size: 'medium' },
calendarProps: {
size: 'medium',
bounds: [dayjs().subtract(5, 'year').format(dateFormat), dayjs().format(dateFormat)]
},
inputProps: { width: '170px' }
}
@ -80,13 +85,13 @@ export const ExportData = () => {
const onDownloadClicked = async () => {
try {
setIsDownloading(true)
const data = await getRelatedTransactionsByType([
const txs = await getRelatedTransactionsByType([
0,
address,
'transaction',
filter,
]);
downloadCSV(data, `export_${address}.csv`)
downloadCSV({ address, txs, onePrice: lastPrice }, `export_${address}.csv`)
} catch (e) {
console.error('Error on download:', (e as Error).message)
showErrorNotification()

@ -257,7 +257,7 @@ export interface RelatedTransaction {
transactionType: RelatedTransactionType;
address: string;
blockNumber: string;
transactionHash: string;
hash: string;
from: string;
to: string;
value: string;
@ -266,6 +266,8 @@ export interface RelatedTransaction {
msg?: { amount: string; delegatorAddress: string; validatorAddress: string };
amount?: string
input: string
gas: string
gasPrice: string
extraMark: TransactionExtraMark
}

@ -0,0 +1,21 @@
export const calculateFee = (gas: string, gasPrice: string) => {
const fee =
isNaN(+gas) || isNaN(+gasPrice)
? 0
: (Number(gas) * Number(gasPrice)) /
10 ** 14 /
10000;
return Intl.NumberFormat("en-US", {
maximumFractionDigits: 18,
}).format(fee);
}
export const calculateFeePriceUSD = (gas: string, gasPrice: string, onePrice: string | number) => {
const fee = calculateFee(gas, gasPrice)
return (+fee * +onePrice).toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 8,
currency: "USD",
})
}
Loading…
Cancel
Save