Skip to content

Commit 969f7d6

Browse files
committed
feat: add date filters to transactions endpoint
1 parent f546495 commit 969f7d6

File tree

12 files changed

+202
-115
lines changed

12 files changed

+202
-115
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ NODE_URL=https://public-node.testnet.rsk.co
66
NODE_MAINNET_URL=https://public-node.rsk.co
77
CYPHER_ESTIMATE_FEE_URL=https://api.blockcypher.com/v1/btc/test3
88
CYPHER_ESTIMATE_FEE_MAINNET_URL=https://api.blockcypher.com/v1/btc/main
9-
# API_URL=https://rootstock-testnet.blockscout.com/api
9+
API_URL=https://rootstock-testnet.blockscout.com/api

src/api/openapi.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ module.exports = {
8585
required: false,
8686
schema: { type: 'string' }
8787
},
88+
{
89+
name: 'startTimestamp',
90+
in: 'query',
91+
description: 'starting block unix timestamp.',
92+
required: false,
93+
schema: {
94+
type: 'string'
95+
}
96+
},
97+
{
98+
name: 'endTimestamp',
99+
in: 'query',
100+
description: 'ending block unix timestamp.',
101+
required: false,
102+
schema: {
103+
type: 'string'
104+
}
105+
},
88106
{
89107
name: 'limit',
90108
in: 'query',
@@ -295,6 +313,24 @@ module.exports = {
295313
default: '0'
296314
}
297315
},
316+
{
317+
name: 'startTimestamp',
318+
in: 'query',
319+
description: 'starting block unix timestamp.',
320+
required: false,
321+
schema: {
322+
type: 'string'
323+
}
324+
},
325+
{
326+
name: 'endTimestamp',
327+
in: 'query',
328+
description: 'ending block unix timestamp.',
329+
required: false,
330+
schema: {
331+
type: 'string'
332+
}
333+
},
298334
{
299335
name: 'prev',
300336
in: 'query',

src/blockscoutApi/index.ts

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import _axios from 'axios'
22
import { DataSource } from '../repository/DataSource'
33
import {
4-
BalanceServerResponse, InternalTransactionResponse, ServerResponse, TokenBalanceServerResponse,
5-
TokenServerResponse, TokenTransferApi, TransactionServerResponse,
6-
TransactionsServerResponse
4+
BalanceServerResponse, BlockResponse, InternalTransaction, ServerResponse, TokenBalanceServerResponse,
5+
TokenServerResponse, TokenTransferApi, TransactionResponse
76
} from './types'
87
import {
98
fromApiToInternalTransaction, fromApiToRtbcBalance, fromApiToTEvents,
@@ -22,6 +21,18 @@ export class BlockscoutAPI extends DataSource {
2221
this.chainId = chainId
2322
}
2423

24+
getBlockNumberByTimestamp (timestamp: number, timeDirection: string) {
25+
const params = {
26+
module: 'block',
27+
action: 'getblocknobytime',
28+
timestamp,
29+
closest: timeDirection
30+
}
31+
return this.axios?.get<ServerResponse<BlockResponse>>(this.url, { params })
32+
.then(response => response.data.result.blockNumber)
33+
.catch(() => '0')
34+
}
35+
2536
getTokens () {
2637
return this.axios?.get<TokenServerResponse>(`${this.url}/v2/tokens`)
2738
.then(response => response.data.items
@@ -47,13 +58,15 @@ export class BlockscoutAPI extends DataSource {
4758
.catch(this.errorHandling)
4859
}
4960

50-
async getEventsByAddress (address: string) {
61+
async getEventsByAddress (address: string, limit?: string, startBlock?: number, endBlock?: number) {
5162
const params = {
5263
module: 'account',
5364
action: 'tokentx',
54-
address: address.toLowerCase()
65+
address: address.toLowerCase(),
66+
...(startBlock && { startblock: startBlock }),
67+
...(endBlock && { endblock: endBlock })
5568
}
56-
return this.axios?.get<ServerResponse<TokenTransferApi>>(`${this.url}`, { params })
69+
return this.axios?.get<ServerResponse<TokenTransferApi[]>>(`${this.url}`, { params })
5770
.then(response =>
5871
response.data.result
5972
.map(tokenTranfer => {
@@ -63,25 +76,48 @@ export class BlockscoutAPI extends DataSource {
6376
}
6477

6578
getTransaction (hash: string) {
66-
return this.axios?.get<TransactionServerResponse>(`${this.url}/v2/transactions/${hash}`)
79+
const params = {
80+
module: 'transaction',
81+
action: 'gettxinfo',
82+
txhash: hash
83+
}
84+
return this.axios?.get<ServerResponse<TransactionResponse>>(`${this.url}`, { params })
6785
.then(response =>
68-
fromApiToTransaction(response.data))
86+
fromApiToTransaction(response.data.result))
6987
.catch(this.errorHandling)
7088
}
7189

72-
getInternalTransactionByAddress (address: string) {
73-
return this.axios?.get<InternalTransactionResponse>(
74-
`${this.url}/v2/addresses/${address.toLowerCase()}/internal-transactions`
75-
)
76-
.then(response => response.data.items.map(fromApiToInternalTransaction))
90+
getInternalTransactionByAddress (address: string, limit?: string, startBlock?: number, endBlock?: number) {
91+
const params = {
92+
module: 'account',
93+
action: 'txlistinternal',
94+
address,
95+
...(startBlock && { startblock: startBlock }),
96+
...(endBlock && { endblock: endBlock })
97+
}
98+
return this.axios?.get<ServerResponse<InternalTransaction[]>>(this.url, { params })
99+
.then(response => response.data.result.map(fromApiToInternalTransaction))
77100
.catch(this.errorHandling)
78101
}
79102

80-
getTransactionsByAddress (address: string) {
81-
return this.axios?.get<TransactionsServerResponse>(
82-
`${this.url}/v2/addresses/${address.toLowerCase()}/transactions`
103+
getTransactionsByAddress (address: string, limit?: string,
104+
prev?: string,
105+
next?: string,
106+
blockNumber?: string,
107+
startTimestamp?: number,
108+
endTimestamp?: number) {
109+
const params = {
110+
module: 'account',
111+
action: 'txlist',
112+
startblock: blockNumber,
113+
address: address.toLowerCase(),
114+
...(startTimestamp && { start_timestamp: startTimestamp }),
115+
...(endTimestamp && { end_timestamp: endTimestamp })
116+
}
117+
return this.axios?.get<ServerResponse<TransactionResponse[]>>(
118+
`${this.url}`, { params }
83119
)
84-
.then(response => ({ data: response.data.items.map(fromApiToTransaction) }))
120+
.then(response => ({ data: response.data.result.map(fromApiToTransaction) }))
85121
.catch(this.errorHandling)
86122
}
87123
}

src/blockscoutApi/types.ts

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -110,60 +110,46 @@ export interface DecodedInput {
110110
}
111111

112112
export interface InternalTransaction {
113-
block: number
114-
created_contract: any
115-
error: any
116-
from: Account
117-
gas_limit: string
118-
index: number
119-
success: boolean
120-
timestamp: string
121-
to: Account
122-
transaction_hash: string
113+
blockNumber: string
114+
callType: string
115+
contractAddress: string
116+
errCode: string
117+
from: string
118+
gas: string
119+
gasUsed: string
120+
index: string
121+
input: string
122+
isError: string
123+
timeStamp: string
124+
to: string
125+
transactionHash: string
123126
type: string
124127
value: string
125128
}
126129

127-
export interface TransactionServerResponse {
128-
timestamp: string
129-
fee: Fee
130-
gas_limit: string
131-
block: number
132-
status: string
133-
method: string
134-
confirmations: number
135-
type: number
136-
exchange_rate: any
137-
to: Account
138-
tx_burnt_fee: any
139-
max_fee_per_gas: any
140-
result: string
130+
export interface TransactionResponse {
131+
blockHash: string
132+
blockNumber: string
133+
confirmations: string
134+
contractAddress: string
135+
cumulativeGasUsed: string
136+
from: string
137+
gas: string
138+
gasPrice: string
139+
gasUsed: string
141140
hash: string
142-
gas_price: string
143-
priority_fee: any
144-
base_fee_per_gas: any
145-
from: Account
146-
token_transfers: TokenTransfer[]
147-
tx_types: string[]
148-
gas_used: string
149-
created_contract: any
150-
position: number
151-
nonce: number
152-
has_error_in_internal_txs: boolean
153-
actions: any[]
154-
decoded_input: DecodedInput
155-
token_transfers_overflow: boolean
156-
raw_input: string
141+
input: string
142+
isError: string
143+
nonce: string
144+
timeStamp: string
145+
to: string
146+
transactionIndex: string
147+
txreceipt_status: string
157148
value: string
158-
max_priority_fee_per_gas: any
159-
revert_reason: any
160-
confirmation_duration: number[]
161-
tx_tag: any
162149
}
163150

164-
export interface TransactionsServerResponse {
165-
items: TransactionServerResponse[]
166-
next_page_params: NextPageParams
151+
export interface BlockResponse {
152+
blockNumber: string
167153
}
168154

169155
export interface BalanceServerResponse {
@@ -229,5 +215,5 @@ export interface TokenTransferApi {
229215
export interface ServerResponse<T> {
230216
message: string
231217
status: string
232-
result: T[]
218+
result: T
233219
}

src/blockscoutApi/utils.ts

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
IApiToken, ITokenWithBalance, InternalTransaction,
3-
Token, TokenTransferApi, TransactionServerResponse
3+
Token, TokenTransferApi, TransactionResponse
44
} from './types'
55
import tokens from '@rsksmart/rsk-contract-metadata'
66
import { toChecksumAddress } from '@rsksmart/rsk-utils'
@@ -126,68 +126,70 @@ export const fromApiToTEvents = (tokenTransfer:TokenTransferApi): IEvent =>
126126
txStatus: '0x1'
127127
})
128128

129-
export const fromApiToTransaction = (transaction: TransactionServerResponse): ITransaction =>
130-
({
129+
export const fromApiToTransaction = (transaction: TransactionResponse): ITransaction => {
130+
const txType = transaction.input === '0x' ? 'normal' : 'contract call'
131+
return ({
131132
_id: '',
132133
hash: transaction.hash,
133-
nonce: transaction.nonce,
134-
blockHash: '',
135-
blockNumber: transaction.block,
134+
nonce: Number(transaction.nonce),
135+
blockHash: transaction.blockHash,
136+
blockNumber: Number(transaction.blockNumber),
136137
transactionIndex: 0,
137-
from: transaction.from.hash,
138-
to: transaction.to.hash,
139-
gas: Number(transaction.gas_used),
140-
gasPrice: transaction.gas_price,
138+
from: transaction.from,
139+
to: transaction.to,
140+
gas: Number(transaction.gas),
141+
gasPrice: transaction.gasPrice,
141142
value: transaction.value,
142-
input: transaction.raw_input,
143+
input: transaction.input,
143144
v: '',
144145
r: '',
145146
s: '',
146-
type: String(transaction.type),
147-
timestamp: Date.parse(transaction.timestamp) / 1000,
147+
type: String(),
148+
timestamp: Number(transaction.timeStamp),
148149
receipt: {
149150
transactionHash: transaction.hash,
150151
transactionIndex: 0,
151152
blockHash: '',
152-
blockNumber: transaction.block,
153-
cumulativeGasUsed: Number(transaction.gas_limit),
154-
gasUsed: Number(transaction.gas_used),
153+
blockNumber: Number(transaction.blockNumber),
154+
cumulativeGasUsed: Number(transaction.gasUsed),
155+
gasUsed: Number(transaction.gasUsed),
155156
contractAddress: null,
156157
logs: [],
157-
from: transaction.from.hash,
158-
to: transaction.to.hash,
159-
status: transaction.status === 'ok' ? '0x1' : '0x0',
158+
from: transaction.from,
159+
to: transaction.to,
160+
status: transaction.txreceipt_status === '1' ? '0x1' : '0x0',
160161
logsBloom: '',
161-
type: String(transaction.type)
162+
type: txType
162163
},
163-
txType: transaction.tx_types[0],
164+
txType,
164165
txId: ''
165166
})
167+
}
166168

167169
export const fromApiToInternalTransaction = (internalTransaction: InternalTransaction): IInternalTransaction =>
168170
({
169171
_id: '',
170172
action: {
171173
callType: internalTransaction.type,
172-
from: internalTransaction.from.hash,
173-
to: internalTransaction.to.hash,
174+
from: internalTransaction.from,
175+
to: internalTransaction.to,
174176
value: internalTransaction.value,
175-
gas: internalTransaction.gas_limit,
177+
gas: internalTransaction.gas,
176178
input: '0x'
177179
},
178180
blockHash: '',
179-
blockNumber: internalTransaction.block,
180-
transactionHash: internalTransaction.transaction_hash,
181-
transactionPosition: internalTransaction.index,
181+
blockNumber: Number(internalTransaction.blockNumber),
182+
transactionHash: internalTransaction.transactionHash,
183+
transactionPosition: Number(internalTransaction.index),
182184
type: internalTransaction.type,
183185
subtraces: 0,
184186
traceAddress: [],
185187
result: {
186-
gasUsed: internalTransaction.gas_limit,
188+
gasUsed: internalTransaction.gasUsed,
187189
output: '0x'
188190
},
189-
_index: internalTransaction.index,
190-
timestamp: Date.parse(internalTransaction.timestamp) / 1000,
191+
_index: Number(internalTransaction.index),
192+
timestamp: Date.parse(internalTransaction.timeStamp) / 1000,
191193
internalTxId: ''
192194
})
193195

0 commit comments

Comments
 (0)