# WaveTrace Client

A lightweight, TypeScript-first web analytics client for tracking user behavior, page views, clicks, and custom events. The primary goal for this client is to provide analytics on a specific user by tracking his/her activity on a DApp. Some tracking are automated while some could be manually tracked.

So, it provides:

- Both automated and manual tracking for users
- Connect annoymous/signed out user tracking linked to existing/future wallet/user login

## Features

- **Lightweight**: Only 4.8KB minified
- **TypeScript Support**: Full type definitions included
- **Zero Dependencies**: No external dependencies
- **DApp Ready**: Built-in wallet tracking for Web3 applications
- **Auto-Detect Wallets**: Automatically detect and track MetaMask, Coinbase, and other wallet connections
- **Transaction Tracking**: Complete lifecycle tracking for blockchain transactions (initiated → pending → executed/failed)
- **Offline Queue**: localStorage persistence - events are saved and sent when back online
- **Retry Logic**: Exponential backoff for failed requests with configurable retries
- **Smart Click Tracking**: Intelligent filtering - track only buttons, links, and important interactions
- **Automatic Tracking**: Auto-track page views and clicks with configurable modes
- **Event Batching**: Efficient event batching with configurable batch size and timeout
- **User Identification**: Track user ID, username, wallet addresses, and custom properties
- **Anonymous-to-Wallet Linking**: Seamlessly connect anonymous activity to wallet addresses
- **Session Management**: Automatic session tracking with 30-minute timeout
- **Privacy-Conscious**: Configurable data collection
- **Multiple Formats**: ESM, CommonJS, and browser IIFE builds

## Installation

```bash
npm install @wavetrace/client
```

## Usage

### Basic Setup (Browser)

```html
<script src="https://unpkg.com/@wavetrace/client/dist/wavetrace.min.js"></script>
<script>
  const tracker = new WaveTrace.WaveTracker({
    endpoint: "https://your-api.com/track",
    autoTrackPageViews: true,
    autoTrackClicks: true,
  });
</script>
```

### ES Modules

```typescript
import { WaveTracker } from "@wavetrace/client";

const tracker = new WaveTracker({
  endpoint: "https://your-api.com/track",
  autoTrackPageViews: true,
  autoTrackClicks: true,
  batchSize: 10,
  batchTimeout: 5000,
  debug: false,
});
```

### DApp Wallet Tracking

For Web3/DApp applications, track wallet connections with automatic detection or manual tracking:

#### Automatic Wallet Detection (Recommended)

```typescript
const tracker = new WaveTracker({
  endpoint: "https://your-api.com/track",
  autoDetectWallet: true, // Automatically detect wallet connections
  autoTrackPageViews: true,
});

// That's it! Wallet connections are automatically tracked
// No need to manually call connectWallet() or disconnectWallet()
```

The tracker automatically:
- Detects when users connect wallets (MetaMask, Coinbase, etc.)
- Tracks `wallet_connected` event with wallet address and chain ID
- Links anonymous activity to wallet address
- Detects account switches
- Detects disconnections
- Handles network changes

#### Manual Wallet Tracking

```typescript
// When user connects wallet (if not using auto-detection)
await tracker.connectWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", {
  properties: {
    chainId: 1,
    walletType: "metamask",
  },
});

// Track DApp events
tracker.track("swap_executed", {
  fromToken: "ETH",
  toToken: "USDC",
  amount: "1.5",
  txHash: "0x...",
});

// When user disconnects
await tracker.disconnectWallet();
```

**How it works:**

1. User browses your DApp anonymously → tracked with anonymous ID
2. User connects wallet → automatically linked to wallet address
3. All future events include wallet address
4. Backend receives `wallet_connected` event with `previousAnonymousId` for user merging

See [DAPP-INTEGRATION.md](./DAPP-INTEGRATION.md) for complete DApp integration guide.

### Smart Click Tracking

WaveTrace includes intelligent click filtering to reduce noise and focus on meaningful interactions.

**Default behavior** (tracks only important elements):

```typescript
const tracker = new WaveTracker({
  endpoint: "...",
  autoTrackClicks: true, // Uses 'important' mode - tracks buttons, links, data-track elements
});
```

**Track specific elements with data-track:**

```html
<button data-track="connect-wallet">Connect Wallet</button>
<button data-track="execute-swap">Swap</button>
<div data-track="feature-card">
  <!-- Entire card is trackable -->
</div>
```

**Advanced configuration:**

```typescript
const tracker = new WaveTracker({
  endpoint: "...",
  autoTrackClicks: {
    mode: "important", // 'all' | 'important' | 'data-attribute' | 'custom'
    ignoreSelectors: ["[data-track-ignore]", ".no-track"],
    customSelectors: [".my-button", "[data-action]"], // For 'custom' mode
  },
});
```

**Tracking modes:**

- `important` (default): Buttons, links, and `data-track` elements
- `all`: Every click on the page
- `data-attribute`: Only elements with `data-track`
- `custom`: Use your own CSS selectors

See [CLICK-TRACKING.md](./CLICK-TRACKING.md) for complete guide and examples.

### User Identification

Track user information with your events:

```typescript
tracker.identify({
  userId: "12345",
  username: "john_doe",
  wallet: "0x1234567890abcdef",
  email: "john@example.com",
  properties: {
    plan: "premium",
    signupDate: "2024-01-01",
  },
});
```

### Transaction Tracking (DApps)

