Skip to content

Commit

Permalink
Wrap got in fetchJson (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
hasparus authored Nov 12, 2021
1 parent d92585b commit 663a484
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { expect, mockFn } from 'earljs'
import { constants } from 'ethers'

import { parseAddress, UserEtherscanURLs } from '../../config'
import { FetchJson } from '../../peripherals/fetchJson'
import { Abi } from '../../types'
import { UserProvidedNetworkSymbol } from '../networks'
import { FetchAbi, getABIFromEtherscan } from './getAbiFromEtherscan'
import { EtherscanResponse, getABIFromEtherscan } from './getAbiFromEtherscan'

describe(getABIFromEtherscan.name, () => {
it('fetches from predefined etherscan URL', async () => {
Expand Down Expand Up @@ -42,11 +43,10 @@ const DAI_ADDRESS = parseAddress('0x6B175474E89094C44Da98b954EedeAC495271d0F')

const RETURNED_ABI = ['{{ RETURNED_ABI }}'] as Abi
function mockEndpoint() {
const fetch: FetchAbi = async (_url) => ({
body: JSON.stringify({
status: '1',
result: JSON.stringify(RETURNED_ABI),
}),
const fetch: FetchJson<EtherscanResponse> = async (_url) => ({
status: '1',
message: 'OK',
result: JSON.stringify(RETURNED_ABI),
})
return mockFn(fetch)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import got, { Response } from 'got'

import type { Address } from '../../config'
import { FetchJson, fetchJson } from '../../peripherals/fetchJson'
import type { Abi } from '../../types'
import type { URLString } from '../../utils/utility-types'
import { NetworkSymbol, symbolToNetworkId, UserProvidedNetworkSymbol } from '../networks'
Expand All @@ -11,30 +10,26 @@ export async function getABIFromEtherscan(
address: Address,
apiKey: string,
userNetworks: UserEtherscanURLs,
fetch: FetchAbi = got,
fetch: FetchJson<EtherscanResponse> = fetchJson,
): Promise<Abi> {
const apiUrl = getEtherscanLinkFromNetworkSymbol(networkSymbol, userNetworks)
if (!apiUrl) {
throw new Error(`Can't find network info for ${networkSymbol}`)
}

const url = `${apiUrl}?module=contract&action=getabi&address=${address}&apikey=${apiKey}`
const rawResponse = await fetch(url)
// @todo error handling for incorrect api keys
const jsonResponse = JSON.parse(rawResponse.body)
const response = await fetch(url)

if (jsonResponse.status !== '1') {
throw new Error(`Can't find mainnet abi for ${address}. Msg: ${rawResponse.body}`)
if (response.status !== '1') {
throw new Error(`Can't find mainnet abi for ${address}. Msg: ${JSON.stringify(response, null, 2)}`)
}

const abi = JSON.parse(jsonResponse.result) as Abi
const abi = JSON.parse(response.result) as Abi

return abi
}

/** @internal exported for tests only */
export type FetchAbi = (url: string) => Promise<Pick<Response<string>, 'body'>>

function getEtherscanLinkFromNetworkSymbol(
networkSymbol: NetworkSymbol,
userNetworks: UserEtherscanURLs,
Expand All @@ -54,3 +49,12 @@ function isUserProvidedNetwork(
): symbol is UserProvidedNetworkSymbol {
return symbol in userNetworks
}

/**
* @see https://docs.etherscan.io/api-endpoints/contracts
*/
export interface EtherscanResponse {
status: string
result: string
message: 'OK' | 'NOTOK'
}
5 changes: 5 additions & 0 deletions packages/eth-sdk/src/peripherals/fetchJson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import got from 'got'

export type FetchJson<T = any> = (url: string) => Promise<T>

export const fetchJson: FetchJson = (url: string) => got(url).json()

0 comments on commit 663a484

Please sign in to comment.