{"_id":"@blu-whale/whatsabi","_rev":"1-10cd86b7b341cf329c437d453e27d640","name":"@blu-whale/whatsabi","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@blu-whale/whatsabi","version":"0.0.1","description":"Guess an ABI from Ethereum bytecode, even if it's unverified","type":"module","scripts":{"test":"vitest run","build:cjs":"tsc --project tsconfig.cjs.json && cp package.cjs.json lib.cjs/package.json","build:esm":"tsc --project tsconfig.esm.json && cp package.esm.json lib.esm/package.json","build:types":"tsc --project tsconfig.types.json","publish":"npm publish --access public --tag latest"},"repository":{"type":"git","url":"git+https://github.com/shazow/whatsabi.git"},"keywords":["ethereum","evm","abi"],"author":{"name":"Andrey Petrov","email":"shazow.net"},"license":"MIT","bugs":{"url":"https://github.com/shazow/whatsabi/issues"},"homepage":"https://github.com/shazow/whatsabi#readme","dependencies":{"ethers":"^6.9.2"},"peerDependencies":{"@noble/hashes":"^1"},"devDependencies":{"@size-limit/esbuild-why":"^8.2.6","@size-limit/preset-small-lib":"^8.2.6","size-limit":"^8.2.6","tsx":"^4.7.0","viem":"^1.21.4","vitest":"^0.34.6"},"main":"./lib.cjs/index.js","module":"./lib.esm/index.js","types":"./lib.types/index.d.ts","exports":{".":{"types":"./lib.types/index.d.ts","import":"./lib.esm/index.js","default":"./lib.cjs/index.js"}},"_id":"@blu-whale/whatsabi@0.0.1","gitHead":"e9417abb695b679cef8abe1772b164e4bf6ad4dd","_nodeVersion":"18.18.0","_npmVersion":"10.3.0","dist":{"integrity":"sha512-a/rH1nQe2pfDdZ+EzN345w5hpHci+7cTipOHi1Rt25YZyHOn7xABww/+TLaGC3aOppenFfemqtR0aTxe65z1+A==","shasum":"60bc600807141b8d9d442650aec41b7209089635","tarball":"https://registry.npmjs.org/@blu-whale/whatsabi/-/whatsabi-0.0.1.tgz","fileCount":139,"unpackedSize":409958,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd8bwEqJuT6Y+rfJJrJRkVDDNinP+D9qDl+ifF0FfA9QIhAPPAubZp1rCZuLQ3SJ9QnELpZ60p6rfy2ERz4qrmwVJE"}]},"_npmUser":{"name":"liulinhui151","email":"liulinhui1994@gmail.com"},"directories":{},"maintainers":[{"name":"liulinhui151","email":"liulinhui1994@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/whatsabi_0.0.1_1708596353211_0.4115881373384851"},"_hasShrinkwrap":false},"0.0.2":{"name":"@blu-whale/whatsabi","version":"0.0.2","description":"Guess an ABI from Ethereum bytecode, even if it's unverified","type":"module","scripts":{"test":"vitest run","build:cjs":"tsc --project tsconfig.cjs.json && cp package.cjs.json lib.cjs/package.json","build:esm":"tsc --project tsconfig.esm.json && cp package.esm.json lib.esm/package.json","build:types":"tsc --project tsconfig.types.json","publish":"npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/shazow/whatsabi.git"},"keywords":["ethereum","evm","abi"],"author":{"name":"Andrey Petrov","email":"shazow.net"},"license":"MIT","bugs":{"url":"https://github.com/shazow/whatsabi/issues"},"homepage":"https://github.com/shazow/whatsabi#readme","dependencies":{"ethers":"^6.9.2"},"peerDependencies":{"@noble/hashes":"^1"},"devDependencies":{"@size-limit/esbuild-why":"^8.2.6","@size-limit/preset-small-lib":"^8.2.6","size-limit":"^8.2.6","tsx":"^4.7.0","viem":"^1.21.4","vitest":"^0.34.6"},"main":"./lib.cjs/index.js","module":"./lib.esm/index.js","types":"./lib.types/index.d.ts","exports":{".":{"types":"./lib.types/index.d.ts","import":"./lib.esm/index.js","default":"./lib.cjs/index.js"}},"_id":"@blu-whale/whatsabi@0.0.2","gitHead":"e9417abb695b679cef8abe1772b164e4bf6ad4dd","_nodeVersion":"18.18.0","_npmVersion":"10.3.0","dist":{"integrity":"sha512-dIsNIBfq6yiu/YCu+GB4XNhTGifurqjOKdaXAmpnMrAw5HbNq+aliAV8+DFrQ7OqJkQiOSA6OXOZgV5uQhdiMA==","shasum":"092243420eca9cbe9aa468d257588af1b27c0cdd","tarball":"https://registry.npmjs.org/@blu-whale/whatsabi/-/whatsabi-0.0.2.tgz","fileCount":139,"unpackedSize":409945,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH7V0+4CIZk8oq3lhcQBQKn5ck3XNQ/N1JARpL5LLf81AiBWB/oszap/9ydQAGcojws/QTyNn0iaMV1c2vY+xNcQ6A=="}]},"_npmUser":{"name":"liulinhui151","email":"liulinhui1994@gmail.com"},"directories":{},"maintainers":[{"name":"liulinhui151","email":"liulinhui1994@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/whatsabi_0.0.2_1708596426277_0.09659904413745823"},"_hasShrinkwrap":false}},"time":{"created":"2024-02-22T10:05:53.138Z","0.0.1":"2024-02-22T10:05:53.522Z","modified":"2024-02-22T10:07:07.036Z","0.0.2":"2024-02-22T10:07:06.567Z"},"maintainers":[{"name":"liulinhui151","email":"liulinhui1994@gmail.com"}],"description":"Guess an ABI from Ethereum bytecode, even if it's unverified","homepage":"https://github.com/shazow/whatsabi#readme","keywords":["ethereum","evm","abi"],"repository":{"type":"git","url":"git+https://github.com/shazow/whatsabi.git"},"author":{"name":"Andrey Petrov","email":"shazow.net"},"bugs":{"url":"https://github.com/shazow/whatsabi/issues"},"license":"MIT","readme":"![WhatsABI](assets/logo.png)\n\n# WhatsABI\n\nGuess an ABI from an Ethereum contract address, even if it's unverified.\n\nWhatsABI does bounded-complexity static analysis to disassemble EVM bytecode and map out the possible call flows,\nwhich allows us to discover function selectors and other metadata about the contract.\n\nWhatsABI is perfect for building procedural frontends, embedding in wallets, block explorers, or doing bytecode analysis.\n\n## Features\n\nWhatsABI is different from other EVM analysis tools in some important ways:\n- Built in Typescript with minimal dependencies, so that it is **runnable in the browser and embeddable in wallets.**\n- Algorithms used are limited to `O(instructions)` with a small constant factor, so that **complex contracts don't cause it to time out or use unbounded memory.**\n- Does not rely on source code, so it **works with unverified contracts.**\n- Does not assume the source language, so it can work for source languages other than Solidity (Vyper, or even hand-written assembly).\n- Permissive open source (MIT-licensed), so that anyone can use it.\n\nWhat can WhatsABI do?\n- Return selectors from bytecode.\n- Look up function signatures from selectors.\n- ✨ Resolve proxy contracts!\n- Small bundle (less than 15 KB) that works with Ethers.js, Viem, and others.\n\n## Usage\n\n```typescript\nimport { ethers } from \"ethers\";\nimport { whatsabi } from \"@shazow/whatsabi\";\n\nconst provider = ethers.getDefaultProvider(); // substitute with your fav provider\nconst address = \"0x00000000006c3852cbEf3e08E8dF289169EdE581\"; // Or your fav contract address\nconst code = await provider.getCode(address); // Load the bytecode\n\n// Get just the callable selectors\nconst selectors = whatsabi.selectorsFromBytecode(code);\nconsole.log(selectors); // -> [\"0x06fdde03\", \"0x46423aa7\", \"0x55944a42\", ...]\n\n// Get an ABI-like list of interfaces\nconst abi = whatsabi.abiFromBytecode(code);\nconsole.log(abi);\n// -> [\n//  {\"type\": \"event\", \"hash\": \"0x721c20121297512b72821b97f5326877ea8ecf4bb9948fea5bfcb6453074d37f\"},\n//  {\"type\": \"function\", \"payable\": true, \"selector\": \"0x06fdde03\", ...},\n//  {\"type\": \"function\", \"payable\": true, \"selector\": \"0x46423aa7\", ...},\n//   ...\n\n// We also have a suite of database loaders for convenience\nconst signatureLookup = new whatsabi.loaders.OpenChainSignatureLookup();\nconsole.log(await signatureLookup.loadFunctions(\"0x06fdde03\"));\n// -> [\"name()\"]);\nconsole.log(await signatureLookup.loadFunctions(\"0x46423aa7\"));\n// -> [\"getOrderStatus(bytes32)\"]);\n\n// We also have event loaders!\nconsole.log(await signatureLookup.loadEvents(\"0x721c20121297512b72821b97f5326877ea8ecf4bb9948fea5bfcb6453074d37f\"));\n// -> [\"CounterIncremented(uint256,address)\"]\n\n// There are more fancy loaders in whatsabi.loaders.*, take a look!\n\n// Here's a multiloader with an Etherscan API key, it can be used with autoload below.\n// Each source will be attempted until a result is found.\nconst abiLoader = new whatsabi.loaders.MultiABILoader([\n  new whatsabi.loaders.SourcifyABILoader(),\n  new whatsabi.loaders.EtherscanABILoader({\n    apiKey: \"...\", // Replace the value with your Etherscan API key\n  }),\n]);\nconsole.log(await abiLoader.loadABI(address));\n```\n\nBonus do-all-the-things helper:\n\n```typescript\n...\n\nlet result = await whatsabi.autoload(address, {\n  provider: provider,\n\n  // * Optional loaders:\n  // abiLoader: whatsabi.loaders.defaultABILoader,\n  // signatureLoader: whatsabi.loaders.defaultSignatureLookup,\n\n  // There is a handy helper for adding the default loaders but with your own settings\n  ... whatsabi.loaders.defaultsWithEnv({\n    SOURCIFY_CHAIN_ID: 42161,\n    ETHERSCAN_BASE_URL: \"https://api.arbiscan.io/api\",\n    ETHERSCAN_API_KEY: \"MYSECRETAPIKEY\",\n  }),\n\n  // * Optional hooks:\n  // onProgress: (phase: string) => { ... }\n  // onError: (phase: string, context: any) => { ... }\n\n  onProgress: (phase) => console.log(\"autoload progress\", phase),\n  onError: (phase, context) => console.log(\"autoload error\", phase, context),\n\n  // * Optional settings:\n  // followProxies: false,\n  // enableExperimentalMetadata: false,\n});\n\nconsole.log(result.abi);\n\n// Detail will vary depending on whether `address` source code was available,\n// or if bytecode-loaded selector signatures were available, or\n// if WhatsABI had to guess everything from just bytecode.\n\n// We can even detect and resolve proxies!\nif (result.followProxies) {\n    console.log(\"Proxies detected:\", result.proxies);\n\n    result = await result.followProxies();\n    console.log(result.abi);\n}\n```\n\nOr we can auto-follow resolved proxies, and expand parts of the result object:\n\n```typescript\nconst { abi, address } = await whatsabi.autoload(\n    \"0x4f8AD938eBA0CD19155a835f617317a6E788c868\",\n    {\n        provider,\n        followProxies: true,\n    },\n});\n\nconsole.log(\"Resolved to:\", address);\n// -> \"0x964f84048f0d9bb24b82413413299c0a1d61ea9f\"\n```\n\n\n## See Also\n\n* [callthis.link](https://callthis.link/) - Transaction builder powered by whatsabi\n* [WhatsABI? - Seminar for Spearbit](https://www.youtube.com/watch?v=sfgassm8SKw) (April 2023)\n* [abi.w1nt3r.xyz](https://abi.w1nt3r.xyz/) - A frontend for whatsabi by [@w1nt3r_eth](https://twitter.com/w1nt3r_eth) - https://github.com/w1nt3r-eth/abi.w1nt3r.xyz\n* [ethcmd.com](https://www.ethcmd.com/) - Contract explorer frontend, [uses whatsabi for unverified contracts](https://github.com/verynifty/ethcmd)\n* [monobase.xyz](https://monobase.xyz) - Universal frontend, [uses whatsabi for unverified contracts](https://twitter.com/nazar_ilamanov/status/1659648915195707392)\n\n## Some Cool People Said...\n\n> Omg WhatsABI by @shazow is so good that it can solve CTFs.  \n> In one of my CTFs, students are supposed to find calldata that doesn’t revert  \n> WhatsABI just spits out the solution automatically😂 I’m impressed!👏\n>  \n> 🗣️ [Nazar Ilamanov](https://twitter.com/nazar_ilamanov/status/1661240265955495936), creator of [monobase.xyz](https://monobase.xyz/)\n\n> WhatsABI by @shazow takes contract bytecode, disassembled it into a set of EVM instructions, and then looks for the common Solidity's dispatch pattern.  \n> Check out the source, it's actually very elegant!\n>  \n> 🗣️ [WINTΞR](https://twitter.com/w1nt3r_eth/status/1575848038223921152), creator of [abi.w1nt3r.xyz](https://abi.w1nt3r.xyz/)\n\n> really cool stuff from @shazow  \n> deduce a contract's ABI purely from bytecode\n>  \n> 🗣️ [t11s](https://twitter.com/transmissions11/status/1574851435971215360), from Paradigm\n\n## Caveats\n\n* Finding valid function selectors works great!\n* Detecting Solidity-style function modifiers (view, payable, etc) is still unreliable.\n* There's some minimal attempts at guessing the presence of arguments, but also unreliable.\n* Call graph traversal only supports static jumps right now. Dynamic jumps are skipped until we add abstract stack tracing, this is the main cause of above's unreliability.\n* Event parsing is janky, haven't found a reliable pattern so assume it's best\n  effort. Feel free to open an issue with good failure examples, especially\n  false negatives.\n\n## Development\n\n```console\n$ cat .env  # Write an .env file with your keys, or `cp .env.example .env`\nexport INFURA_API_KEY=\"...\"\nexport ETHERSCAN_API_KEY=\"...\"\n$ nix develop  # Or use your system's package manager to install node/ts/etc\n[dev] $ npm install\n[dev] $ ONLINE=1 make test\n```\n\n\n## Thanks\n\n* [ethers.js](https://github.com/ethers-io/ethers.js/) for being excellent, and\n  having a helpful assembler sub-package was inspiring.\n* [@jacobdehart](https://twitter.com/jacobdehart) for the library name and logo\n  that is totally a wasabi and not a green poop!\n\n\n## License\n\nMIT\n","readmeFilename":"README.md"}