# ChainErrors
> **Blockchain error decoder for EVM and Solana — decode reverts, panics, custom errors, and program failures.**
ChainErrors is part of [ChainKit](https://github.com/DarshanKumar89/chainkit), a monorepo of blockchain primitives for Rust, TypeScript, Python, Go, and Java.
---
## Features
| EVM `Error(string)` revert decoding | ✅ |
| EVM `Panic(uint256)` decode with meanings | ✅ |
| EVM custom error decoding (40+ bundled) | ✅ |
| Solana System Program errors (0-17) | ✅ |
| Solana SPL Token errors (0-17) | ✅ |
| Solana Anchor framework errors (100-5000+) | ✅ |
| Solana program log parsing | ✅ |
| Confidence scoring (0.0 – 1.0) | ✅ |
| Human-readable suggestions | ✅ |
| Golden fixture test suite | ✅ |
## Quick Start
### Rust
```toml
[dependencies]
chainerrors-core = "0.1.0"
chainerrors-evm = "0.1.0"
chainerrors-solana = "0.1.0"
```
```rust
use chainerrors_evm::EvmErrorDecoder;
use chainerrors_core::ErrorDecoder;
let decoder = EvmErrorDecoder::new();
// Decode a revert string
let data = hex::decode("08c379a0...").unwrap();
let result = decoder.decode(&data, None).unwrap();
println!("{result}");
// → "reverted: Not enough tokens"
// Decode a panic
let panic_data = hex::decode("4e487b71...0011").unwrap();
let result = decoder.decode(&panic_data, None).unwrap();
println!("{result}");
// → "panic 0x11: arithmetic overflow"
```
```rust
use chainerrors_solana::SolanaErrorDecoder;
use chainerrors_core::ErrorDecoder;
let decoder = SolanaErrorDecoder::new();
// Decode a system program error
let result = decoder.decode_error_code(
1,
Some("11111111111111111111111111111111"),
None,
).unwrap();
println!("{result}");
// → "AccountAlreadyInUse(code=1)"
// Decode from program logs
let result = decoder.decode_log(
"Program failed: custom program error: 0xbc4",
None,
).unwrap();
println!("{result}");
// → "AccountNotInitialized(code=3012)"
```
### TypeScript (Node.js)
```bash
npm install @chainfoundry/chainerrors
```
```typescript
import { decodeEvmError } from '@chainfoundry/chainerrors';
const result = decodeEvmError('0x08c379a0...');
console.log(result.kind); // "revert_string"
console.log(result.message); // "Not enough tokens"
```
### Python
```bash
pip install chainerrors
```
```python
from chainerrors import decode_evm_error
result = decode_evm_error("0x08c379a0...")
print(result["kind"]) # "revert_string"
print(result["message"]) # "Not enough tokens"
```
### CLI
```bash
cargo install chainerrors-cli
chainerrors decode --data 0x08c379a0...
# → Error(string): "Not enough tokens"
chainerrors decode --data 0x4e487b710000...0011
# → Panic(uint256): arithmetic overflow (0x11)
```
---
## EVM Error Types
### Revert Strings (`0x08c379a0`)
```
require(balance >= amount, "Insufficient balance")
→ Error(string): "Insufficient balance"
```
### Panic Codes (`0x4e487b71`)
| 0x01 | `assert()` violation |
| 0x11 | Arithmetic overflow |
| 0x12 | Division by zero |
| 0x21 | Invalid enum conversion |
| 0x32 | Array out of bounds |
| 0x51 | Zero-initialized function pointer |
### Bundled Custom Errors (40+)
**ERC-20**: InsufficientBalance, InvalidSender, InvalidReceiver, InsufficientAllowance
**ERC-721**: InvalidOwner, NonexistentToken, IncorrectOwner, InsufficientApproval
**OpenZeppelin**: OwnableUnauthorizedAccount, AccessControlUnauthorizedAccount, ReentrancyGuardReentrantCall, EnforcedPause
**Uniswap V3**: T, LOK, TLU, TLM, TUM, AS, M0, M1, IIA, SPL, F0, F1, L, LS, LA
**EIP-4626**: ExceededMaxDeposit/Mint/Withdraw/Redeem
**SafeERC20**: FailedOperation, FailedDecreaseAllowance
---
## Solana Error Types
### System Program (18 errors)
AccountAlreadyInitialized, AccountAlreadyInUse, AccountDataTooSmall, AccountNotRentExempt, InsufficientFundsForFee, InvalidAccountDataLength, and more.
### SPL Token (18 errors)
NotRentExempt, InsufficientFunds, InvalidMint, MintMismatch, OwnerMismatch, UninitializedState, AccountFrozen, and more.
### Anchor Framework (40+ errors)
- **Instruction** (100-103): InstructionMissing, InstructionDidNotDeserialize
- **Constraint** (2000-2020): ConstraintMut, ConstraintHasOne, ConstraintSigner, ConstraintSeeds, ConstraintOwner
- **Account** (3000-3017): AccountDiscriminatorMismatch, AccountNotInitialized, AccountOwnedByWrongProgram, InvalidProgramId
### Program Log Parsing
```
"Program XYZ failed: custom program error: 0xbc4" → Code(3012) → AccountNotInitialized
"Program log: Error: insufficient funds" → Message("insufficient funds")
"Error Code: AccountNotInitialized. Error Number: 3012." → Code(3012)
```
---
## Architecture
```
chainerrors/
├── crates/
│ ├── chainerrors-core/ # ErrorDecoder trait, DecodedError, ErrorKind, registry
│ ├── chainerrors-evm/ # EvmErrorDecoder — revert, panic, custom errors
│ └── chainerrors-solana/ # SolanaErrorDecoder — system, token, anchor, logs
├── bindings/
│ ├── node/ # TypeScript via napi-rs
│ ├── python/ # Python via PyO3/maturin
│ ├── go/ # Go via cgo
│ └── java/ # Java via JNI
└── cli/ # chainerrors-cli binary
```
## Tests
```bash
cd chainerrors && cargo test --workspace
# 72 tests: 7 core + 17 evm + 10 golden + 35 solana + 3 doc-tests
```
---
## License
MIT — see [LICENSE](../LICENSE)
## Contact
Built by [@darshan_aqua](https://x.com/darshan_aqua) — questions, feedback, and contributions welcome.