# @elizaos/plugin-zapper

ElizaOS plugin for Zapper protocol integration - comprehensive portfolio tracking, DeFi analytics, NFT data, and blockchain insights across 50+ networks.

## Features

- **🏦 Portfolio Tracking**: Complete wallet portfolio analysis with token balances, values, and performance metrics
- **💰 Token Analytics**: Real-time prices, historical data, charts, and market analysis
- **🖼️ NFT Intelligence**: Collection metadata, traits, marketplace data, ownership analytics, and valuations
- **🔄 Transaction Analysis**: Detailed transaction history and individual transaction insights
- **🌐 Cross-Chain Support**: Multi-network asset tracking and cross-chain analytics
- **📊 DeFi Integration**: App positions, protocol data, and yield analytics
- **⛽ Network Utilities**: Gas prices, network health, features, and block explorer integration
- **👤 Account Intelligence**: Comprehensive account data including social integrations
- **📈 Performance Analytics**: Portfolio performance, returns analysis, and risk metrics
- **🔗 Real-time Data**: Live blockchain data through Zapper's GraphQL API

## Installation

```bash
bun install @elizaos/plugin-zapper
```

## Configuration

Add the following environment variables to your `.env` file:

```env
ZAPPER_API_KEY=your_api_key_here
ZAPPER_API_URL=https://public.zapper.xyz/graphql  # Optional, defaults to this URL
```

### Getting a Zapper API Key

