Skip to content

Commit

Permalink
Adding AnyABI loader
Browse files Browse the repository at this point in the history
  • Loading branch information
k-thornton committed Nov 22, 2024
1 parent 1a8c899 commit e7609cc
Showing 1 changed file with 66 additions and 5 deletions.
71 changes: 66 additions & 5 deletions src/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import * as errors from "./errors.js";
export type ContractResult = {
abi: any[];
name: string | null;
evmVersion: string;
compilerVersion: string;
runs: number;

ok: boolean; // False if no result is found
evmVersion?: string;
compilerVersion?: string;
runs?: number;


/**
* getSources returns the imports -> source code mapping for the contract, if available.
Expand Down Expand Up @@ -425,7 +425,6 @@ export interface SourcifyContractMetadata {
version: number;
}


export class BlockscoutABILoader implements ABILoader {
readonly name = "BlockscoutABILoader";

Expand Down Expand Up @@ -602,6 +601,68 @@ export type BlockscoutContractResult = {
has_methods_write_proxy?: boolean;
};


function isAnyABINotFound(error: any): boolean {
return (
error.message === "Failed to fetch" ||
error.message === "ABI not found" ||
error.status === 404
);
}

// https://anyabi.xyz/
export class AnyABILoader implements ABILoader {
readonly name = "AnyABILoader";

chainId?: number;

constructor(config?: { chainId?: number }) {
this.chainId = config?.chainId ?? 1;
}

async #fetchAnyABI(address: string): Promise<ContractResult> {
const url = "https://anyabi.xyz/api/get-abi/" + this.chainId + "/" + address;
try {
const r = await fetchJSON(url);
const { abi, name }: { abi: any[]; name: string } = r;

return {
abi: abi,
name: name,
ok: true,
loader: this,
loaderResult: r,
};
} catch (err: any) {
if (!isAnyABINotFound(err)) return emptyContractResult;
throw new AnyABILoaderError("AnyABILoader load contract error: " + err.message, {
context: { url },
cause: err,
});
}
}

async getContract(address: string): Promise<ContractResult> {
{
const r = await this.#fetchAnyABI(address);
if (r.ok) return r;
}

return emptyContractResult;
}

async loadABI(address: string): Promise<any[]> {
{
const r = await this.#fetchAnyABI(address);
if (r.ok) return r.abi;
}

return [];
}
}

export class AnyABILoaderError extends errors.LoaderError { };

export interface SignatureLookup {
loadFunctions(selector: string): Promise<string[]>;
loadEvents(hash: string): Promise<string[]>;
Expand Down

0 comments on commit e7609cc

Please sign in to comment.