Automatically track the complete lifecycle of blockchain transactions:

```typescript
// Track a swap transaction with automatic lifecycle tracking
const tx = await tracker.trackTransaction(
  "swap",
  async () => {
    // Your transaction logic
    return await contract.swap(fromToken, toToken, amount);
  },
  {
    fromToken: "ETH",
    toToken: "USDC",
    amount: "1.5",
  }
);

// Automatically tracks:
// 1. swap_initiated - When transaction starts
// 2. swap_pending - Transaction submitted with txHash
// 3. swap_executed - Transaction confirmed with gasUsed, blockNumber
// 4. swap_failed - If transaction fails (with error details)
```

The transaction helper captures:
- Transaction hash
- Gas used
- Block number
- Confirmation time
- Error messages (if failed)

This eliminates the need to manually track each transaction state.

### Track Custom Events

```typescript
// Simple event
tracker.track("button_click");

// Event with properties
tracker.track("purchase", {
  productId: "prod_123",
  amount: 99.99,
  currency: "USD",
});
```

### Manual Page View Tracking

```typescript
// Track page view with custom properties
tracker.trackPageView({
  campaign: "summer_sale",
  source: "email",
});
```

### Configuration Options

```typescript
interface TrackerConfig {
  // Required: Your tracking endpoint URL
  endpoint: string;

  // Auto-detect wallet connections (MetaMask, Coinbase, etc.)
  // Automatically tracks wallet_connected events and links anonymous activity
  // (default: false)
  autoDetectWallet?: boolean;

  // Enable offline queue with localStorage persistence
  // Events are saved locally and sent when back online
  // (default: true)
  offlineQueue?: boolean;

  // Maximum number of events to store offline
  // (default: 100)
  maxOfflineEvents?: number;

  // Retry configuration for failed requests
  retry?: {
    enabled?: boolean;           // Enable retry logic (default: true)
    maxRetries?: number;         // Max retry attempts (default: 3)
    initialDelay?: number;       // Initial delay in ms (default: 1000)
    backoffMultiplier?: number;  // Exponential backoff multiplier (default: 2)
  };

  // Auto-track page views (default: true)
  autoTrackPageViews?: boolean;

  // Auto-track link clicks (default: true)
  autoTrackClicks?: boolean;

  // Batch size for sending events (0 = send immediately, default: 10)
  batchSize?: number;

  // Max time in ms to wait before sending batch (default: 5000)
  batchTimeout?: number;

  // Include referrer information (default: true)
  includeReferrer?: boolean;

  // Include user agent (default: true)
  includeUserAgent?: boolean;

  // Custom headers for tracking requests
  customHeaders?: Record<string, string>;

  // Enable debug logging (default: false)
  debug?: boolean;
}
```

## Event Structure

All events sent to your endpoint follow this structure:

```typescript
{
  events: [
    {
      type: "pageview" | "click" | "custom_event_name",
      timestamp: "2024-01-15T10:30:00.000Z",
      url: "https://example.com/page",
      title: "Page Title",
      referrer: "https://google.com",
      userAgent: "Mozilla/5.0...",
      screen: { width: 1920, height: 1080 },
      viewport: { width: 1200, height: 800 },
      sessionId: "1234567890-abcdef",
      user: {
        userId: "12345",
        username: "john_doe",
        wallet: "0x1234...",
        properties: {
          /* custom user properties */
        },
      },
      properties: {
        /* event-specific properties */
      },
    },
  ];
}
```

### Click Events

Click events include additional properties:

```typescript
{
  type: 'click',
  properties: {
    tagName: 'button',
    id: 'submit-btn',
    className: 'btn btn-primary',
    href: 'https://example.com/link', // for anchor tags
    text: 'Click Me',
    x: 450,  // click coordinates
    y: 200
  }
}
```

## Advanced Usage

### Manual Event Flushing

```typescript
// Flush all queued events immediately
await tracker.flush();
```

### Disable Click Tracking

```typescript
tracker.disableClickTracking();
```

### Cleanup

```typescript
// Clean up resources and flush remaining events
tracker.destroy();
```

## Server-Side Endpoint

Your tracking endpoint should accept POST requests with JSON payloads. Here's a simple example using Express:

```typescript
app.post("/track", express.json(), (req, res) => {
  const { events } = req.body;

  // Store events in your database
  events.forEach((event) => {
    // Add IP address from request
    event.ip = req.ip;

    // Save to database
    db.events.insert(event);
  });

  res.json({ success: true });
});
```

## Building from Source

```bash
# Install dependencies
npm install

# Build all formats
npm run build

# Build and watch for changes
npm run dev
```

## Browser Support

- Modern browsers (Chrome, Firefox, Safari, Edge)
- ES2020+ features required
- LocalStorage required for session management

## Privacy Considerations

- IP addresses are captured server-side (from request headers)
- User agent strings are optional (configurable)
- No cookies are used
- Session data stored in localStorage only
- All tracking is explicit and configurable

## License

MIT

## Roadmap

### Completed ✅
- ✅ Auto-detect wallet connections (MetaMask, Coinbase, etc.)
- ✅ Offline queue persistence with localStorage
- ✅ Retry logic with exponential backoff
- ✅ Transaction lifecycle tracking helper

### Planned
- React integration with hooks
- Next.js plugin
- Vue integration
- Server-side tracking
- Custom storage adapters
- Event validation and schemas
- Performance monitoring
- Multi-wallet management
- GDPR compliance helpers
