Skip to content

Commit 8548c76

Browse files
feat: add getAccountHistoricalTransactions
1 parent 6f35dd1 commit 8548c76

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

apps/evm/src/clients/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,6 @@ export * from './queries/getImportablePositions/useGetImportablePositions';
231231

232232
export * from './queries/getAccountPerformanceHistory';
233233
export * from './queries/getAccountPerformanceHistory/useGetAccountPerformanceHistory';
234+
235+
export * from './queries/getAccountTransactionHistory';
236+
export * from './queries/getAccountTransactionHistory/useGetAccountTransactionHistory';
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { Token } from 'types';
2+
import {
3+
convertDollarsToCents,
4+
convertMantissaToTokens,
5+
convertPriceMantissaToDollars,
6+
} from 'utilities';
7+
import type { Address } from 'viem';
8+
import type { AmountTransaction, ApiAccountHistoricalTransaction } from './types';
9+
10+
export const formatApiTransaction = ({
11+
contractToTokenMap,
12+
apiTransaction,
13+
}: {
14+
contractToTokenMap: Record<
15+
Address,
16+
{
17+
token: Token;
18+
poolName: string;
19+
}
20+
>;
21+
apiTransaction: ApiAccountHistoricalTransaction;
22+
}): AmountTransaction => {
23+
const {
24+
txType,
25+
txHash: hash,
26+
txTimestamp,
27+
blockNumber,
28+
accountAddress,
29+
contractAddress,
30+
chainId,
31+
amountUnderlyingMantissa,
32+
underlyingTokenPriceMantissa,
33+
} = apiTransaction;
34+
const { poolName, token } = contractToTokenMap[contractAddress];
35+
const tokenPriceDollars = underlyingTokenPriceMantissa
36+
? convertPriceMantissaToDollars({
37+
priceMantissa: underlyingTokenPriceMantissa,
38+
decimals: token.decimals,
39+
})
40+
: undefined;
41+
const tokenPriceCents = tokenPriceDollars ? convertDollarsToCents(tokenPriceDollars) : undefined;
42+
const amountTokens = amountUnderlyingMantissa
43+
? convertMantissaToTokens({
44+
value: BigInt(amountUnderlyingMantissa),
45+
token: token,
46+
})
47+
: undefined;
48+
const amountCents =
49+
amountTokens && tokenPriceCents ? amountTokens.multipliedBy(tokenPriceCents) : undefined;
50+
51+
return {
52+
txType,
53+
hash,
54+
blockTimestamp: txTimestamp,
55+
blockNumber,
56+
accountAddress,
57+
contractAddress,
58+
chainId,
59+
poolName,
60+
amountTokens,
61+
amountCents,
62+
token,
63+
};
64+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { VError } from 'libs/errors';
2+
import type { Token } from 'types';
3+
import { restService } from 'utilities';
4+
import { type Address, isAddress } from 'viem';
5+
import { formatApiTransaction } from './formatApiTransaction';
6+
import type {
7+
AccountTransactionHistoryApiResponse,
8+
GetAccountTransactionHistoryInput,
9+
GetAccountTransactionHistoryOutput,
10+
} from './types';
11+
12+
export * from './types';
13+
14+
export const getAccountTransactionHistory = async ({
15+
chainId,
16+
accountAddress,
17+
contractAddress,
18+
getPoolsData,
19+
type,
20+
page,
21+
}: GetAccountTransactionHistoryInput): Promise<GetAccountTransactionHistoryOutput> => {
22+
const txsResponse = await restService<AccountTransactionHistoryApiResponse>({
23+
endpoint: `/account/${accountAddress}/transactions`,
24+
method: 'GET',
25+
params: {
26+
chainId,
27+
type,
28+
contractAddress: isAddress(contractAddress) ? contractAddress : undefined,
29+
page,
30+
},
31+
});
32+
33+
if (txsResponse.data && 'error' in txsResponse.data) {
34+
throw new VError({
35+
type: 'unexpected',
36+
code: 'somethingWentWrong',
37+
data: { message: txsResponse.data.error },
38+
});
39+
}
40+
41+
if (!txsResponse.data) {
42+
throw new VError({ type: 'unexpected', code: 'somethingWentWrong' });
43+
}
44+
45+
const allAssets =
46+
getPoolsData?.pools.flatMap(p =>
47+
p.assets.map(a => ({
48+
...a,
49+
poolName: p.name,
50+
})),
51+
) || [];
52+
53+
const contractToTokenMap = allAssets.reduce<Record<Address, { token: Token; poolName: string }>>(
54+
(acc, a) => {
55+
const { poolName, vToken } = a;
56+
57+
return {
58+
...acc,
59+
[vToken.address.toLowerCase()]: {
60+
poolName,
61+
token: vToken.underlyingToken,
62+
},
63+
};
64+
},
65+
{},
66+
);
67+
68+
const formattedResponse = txsResponse.data.results.map(apiTransaction =>
69+
formatApiTransaction({
70+
contractToTokenMap,
71+
apiTransaction,
72+
}),
73+
);
74+
75+
return {
76+
count: Number(txsResponse.data.count),
77+
transactions: formattedResponse,
78+
};
79+
};
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { ChainId } from '@venusprotocol/chains';
2+
import type { Token } from 'types';
3+
import type { Address } from 'viem';
4+
import type { GetPoolsOutput } from '../useGetPools/types';
5+
6+
export enum TxType {
7+
Mint = 'mint',
8+
Borrow = 'borrow',
9+
Redeem = 'redeem',
10+
Repay = 'repay',
11+
EnterMarket = 'enter_market',
12+
ExitMarket = 'exit_market',
13+
Approve = 'approve',
14+
}
15+
16+
export interface ApiAccountHistoricalTransaction {
17+
id: string;
18+
txHash: string;
19+
txIndex: number;
20+
txTimestamp: Date;
21+
blockNumber: string;
22+
txType: TxType;
23+
accountAddress: Address;
24+
contractAddress: Address;
25+
amountVTokenMantissa: string | null;
26+
amountUnderlyingMantissa: string | null;
27+
underlyingAddress: string;
28+
underlyingTokenPriceMantissa: string | null;
29+
chainId: ChainId;
30+
}
31+
32+
export interface AmountTransaction {
33+
txType: TxType;
34+
hash: string;
35+
blockTimestamp: Date;
36+
blockNumber: string;
37+
accountAddress: string;
38+
contractAddress: string;
39+
chainId: ChainId;
40+
poolName: string;
41+
amountTokens: BigNumber | undefined;
42+
amountCents: BigNumber | undefined;
43+
token: Token;
44+
}
45+
46+
export interface AccountTransactionHistoryApiResponse {
47+
count: number;
48+
results: ApiAccountHistoricalTransaction[];
49+
}
50+
51+
export interface GetAccountTransactionHistoryInput {
52+
accountAddress: string;
53+
contractAddress: string;
54+
chainId: ChainId;
55+
getPoolsData: GetPoolsOutput | undefined;
56+
type?: number;
57+
page?: number;
58+
}
59+
60+
export type GetAccountTransactionHistoryOutput = {
61+
count: number;
62+
transactions: AmountTransaction[];
63+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { type QueryObserverOptions, useQuery } from '@tanstack/react-query';
2+
3+
import FunctionKey from 'constants/functionKey';
4+
import { useChainId } from 'libs/wallet';
5+
import {
6+
type GetAccountTransactionHistoryInput,
7+
type GetAccountTransactionHistoryOutput,
8+
getAccountTransactionHistory,
9+
} from '.';
10+
import { useGetPools } from '../useGetPools';
11+
12+
type TrimmedGetAccountTransactionHistoryInput = Omit<
13+
GetAccountTransactionHistoryInput,
14+
'chainId' | 'getPoolsData'
15+
>;
16+
17+
type Options = QueryObserverOptions<
18+
GetAccountTransactionHistoryOutput,
19+
Error,
20+
GetAccountTransactionHistoryOutput,
21+
GetAccountTransactionHistoryOutput,
22+
[FunctionKey.GET_ACCOUNT_HISTORICAL_TRANSACTIONS, TrimmedGetAccountTransactionHistoryInput]
23+
>;
24+
25+
export const useGetAccountTransactionHistory = (
26+
params: TrimmedGetAccountTransactionHistoryInput,
27+
options?: Partial<Options>,
28+
) => {
29+
const { chainId } = useChainId();
30+
const { data: getPoolsData } = useGetPools();
31+
const extendedParams = {
32+
...params,
33+
getPoolsData,
34+
chainId,
35+
};
36+
37+
return useQuery({
38+
queryKey: [FunctionKey.GET_ACCOUNT_HISTORICAL_TRANSACTIONS, params],
39+
queryFn: () => getAccountTransactionHistory(extendedParams),
40+
...options,
41+
});
42+
};

apps/evm/src/constants/functionKey.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ enum FunctionKey {
6969
GET_IMPORTABLE_POSITIONS = 'GET_IMPORTABLE_POSITIONS',
7070
GET_ACCOUNT_PERFORMANCE_HISTORY = 'GET_ACCOUNT_PERFORMANCE_HISTORY',
7171
GET_ENABLED_E_MODE_GROUP = 'GET_ENABLED_E_MODE_GROUP',
72+
GET_ACCOUNT_HISTORICAL_TRANSACTIONS = 'GET_ACCOUNT_HISTORICAL_TRANSACTIONS',
7273
}
7374

7475
export default FunctionKey;

0 commit comments

Comments
 (0)