hadv / hadv/ethaura

[Phase 4] External Simulation API Integration (Optional Enhancement)

Open
#144 0 comments 0 reactions 0 assignees View on GitHub
⛨ security enhancement UI/UX
Dominant language
JavaScript
Stars
2
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Overview

Integrate external transaction simulation APIs for enhanced threat detection and more detailed transaction analysis. This phase is optional but recommended for production-grade security.

## Parent Issue

#140 - Implement Transaction Simulation for Enhanced Wallet Security

## Dependencies

- Requires #141 (Phase 1: Basic On-Chain Simulation)
- Can be done in parallel with #142 and #143

## Background

While on-chain simulation (Phase 1) provides basic functionality, external simulation APIs offer:
- More detailed execution traces
- ML-based threat detection
- Pre-built scam databases
- Better error messages and debugging
- State diff visualization

## Simulation API Comparison

| Provider | Strengths | Pricing | Best For |
|----------|-----------|---------|----------|
| **Tenderly** | Full traces, state diffs, debugging | Free tier available | Development & debugging |
| **Blowfish** | Security-focused, phishing detection | API key required | Security-first wallets |
| **Blockaid** | ML-based, real-time threat intel | Enterprise | Large-scale protection |
| **Alchemy** | Simple API, good infra | Free tier | Quick integration |

## Recommended: Tenderly Integration

Tenderly is recommended for MVP due to:
- Generous free tier (5,000 simulations/month)
- Excellent documentation
- Full execution trace with state diffs
- JavaScript SDK available

### Tenderly SDK Integration

```javascript
// frontend/src/lib/tenderlySimulator.js
import { Tenderly, Network } from '@tenderly/sdk'

const tenderly = new Tenderly({
accessKey: process.env.TENDERLY_ACCESS_KEY,
accountName: process.env.TENDERLY_ACCOUNT,
projectName: process.env.TENDERLY_PROJECT,
network: Network.SEPOLIA, // or MAINNET
})

/**
* Simulate transaction using Tenderly
*/
export async function simulateWithTenderly(transaction) {
const simulation = await tenderly.simulator.simulateTransaction({
transaction: {
from: transaction.from,
to: transaction.to,
input: transaction.data,
value: transaction.value,
gas: transaction.gas,
gas_price: transaction.gasPrice,
},
blockNumber: 'latest',
})

return {
success: simulation.simulation.status,
gasUsed: simulation.simulation.gas_used,
logs: simulation.simulation.logs,
trace: simulation.simulation.trace,
stateDiff: simulation.simulation.state_diff,
error: simulation.simulation.error_message,
}
}

/**
* Simulate UserOperation bundle
*/
export async function simulateUserOpWithTenderly(userOp, entryPointAddress) {
// Encode the handleOps call
const handleOpsCalldata = encodeHandleOps([userOp], beneficiary)

const simulation = await tenderly.simulator.simulateTransaction({
transaction: {
from: bundlerAddress, // Simulated bundler
to: entryPointAddress,
input: handleOpsCalldata,
value: '0x0',
gas: 10000000,
},
blockNumber: 'latest',
})

return parseUserOpSimulation(simulation)
}
```

### Parse Tenderly State Diffs

```javascript
/**
* Parse Tenderly state diff into balance changes
*/
function parseStateDiff(stateDiff, accountAddress) {
const balanceChanges = []

for (const [address, changes] of Object.entries(stateDiff)) {
// ETH balance change
if (changes.balance) {
balanceChanges.push({
token: 'ETH',
before: changes.balance.before,
after: changes.balance.after,
})
}

// ERC20 balance changes (storage slot parsing)
if (changes.storage) {
for (const [slot, value] of Object.entries(changes.storage)) {
const tokenChange = parseERC20StorageChange(address, slot, value, accountAddress)
if (tokenChange) {
balanceChanges.push(tokenChange)
}
}
}
}

return balanceChanges
}
```

## Alternative: Blowfish Integration

Blowfish specializes in security and provides:
- Pre-built phishing detection
- Scam token database
- Human-readable transaction summaries

```javascript
// frontend/src/lib/blowfishSimulator.js

const BLOWFISH_API = 'https://api.blowfish.xyz'

export async function scanWithBlowfish(transaction, userAddress) {
const response = await fetch(`${BLOWFISH_API}/ethereum/v0/mainnet/scan/transactions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.BLOWFISH_API_KEY,
},
body: JSON.stringify({
userAccount: userAddress,
metadata: { origin: 'https://ethaura.app' },
txObjects: [transaction],
}),
})

const result = await response.json()

return {
action: result.action, // 'BLOCK', 'WARN', 'NONE'
warnings: result.warnings,
simulationResults: result.simulationResults,
humanReadable: result.aggregated?.humanReadableDiff,
}
}
```

## Architecture: Hybrid Approach

Use a hybrid approach with fallback:

```javascript
// frontend/src/lib/transactionSimulator.js

