Skip to content

Commit

Permalink
feat(abi-fetcher): add support for blockscout
Browse files Browse the repository at this point in the history
  • Loading branch information
KABBOUCHI committed Sep 14, 2023
1 parent 8f5ff0e commit fbd6b8f
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@instadapp/utils",
"version": "0.4.10",
"version": "0.4.11",
"description": "",
"repository": "instadapp/utils",
"license": "MIT",
Expand Down
86 changes: 68 additions & 18 deletions src/abi/fetcher/AbiFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const DEFAULTS: IAbiFetcherOptions = {
gnosis: 'https://api.gnosisscan.io/api',
'polygon-zkevm': 'https://api-zkevm.polygonscan.com/api',
base: 'https://api.basescan.org/api'
},
networkToBlockscoutAPI: {
aurora: 'https://explorer.aurora.dev/graphiql',
fuse: 'https://explorer.fuse.io/graphiql'
}
}

Expand All @@ -47,8 +51,70 @@ export class AbiFetcher {
this.options = Object.assign({}, DEFAULTS, options)
}

private async fetchABI (contractAddress: string, network: Network): Promise<JsonFragment[]> {
const { networkToEtherscanAPI, networkToBlockscoutAPI } = this.options

if (networkToEtherscanAPI[network]) {
return await this.fetchABIFromEtherscan(contractAddress, network)
}

if (networkToBlockscoutAPI[network]) {
return await this.fetchABIFromBlockscout(contractAddress, network)
}

throw new Error(`Couldn't fetch ABI for ${contractAddress}`)
}

private async fetchABIFromEtherscan (contractAddress: string, network: Network): Promise<JsonFragment[]> {
const { retries, networkToEtherscanAPI, etherscanApiKey } = this.options

return await retry(
async () =>
await axios
.get(
networkToEtherscanAPI[network], {
params: {
module: 'contract',
action: 'getabi',
address: contractAddress,
apikey: etherscanApiKey ? etherscanApiKey[network] : undefined
}
}
)
.then(({ data }) => JSON.parse(data.result)),
{
retries
})
}

private async fetchABIFromBlockscout (contractAddress: string, network: Network): Promise<JsonFragment[]> {
const { retries, networkToBlockscoutAPI } = this.options

return await retry(
async () =>
await axios
.post(
networkToBlockscoutAPI[network],
{
query: `{\n address(hash:"${contractAddress}") {\n \tsmartContract {\n abi\n }\n }\t\n}`,
variables: null,
operationName: null
}
)
.then(({ data: { data } }) => {
if (data.errors) {
throw new Error(data.errors[0].message)
}

return JSON.parse(data.address.smartContract.abi)
}),
{
retries
})
}

private async _get (contractAddress: string, network: Network, metadata?: Record<string, any>): Promise<JsonFragment[]> {
const { cache, retries, networkToEtherscanAPI, etherscanApiKey } = this.options
const { cache } = this.options

try {
getAddress(contractAddress)
Expand All @@ -71,23 +137,7 @@ export class AbiFetcher {
}

try {
const abi = await retry(
async () =>
await axios
.get(
networkToEtherscanAPI[network], {
params: {
module: 'contract',
action: 'getabi',
address: contractAddress,
apikey: etherscanApiKey ? etherscanApiKey[network] : undefined
}
}
)
.then(({ data }) => JSON.parse(data.result)),
{
retries
})
const abi = await this.fetchABI(contractAddress, network)
if (cache) {
try {
await cache.set(`${network}:${contractAddress}`, abi, network, metadata)
Expand Down
8 changes: 8 additions & 0 deletions src/abi/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ export interface IAbiFetcherOptions {
}
*/
networkToEtherscanAPI: Partial<Record<Network, string>>,
/**
* @default
{
aurora: 'https://explorer.aurora.dev/graphiql',
fuse: 'https://explorer.fuse.io/graphiql',
}
*/
networkToBlockscoutAPI: Partial<Record<Network, string>>,
/**
* @default proxyAndImplementation
*/
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type Network = 'polygon' | 'mainnet' | 'fantom' | 'arbitrum' | 'avalanche' | 'optimism' | 'bsc' | 'gnosis' | string;
export type Network = 'polygon' | 'mainnet' | 'fantom' | 'arbitrum' | 'avalanche' | 'optimism' | 'bsc' | 'gnosis' | 'base' | 'aurora' | 'fuse'| string;
12 changes: 12 additions & 0 deletions test/abi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,16 @@ describe.concurrent('abi', () => {
type: 'event'
})
})

test('can fetch abi using blockscout - aurora', async () => {
const abi = await defaultAbiFetcher.get('0x4988a896b1227218e4A686fdE5EabdcAbd91571f', 'aurora', 'implementationOnly')

expect(abi.length).to.be.greaterThan(0)
})

test('can fetch abi using blockscout - fuse', async () => {
const abi = await defaultAbiFetcher.get('0xeEeEEb57642040bE42185f49C52F7E9B38f8eeeE', 'fuse', 'implementationOnly')

expect(abi.length).to.be.greaterThan(0)
})
})

0 comments on commit fbd6b8f

Please sign in to comment.