Skip to content

Commit

Permalink
DAO-528 Fixed transactions crashing due to .to.hash not being existen…
Browse files Browse the repository at this point in the history
…t. Created new endpoint to fetch events by topic0 from an address. This is used to fetch governor ProposalCreated event - openapi.js implementation is pending. (#152)
  • Loading branch information
Freshenext authored Jul 13, 2024
1 parent 16e3a91 commit 51625d3
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 2 deletions.
27 changes: 27 additions & 0 deletions src/blockscoutApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
fromApiToInternalTransaction, fromApiToNft, fromApiToNftOwner, fromApiToRtbcBalance, fromApiToTEvents,
fromApiToTokenWithBalance, fromApiToTokens, fromApiToTransaction
} from './utils'
import { GetEventLogsByAddressAndTopic0 } from '../service/address/AddressService'

export class BlockscoutAPI extends DataSource {
private chainId: number
Expand Down Expand Up @@ -118,4 +119,30 @@ export class BlockscoutAPI extends DataSource {
}
return fromApiToNftOwner(address, [...(response?.items || []), ...items])
}

async getEventLogsByAddressAndTopic0 ({
address, topic0, toBlock = 'latest', fromBlock
}: Omit<GetEventLogsByAddressAndTopic0, 'chainId'>) {
let fromBlockToUse = fromBlock
if (!fromBlock) {
const tx = await this.getTransactionsByAddress(address)
// @ts-ignore ignored because it's using never as type
const lastTx = tx.data.pop() // The last tx is the first transaction

if (lastTx) fromBlockToUse = lastTx.blockNumber
}

if (!fromBlockToUse) return []
const params = {
module: 'logs',
action: 'getLogs',
address: address.toLowerCase(),
toBlock,
fromBlock: fromBlockToUse,
topic0
}
return this.axios?.get<ServerResponse<TokenTransferApi>>(`${this.url}`, { params })
.then(({ data }) => data.result)
.catch(() => [])
}
}
4 changes: 2 additions & 2 deletions src/blockscoutApi/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export const fromApiToTransaction = (transaction: TransactionServerResponse): IT
blockNumber: transaction.block,
transactionIndex: 0,
from: transaction.from.hash,
to: transaction.to.hash,
to: transaction.to?.hash,
gas: Number(transaction.gas_used),
gasPrice: transaction.gas_price,
value: transaction.value,
Expand All @@ -167,7 +167,7 @@ export const fromApiToTransaction = (transaction: TransactionServerResponse): IT
contractAddress: null,
logs: [],
from: transaction.from.hash,
to: transaction.to.hash,
to: transaction.to?.hash,
status: transaction.status === 'ok' ? '0x1' : '0x0',
logsBloom: '',
type: String(transaction.type)
Expand Down
21 changes: 21 additions & 0 deletions src/controller/httpsAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,27 @@ export class HttpsAPI {
}
})

this.app.get('/address/:address/eventsByTopic0',
async ({ params: { address }, query: { chainId = '31', topic0, fromBlock, toBlock } } : Request, res: Response,
nextFunction: NextFunction) => {
try {
chainIdSchema.validateSync({ chainId })
addressSchema.validateSync({ address })
const result = await this.addressService
.getEventLogsByAddressAndTopic0({
chainId: chainId as string,
address: address as string,
topic0: topic0 as string,
fromBlock: fromBlock as string,
toBlock: toBlock as string
})
.catch(nextFunction)
return this.responseJsonOk(res)(result)
} catch (e) {
this.handleValidationError(e, res)
}
})

this.app.get(
'/price',
async (req: Request<{}, {}, {}, PricesQueryParams>, res: Response) => {
Expand Down
3 changes: 3 additions & 0 deletions src/repository/DataSource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _axios from 'axios'
import { ethers } from 'ethers'
import BitcoinCore from '../service/bitcoin/BitcoinCore'
import { GetEventLogsByAddressAndTopic0 } from '../service/address/AddressService'

export abstract class DataSource {
readonly url: string
Expand All @@ -27,6 +28,8 @@ export abstract class DataSource {

abstract getNft(address: string);
abstract getNftOwnedByAddress(address: string, nft: string);
abstract getEventLogsByAddressAndTopic0({ address, topic0, toBlock, fromBlock } :
Omit<GetEventLogsByAddressAndTopic0, 'chainId'>);
}

export type RSKDatasource = {
Expand Down
4 changes: 4 additions & 0 deletions src/rskExplorerApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,8 @@ export class RSKExplorerAPI extends DataSource {
getNftOwnedByAddress () {
throw new Error('Feature not supported')
}

getEventLogsByAddressAndTopic0 () {
throw new Error('Feature not supported')
}
}
13 changes: 13 additions & 0 deletions src/service/address/AddressService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ interface GetNftsByAddress extends GetTokensByAddress {
nftAddress: string
}

export interface GetEventLogsByAddressAndTopic0 {
address: string
topic0: string
toBlock: string
chainId: string
fromBlock?: string
}

type GetBalancesTransactionsPricesByAddress = {
chainId: string
address: string
Expand Down Expand Up @@ -139,4 +147,9 @@ export class AddressService {
const dataSource = this.dataSourceMapping[chainId]
return dataSource.getNftOwnedByAddress(address, nftAddress)
}

async getEventLogsByAddressAndTopic0 ({ chainId, ...rest }: GetEventLogsByAddressAndTopic0) {
const dataSource = this.dataSourceMapping[chainId]
return dataSource.getEventLogsByAddressAndTopic0(rest)
}
}

0 comments on commit 51625d3

Please sign in to comment.