/**
* Simulate transaction with fallback strategy
* 1. Try external API (Tenderly/Blowfish)
* 2. Fall back to on-chain simulation if API fails
*/
export async function simulateTransaction(userOp, options = {}) {
const { useExternalAPI = true, provider, entryPointAddress } = options

if (useExternalAPI) {
try {
// Try Tenderly first
const result = await simulateWithTenderly(userOp)
return { ...result, source: 'tenderly' }
} catch (error) {
console.warn('Tenderly simulation failed, falling back to on-chain:', error)
}
}

// Fallback to on-chain simulation
const result = await simulateUserOperation(userOp, provider, entryPointAddress)
return { ...result, source: 'onchain' }
}
```

## Tasks

### Tenderly Integration
- [ ] Set up Tenderly account and project
- [ ] Add Tenderly SDK dependency
- [ ] Create `frontend/src/lib/tenderlySimulator.js`
- [ ] Implement `simulateWithTenderly()` for regular transactions
- [ ] Implement `simulateUserOpWithTenderly()` for UserOperations
- [ ] Parse state diffs into balance changes
- [ ] Handle Tenderly API errors gracefully
- [ ] Add rate limiting and caching

### Blowfish Integration (Optional)
- [ ] Set up Blowfish API access
- [ ] Create `frontend/src/lib/blowfishSimulator.js`
- [ ] Implement `scanWithBlowfish()` for security scanning
- [ ] Parse Blowfish warnings into our warning format
- [ ] Display human-readable transaction summaries

### Hybrid Architecture
- [ ] Implement fallback strategy (API → on-chain)
- [ ] Add configuration for simulation provider preference
- [ ] Handle network-specific API availability
- [ ] Add simulation source indicator in UI

### Configuration & Environment
- [ ] Add environment variables for API keys:
```
TENDERLY_ACCESS_KEY=
TENDERLY_ACCOUNT=
TENDERLY_PROJECT=
BLOWFISH_API_KEY=
```
- [ ] Document API key setup in README
- [ ] Add fallback toggle in settings

### Caching & Performance
- [ ] Cache simulation results (short TTL: 30s)
- [ ] Deduplicate identical simulation requests
- [ ] Add request timeout handling
- [ ] Implement retry logic for transient failures

## Files to Create

1. **`frontend/src/lib/tenderlySimulator.js`** - Tenderly integration
2. **`frontend/src/lib/blowfishSimulator.js`** - Blowfish integration (optional)
3. **`frontend/src/lib/simulationCache.js`** - Caching layer

## Files to Modify

1. **`frontend/src/lib/transactionSimulator.js`** - Add external API fallback
2. **`frontend/.env.example`** - Add API key variables
3. **`frontend/src/components/SimulationStatus.jsx`** - Show simulation source

## Acceptance Criteria

- [ ] Tenderly simulation works for regular transactions
- [ ] Tenderly simulation works for UserOperations
- [ ] State diffs are parsed into balance changes
- [ ] Fallback to on-chain simulation works when API fails
- [ ] API errors don't block transaction flow
- [ ] Simulation results are cached appropriately
- [ ] API keys are properly secured (not exposed to client)

## Testing

- [ ] Test Tenderly simulation on Sepolia
- [ ] Test fallback when Tenderly is unavailable
- [ ] Test caching behavior
- [ ] Test rate limiting handling
- [ ] Compare results between Tenderly and on-chain simulation

## Security Considerations

### API Key Security

**Option 1: Backend Proxy (Recommended)**
```javascript
// Don't expose API keys to frontend
// Create a backend endpoint to proxy simulation requests
app.post('/api/simulate', async (req, res) => {
const result = await tenderly.simulator.simulateTransaction(req.body)
res.json(result)
})
```

**Option 2: Serverless Function**
```javascript
// Use Vercel/Netlify serverless function
// frontend/api/simulate.js
export default async function handler(req, res) {
// API key is in server environment, not exposed
const tenderly = new Tenderly({ accessKey: process.env.TENDERLY_KEY })
// ...
}
```

### Rate Limiting
- Implement client-side rate limiting
- Queue requests to avoid hitting API limits
- Show warning if approaching limits

## Cost Estimation

| Provider | Free Tier | Paid |
|----------|-----------|------|
| Tenderly | 5,000 sims/month | $0.01/sim |
| Blowfish | Contact sales | Enterprise |
| Alchemy | 10,000 sims/month | Pay as you go |

For MVP, Tenderly's free tier should be sufficient.

## Estimated Effort

**Medium** - 2-3 days for Tenderly integration
**High** - 4-5 days for full hybrid approach with Blowfish

## Priority

**Medium** - This is an enhancement phase. The core simulation (Phase 1-3) provides sufficient security for MVP.

## Labels

`security`, `enhancement`, `frontend`, `integration`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.