shazow / whatsabi

Extract the ABI (and resolve proxies, and get other metadata) from Ethereum bytecode, even without source code.
https://shazow.github.io/whatsabi/
MIT License
1.06k stars 74 forks source link

Pass an optional baseUrl or chainId to defaultWithApiKeys #72

Closed SonOfMosiah closed 10 months ago

SonOfMosiah commented 10 months ago

I think the defaultWithApiKeys function should take either a chainId or a baseUrl as a optional parameter to query chains other than mainnet.

SonOfMosiah commented 10 months ago

Here's a current workaround we're using for the function:

// Example:
// whatsabi.autoload(address, {provider, ...defaultsWithAPIKeys(process.env)})
export function defaultsWithAPIKeys({
    apiKeys,
    chainId,
}: {
    apiKeys: APIKeys
    chainId: number
}): Record<string, ABILoader | SignatureLookup> {
    const baseURL =
        chainId === 42161 ? 'https://api.arbiscan.io/api' : 'https://api.etherscan.io/api'
    return {
        abiLoader: new whatsabi.loaders.MultiABILoader([
            new whatsabi.loaders.SourcifyABILoader(),
            new whatsabi.loaders.EtherscanABILoader({
                apiKey: apiKeys.ETHERSCAN_API_KEY,
                baseURL,
            }),
        ]),
        signaturelookup: new whatsabi.loaders.MultiSignatureLookup([
            new whatsabi.loaders.OpenChainSignatureLookup(),
            new whatsabi.loaders.FourByteSignatureLookup(),
        ]),
    }
}

export async function getAutoloadAbi({ address, chainId }: AutoloadAbiParameters) {
    const client = getPublicClient({ chainId })
    const apiKeys = {
        ETHERSCAN_API_KEY:
            chainId === 42161 ? process.env.ARBISCAN_API_KEY : process.env.ETHERSCAN_API_KEY,
    }

    const result = await whatsabi.autoload(address, {
        // @ts-ignore
        provider: client,
        ...defaultsWithAPIKeys({ apiKeys, chainId }),
    })
    if (!result.abi.some((item) => (item as { name?: string }).name))
        throw new Error('No abi found')

    if (!result?.abi) throw new Error('No abi found')

    return result.abi
}
shazow commented 10 months ago

That's really useful context, thank you.

Part of me is thinking maybe whatsabi should include a mapping of chainIds to API urls, so that all you need to pass in is just the chainId... but I'm not sure that's the best thing to commit to at this point. 😅