1. Visit [Zapper API Dashboard](https://zapper.xyz/api)
2. Sign up or log in to your account
3. Create a new API key
4. Copy the key to your environment variables

## Usage

```typescript
import { zapperPlugin } from '@elizaos/plugin-zapper';

// Add to your ElizaOS configuration
const runtime = new AgentRuntime({
  plugins: [zapperPlugin],
  // ... other configuration
});
```

## Actions (25 Total)

### 🏦 Portfolio & Assets

#### GET_PORTFOLIO
Get comprehensive portfolio data for a wallet address.

**Triggers**: "portfolio", "balance", "wallet", "holdings", "tokens", "assets"
**Example**: "Show me the portfolio for 0x1234..." | "Check wallet balance for vitalik.eth"

#### GET_CROSS_CHAIN_ASSETS
Track assets across multiple blockchain networks with bridge support.

**Triggers**: "cross chain", "multi chain", "bridge assets", "cross chain balance"
**Example**: "Show me my cross-chain assets" | "Track my multi-chain portfolio"

#### GET_PORTFOLIO_PERFORMANCE
Analyze portfolio performance with returns, allocation, and risk metrics.

**Triggers**: "portfolio performance", "returns", "portfolio analytics", "investment performance"
**Example**: "Show me my portfolio performance" | "Analyze my investment returns"

### 💰 Token & Price Data

#### GET_TOKEN_PRICE
Get current price and market data for tokens.

**Triggers**: "price", "cost", "value", "worth", "market", "trading"
**Example**: "What is the current price of ETH?" | "Check MATIC price on Polygon"

#### GET_HISTORICAL_PRICE
Fetch historical price data and trends for tokens.

**Triggers**: "historical price", "price history", "past price", "price trend"
**Example**: "Show me ETH price history" | "Get historical data for BTC"

#### GET_PRICE_CHART_DATA
Generate detailed price charts and technical analysis data.

**Triggers**: "price chart", "chart data", "technical analysis", "price graph"
**Example**: "Show me a price chart for ETH" | "Generate chart data for BTC"

#### GET_VOLUME_AND_LIQUIDITY
Analyze trading volume and liquidity data across DEXs.

**Triggers**: "volume", "liquidity", "trading volume", "pool data", "dex data"
**Example**: "Show me volume data for ETH" | "Check liquidity for USDC pools"

### 🖼️ NFT Analytics

#### GET_NFTS
Get NFT collection data for wallet addresses.

**Triggers**: "nft", "nfts", "collectible", "collectibles", "collection"
**Example**: "Show me NFTs for 0x1234..." | "Check my NFT collection"

#### GET_NFT_COLLECTION_METADATA
Detailed metadata for NFT collections.

**Triggers**: "nft collection", "collection metadata", "collection info"
**Example**: "Get metadata for Bored Ape Yacht Club" | "Show collection details"

#### GET_NFT_TRAITS
Analyze NFT traits and rarity data.

**Triggers**: "nft traits", "rarity", "trait analysis", "nft attributes"
**Example**: "Show me traits for this NFT" | "Analyze rarity data"

#### GET_NFT_MARKETPLACE_DATA
Marketplace activity and trading data for NFTs.

**Triggers**: "nft marketplace", "nft trading", "marketplace data", "nft sales"
**Example**: "Show marketplace data for CryptoPunks" | "Check NFT trading volume"

#### GET_NFT_OWNERSHIP_DATA
Ownership analytics and holder distribution.

**Triggers**: "nft ownership", "holder data", "ownership analytics"
**Example**: "Show ownership data for this collection" | "Analyze holder distribution"

#### GET_NFT_VALUATION
NFT valuation and pricing analysis.

**Triggers**: "nft valuation", "nft price", "nft value", "price estimate"
**Example**: "Value this NFT" | "Get price estimate for my collectible"

#### GET_NFT_ANALYTICS
Comprehensive NFT analytics and insights.

**Triggers**: "nft analytics", "nft insights", "collection analytics"
**Example**: "Show me NFT analytics" | "Analyze this collection's performance"

### 🔄 Transaction Analysis

#### GET_TRANSACTION_HISTORY
Comprehensive transaction history for addresses.

**Triggers**: "transaction history", "tx history", "transactions", "activity"
**Example**: "Show transaction history for 0x1234..." | "Get my recent transactions"

#### GET_TRANSACTION_DETAILS
Detailed analysis of individual transactions.

**Triggers**: "transaction details", "tx details", "analyze transaction"
**Example**: "Analyze this transaction hash" | "Show details for this tx"

### 🌐 Network & Infrastructure

#### GET_NETWORK_INFO
Information about blockchain networks and their status.

**Triggers**: "network info", "blockchain info", "network details"
**Example**: "Show me Ethereum network info" | "Get network details for Polygon"

#### GET_NETWORK_FEATURES
Feature capabilities and specifications of networks.

**Triggers**: "network features", "blockchain features", "network capabilities"
**Example**: "What features does Arbitrum have?" | "Show network capabilities"

#### GET_NETWORK_HEALTH
Real-time network health and performance metrics.

**Triggers**: "network health", "network status", "blockchain health"
**Example**: "Check Ethereum network health" | "Show network performance"

#### GET_GAS_PRICE
Current gas prices and fee estimates across networks.

**Triggers**: "gas price", "gas fees", "transaction fees", "network fees"
**Example**: "What are current gas prices?" | "Check Ethereum gas fees"

#### GET_BLOCK_EXPLORER
Block explorer links and blockchain data access.

**Triggers**: "block explorer", "explorer link", "blockchain explorer"
**Example**: "Get block explorer for this address" | "Show explorer link"

### 🏛️ DeFi & Applications

#### GET_APP_POSITIONS
DeFi application positions and yield farming data.

**Triggers**: "app positions", "defi positions", "yield positions", "protocol positions"
**Example**: "Show my DeFi positions" | "Check my yield farming positions"

#### GET_ACCOUNT_INFO
Comprehensive account information and social data.

**Triggers**: "account info", "account data", "profile info", "address info"
**Example**: "Get account info for this address" | "Show profile data"

#### GET_FARCASTER_DATA
Farcaster social protocol integration and data.

**Triggers**: "farcaster", "farcaster data", "social data"
**Example**: "Get Farcaster data for this user" | "Show social profile"

## Providers (5 Total)

### portfolioProvider
Provides portfolio data context for conversations. Automatically extracts wallet addresses and provides relevant portfolio information.

**Dynamic**: Yes - Updates based on context
**Usage**: Automatically activated when wallet addresses are mentioned

### transactionProvider
Supplies transaction history context for wallet addresses found in conversations.

**Dynamic**: Yes - Extracts addresses from messages
**Usage**: Provides transaction context when analyzing wallet activity

### accountProvider
Delivers comprehensive account information including balances and metadata.

**Dynamic**: Yes - Address-based activation
**Usage**: Account-level insights and information

### defiProvider
Provides DeFi protocol positions and yield farming context.

**Dynamic**: Yes - Protocol and address-based
**Usage**: DeFi application context and position analysis

### marketDataProvider
Supplies market data, analytics, and trends for tokens and overall market metrics.

**Dynamic**: Yes - Token and market context
**Usage**: Real-time market insights and token analytics

## Supported Networks (50+)

**Major Networks**:
- Ethereum
- Polygon
- Arbitrum
- Optimism
- Base
- BNB Chain (BSC)
- Avalanche
- Fantom

**Layer 2 Solutions**:
- Arbitrum Nova
- Polygon zkEVM
- Optimism Bedrock
- Base

**Emerging Networks**:
- Linea
- Scroll
- zkSync Era
- Manta Pacific
- Blast
- Mode Network

**And 30+ additional networks** supported through Zapper's comprehensive infrastructure.

## Error Handling

The plugin includes comprehensive error handling for:

- ✅ Invalid API keys and authentication
- ✅ Network connectivity issues
- ✅ Malformed wallet addresses
- ✅ GraphQL query errors and timeouts
- ✅ Rate limiting and quota management
- ✅ Cross-chain data inconsistencies
- ✅ NFT metadata failures
- ✅ Price data unavailability

## API Usage Examples

### Correct GraphQL Query Pattern

```typescript
// ✅ CORRECT - Use chainIds instead of networks
const query = `
  query GetPortfolio($addresses: [Address!]!, $chainIds: [Int!]) {
    portfolioV2(addresses: $addresses, chainIds: $chainIds) {
      tokenBalances {
        byToken {
          edges {
            node {
              symbol
              balance
              balanceUSD
              network {
                name  // ✅ Access network name via object property
              }
            }
          }
        }
      }
    }
  }
`;

// ✅ CORRECT - Use chain IDs instead of network names
const variables = {
  addresses: ['0x1234...'],
  chainIds: [1, 137, 42161] // Ethereum, Polygon, Arbitrum
};
```

### Correct Authentication Headers

```typescript
// ✅ CORRECT - Use x-zapper-api-key header
const headers = {
  'Content-Type': 'application/json',
  'x-zapper-api-key': process.env.ZAPPER_API_KEY,
  'User-Agent': 'ElizaOS-ZapperPlugin/1.0.0'
};
```

### Network Name to Chain ID Mapping

```typescript
// ✅ CORRECT - Map network names to chain IDs
const NETWORK_TO_CHAIN_ID = {
  ethereum: 1,
  polygon: 137,
  arbitrum: 42161,
  optimism: 10,
  base: 8453,
  avalanche: 43114,
  bsc: 56,
  fantom: 250,
  // ... additional networks
};
```

### Response Data Parsing

```typescript
// ✅ CORRECT - Parse network object safely
const tokenBalances = edges.map(edge => ({
  symbol: edge.node.symbol,
  balance: edge.node.balance,
  balanceUSD: edge.node.balanceUSD,
  network: edge.node.network?.name || 'unknown', // Safe access
  tokenAddress: edge.node.tokenAddress
}));
```

## Troubleshooting

### Common GraphQL Query Errors

#### "Field 'networks' not found" Error
```typescript
// ❌ WRONG - This causes HTTP 400 errors
query GetData($networks: [Network!]) {
  portfolioV2(networks: $networks) { ... }
}

// ✅ CORRECT - Use chainIds parameter
query GetData($chainIds: [Int!]) {
  portfolioV2(chainIds: $chainIds) { ... }
}
```

#### "Unknown argument 'networks'" Error
```typescript
// ❌ WRONG - networks parameter doesn't exist
const variables = {
  address: '0x1234...',
  networks: ['ethereum', 'polygon']
};

// ✅ CORRECT - Use chainIds array
const variables = {
  addresses: ['0x1234...'], // Note: also use addresses array
  chainIds: [1, 137] // Ethereum, Polygon
};
```

### Authentication Issues

#### Invalid API Key Format
```typescript
// ❌ WRONG - Bearer token format causes 401 errors
headers: {
  'Authorization': `Bearer ${apiKey}`
}

// ✅ CORRECT - Use x-zapper-api-key header
headers: {
  'x-zapper-api-key': apiKey
}
```

### Response Parsing Errors

#### Network Access Error
```typescript
// ❌ WRONG - Direct network access fails
const network = edge.node.network; // Returns object, not string

// ✅ CORRECT - Access network name property
const network = edge.node.network?.name; // Returns string
```

### Test Mock Data Issues

#### Incorrect Mock Structure
```typescript
// ❌ WRONG - Old mock data structure
const mockData = {
  network: 'ethereum' // String value
};

// ✅ CORRECT - New mock data structure  
const mockData = {
  network: {
    name: 'ethereum' // Object with name property
  }
};
```

### Rate Limiting and Performance

The plugin includes built-in rate limiting and performance optimizations:

- **Rate Limit**: 100 requests per minute with burst capability
- **Caching**: Intelligent 5-minute cache for portfolio data
- **Retry Logic**: Automatic retry with exponential backoff
- **Circuit Breaker**: Prevents cascading failures
- **Performance Monitoring**: Real-time metrics and optimization

### Common Pitfalls

1. **Don't use `networks` parameter** - Always use `chainIds`
2. **Don't use Bearer tokens** - Always use `x-zapper-api-key` header
3. **Don't access network directly** - Always use `network?.name`
4. **Don't use `config.apiUrl!`** - Avoid non-null assertions
5. **Update test mocks** - Use object structure for network data

## Development

```bash
# Install dependencies
bun install

# Build the plugin
bun run build

# Run tests (645 tests, 100% pass rate)
bun run test

# Format code
bun run format

# Type checking
bun run lint
```

## Testing

```bash
# Run all tests
bun test

# Run tests with coverage
bun test --coverage

# Run tests in watch mode
bun test --watch
```

The plugin includes **645 comprehensive tests** covering:
- All 25 actions with validation and handler testing
- All 5 providers with dynamic context testing
- Error scenarios and edge cases
- GraphQL integration and API responses
- Type safety and validation

## API Reference

### Core Configuration

```typescript
interface ZapperConfig {
  apiKey: string;
  apiUrl?: string;
}
```

### Portfolio Data

```typescript
interface PortfolioData {
  totalValueUSD: number;
  tokenBalances: TokenBalance[];
  networks: string[];
  nftCount?: number;
  defiPositions?: DefiPosition[];
}

interface TokenBalance {
  symbol: string;
  name: string;
  balance: string;
  balanceUSD: number;
  network: string;
  address: string;
  price?: number;
  change24h?: number;
}
```

### NFT Data

```typescript
interface NFTMetadata {
  name: string;
  description: string;
  image: string;
  collection: string;
  tokenId: string;
  network: string;
  traits?: NFTTrait[];
  valuation?: NFTValuation;
}

interface NFTTrait {
  trait_type: string;
  value: string;
  rarity?: number;
}
```

### Transaction Data

```typescript
interface TransactionData {
  hash: string;
  from: string;
  to: string;
  value: number;
  gasUsed: number;
  gasPrice: number;
  timestamp: string;
  network: string;
  type?: string;
  decodedData?: any;
}
```

### DeFi Positions

```typescript
interface DefiPosition {
  protocol: string;
  network: string;
  type: 'lending' | 'borrowing' | 'liquidity' | 'staking' | 'yield_farming';
  totalValue: number;
  assets: DeFiAsset[];
  apr?: number;
  apy?: number;
}
```

## Performance

- **Response Time**: < 2s average for most queries
- **Rate Limiting**: Built-in quota management
- **Caching**: Intelligent caching for frequently accessed data
- **Error Recovery**: Automatic retry mechanisms
- **Memory Usage**: Optimized for production deployments

## Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Links

- [Zapper Protocol](https://zapper.xyz)
- [Zapper API Documentation](https://protocol.zapper.xyz/docs/api/)
- [ElizaOS Documentation](https://elizaos.github.io/eliza/)
- [Plugin Repository](https://github.com/elizaos/eliza)

## Support

For support, please visit our [GitHub Issues](https://github.com/elizaos/eliza/issues) or join our [Discord community](https://discord.gg/elizaos).

---

**Version**: 1.0.5 | **Actions**: 25 | **Providers**: 5 | **Networks**: 50+ | **Tests**: 645 ✅