Files
explorer-monorepo/docs/specs/multichain/chain-adapter-interface.md

294 lines
7.1 KiB
Markdown
Raw Normal View History

# Chain Adapter Interface Specification
## Overview
This document specifies the abstract chain adapter interface that enables multi-chain support by abstracting chain-specific differences behind a unified interface.
## Adapter Interface
### Core Interface
```typescript
interface ChainAdapter {
// Chain identification
getChainId(): number;
getChainName(): string;
// RPC capabilities
getBlock(blockNumber: number | string): Promise<Block>;
getBlockByHash(hash: string): Promise<Block>;
getTransaction(hash: string): Promise<Transaction>;
getTransactionReceipt(hash: string): Promise<Receipt>;
getBalance(address: string, blockNumber?: string): Promise<string>;
call(transaction: CallRequest, blockNumber?: string): Promise<string>;
// Advanced capabilities
traceTransaction(hash: string): Promise<Trace[]>;
traceBlock(blockNumber: number): Promise<Trace[]>;
getCode(address: string, blockNumber?: string): Promise<string>;
// Subscription capabilities
subscribeNewBlocks(callback: (block: Block) => void): Subscription;
subscribePendingTransactions(callback: (tx: Transaction) => void): Subscription;
// Capability queries
supportsTracing(): boolean;
supportsArchive(): boolean;
supportsDebug(): boolean;
}
```
## RPC Capabilities Abstraction
### Archive Mode
**Interface**:
```typescript
interface ArchiveCapability {
getHistoricalBalance(address: string, blockNumber: number): Promise<string>;
getHistoricalCode(address: string, blockNumber: number): Promise<string>;
getHistoricalStorage(address: string, slot: string, blockNumber: number): Promise<string>;
}
```
**Implementation**:
- EVM chains: Use `eth_getBalance` with block number
- Non-EVM: Chain-specific historical queries
### Tracing Capabilities
**Interface**:
```typescript
interface TracingCapability {
traceCall(call: CallRequest, traceType: string[]): Promise<TraceResult>;
traceTransaction(hash: string, traceType: string[]): Promise<Trace[]>;
traceBlock(blockNumber: number, traceType: string[]): Promise<Trace[][]>;
}
```
**Trace Types**:
- `call`: Call traces
- `trace`: Full trace information
- `vmTrace`: VM execution trace
- `stateDiff`: State differences
**Implementation**:
- EVM chains: Use `debug_trace*` methods
- Non-EVM: Chain-specific trace methods
### Debug Capabilities
**Interface**:
```typescript
interface DebugCapability {
debugTraceTransaction(hash: string, options: TraceOptions): Promise<TraceResult>;
debugTraceBlock(blockNumber: number, options: TraceOptions): Promise<TraceResult[]>;
debugTraceCall(call: CallRequest, blockNumber: number, options: TraceOptions): Promise<TraceResult>;
}
```
**Use Cases**: Advanced debugging, detailed transaction analysis
## Token Standards Abstraction
### Token Interface
```typescript
interface TokenStandard {
// Common methods
getBalance(address: string, tokenAddress: string): Promise<string>;
getTotalSupply(tokenAddress: string): Promise<string>;
getDecimals(tokenAddress: string): Promise<number>;
getName(tokenAddress: string): Promise<string>;
getSymbol(tokenAddress: string): Promise<string>;
// Standard-specific
getTokenId(owner: string, index: number): Promise<string>; // ERC-721/1155
getTokenURI(tokenAddress: string, tokenId: string): Promise<string>; // ERC-721/1155
}
```
### Standard Detection
**ERC-20**:
- Detect `balanceOf`, `totalSupply`, `transfer` functions
- Standard interface ID: `0x36372b07`
**ERC-721**:
- Detect `balanceOf`, `ownerOf`, `tokenURI` functions
- Standard interface ID: `0x80ac58cd`
**ERC-1155**:
- Detect `balanceOf`, `balanceOfBatch`, `uri` functions
- Standard interface ID: `0xd9b67a26`
**Non-EVM Standards**:
- Chain-specific token standards
- Custom detection logic
## Gas Model Abstraction
### Gas Interface
```typescript
interface GasModel {
// Gas estimation
estimateGas(transaction: TransactionRequest): Promise<number>;
// Fee calculation
getGasPrice(): Promise<string>;
getFeeData(): Promise<FeeData>; // EIP-1559
// Gas limit
getBlockGasLimit(): Promise<number>;
getBlockGasUsed(): Promise<number>;
}
```
### EIP-1559 Support
**Interface**:
```typescript
interface EIP1559GasModel extends GasModel {
getBaseFee(): Promise<string>;
getMaxFeePerGas(): Promise<string>;
getMaxPriorityFeePerGas(): Promise<string>;
}
```
**Detection**: Check for `baseFeePerGas` in block header
### Legacy Gas Model
**Interface**: Simple gas price model (pre-EIP-1559)
## Finality Model Abstraction
### Finality Interface
```typescript
interface FinalityModel {
getFinalityDepth(): number; // Blocks until final
isFinal(blockNumber: number): Promise<boolean>;
getFinalityTime(): number; // Estimated time to finality (seconds)
}
```
### Finality Types
**Immediate Finality** (BFT chains):
- Finality depth: 1
- Examples: Cosmos, Polkadot (with finality gadgets)
**Probabilistic Finality** (PoW):
- Finality depth: 12-100 blocks
- Examples: Ethereum (pre-merge), Bitcoin
**Economic Finality** (PoS):
- Finality depth: 1-2 epochs
- Examples: Ethereum (post-merge), Cardano
## Implementation Examples
### EVM Chain Adapter
```typescript
class EVMChainAdapter implements ChainAdapter {
constructor(private rpcUrl: string, private chainId: number) {}
async getBlock(blockNumber: number | string): Promise<Block> {
const response = await this.rpcCall('eth_getBlockByNumber', [
blockNumber === 'latest' ? 'latest' : `0x${blockNumber.toString(16)}`,
true
]);
return this.transformBlock(response);
}
supportsTracing(): boolean {
return true; // Most EVM chains support tracing
}
// ... other methods
}
```
### Non-EVM Chain Adapter
```typescript
class NonEVMChainAdapter implements ChainAdapter {
// Chain-specific implementation
// Map chain-specific RPC calls to standard interface
}
```
## Adapter Registry
### Registry Interface
```typescript
interface ChainAdapterRegistry {
register(chainId: number, adapter: ChainAdapter): void;
get(chainId: number): ChainAdapter;
list(): ChainAdapter[];
supports(chainId: number): boolean;
}
```
### Configuration
```yaml
chains:
- chain_id: 138
name: "ChainID 138"
adapter: "evm"
rpc_url: "http://192.168.11.221:8545" # Internal IP for direct connection
supports_tracing: true
supports_archive: true
- chain_id: 1
name: "Ethereum Mainnet"
adapter: "evm"
rpc_url: "https://eth-mainnet.alchemyapi.io/v2/..."
supports_tracing: true
supports_archive: true
```
## Error Handling
### Chain-Specific Errors
**Handling**:
- Map chain-specific errors to standard error codes
- Provide error context (chain_id, method called)
- Log chain-specific error details
### Capability Errors
**Handling**:
- Check capability before calling method
- Return appropriate error if capability not supported
- Provide alternative methods when possible
## Testing
### Adapter Tests
**Test Cases**:
- Standard interface methods
- Error handling
- Capability detection
- Data transformation
### Integration Tests
**Test Cases**:
- Multi-chain queries
- Adapter switching
- Error propagation
## References
- Multi-chain Indexing: See `multichain-indexing.md`
- Database Schema: See `../database/postgres-schema.md`