Skip to main content

Iframe Integration

Raze can be embedded as an iframe in your application, allowing you to control wallet whitelisting and receive real-time trading data programmatically.

Basic Setup

<iframe 
  id="trading-iframe" 
  src="https://frame.raze.sh/sol/" 
  frameborder="0"
  width="100%"
  height="800px">
</iframe>

TypeScript Setup

// Get iframe reference
const iframe = document.getElementById('trading-iframe') as HTMLIFrameElement;

// Listen for messages from iframe
window.addEventListener('message', (event: MessageEvent) => {
  if (event.source !== iframe.contentWindow) return;
  handleIframeMessage(event.data);
});

// Send message to iframe
function sendMessage(message: IframeMessage): void {
  iframe.contentWindow?.postMessage(message, '*');
}

API Reference

Commands (Sent to Iframe)

  • ADD_WALLETS
  • CLEAR_WALLETS
  • GET_WALLETS
Add wallets to the whitelist for tracking.
interface AddWalletsMessage {
  type: 'ADD_WALLETS';
  wallets: (string | Wallet)[];
}

// Wallet formats supported:
// String: "ABCD" or "ABCD:Label"
// Object: { address: "ABCD", label: "Label" }
Example:
sendMessage({
  type: 'ADD_WALLETS',
  wallets: [
    { address: 'ABC123...', label: 'Whale Trader' },
    'DEF456...:Smart Money',
    'GHI789...'
  ]
});

Responses (Received from Iframe)

IFRAME_READY
object
Sent when iframe is loaded and ready for communication.
{ type: 'IFRAME_READY' }
WALLETS_ADDED
object
Confirms wallets were added successfully.
{ 
  type: 'WALLETS_ADDED',
  success: boolean,
  count: number
}
WHITELIST_TRADING_STATS
object
Real-time trading statistics for whitelisted addresses.
{
  type: 'WHITELIST_TRADING_STATS',
  data: {
    bought: number,    // Total SOL bought
    sold: number,      // Total SOL sold
    net: number,       // Net SOL (sold - bought)
    trades: number,    // Total number of trades
    solPrice: number,  // Current SOL price in USD
    timestamp: number  // When stats were calculated
  }
}
WHITELIST_TRADE
object
Individual trade data from whitelisted addresses.
{
  type: 'WHITELIST_TRADE',
  data: {
    type: 'buy' | 'sell',
    address: string,
    tokensAmount: number,
    avgPrice: number,
    solAmount: number,
    timestamp: number,
    signature: string
  }
}
TOKEN_PRICE_UPDATE
object
Real-time token price updates from all trading activity.
{
  type: 'TOKEN_PRICE_UPDATE',
  data: {
    tokenPrice: number,
    tokenMint: string,
    timestamp: number,
    tradeType: 'buy' | 'sell',
    volume: number
  }
}

Complete Integration Example

TypeScript Class

class TradingAppIframe {
  private iframe: HTMLIFrameElement;
  private isReady: boolean = false;
  private messageQueue: IframeMessage[] = [];

  constructor(iframeId: string) {
    this.iframe = document.getElementById(iframeId) as HTMLIFrameElement;
    this.setupMessageListener();
  }

  private setupMessageListener(): void {
    window.addEventListener('message', (event) => {
      if (event.source !== this.iframe.contentWindow) return;
      this.handleMessage(event.data);
    });
  }

  private handleMessage(data: IframeResponse): void {
    switch (data.type) {
      case 'IFRAME_READY':
        this.isReady = true;
        this.processMessageQueue();
        break;
      
      case 'WHITELIST_TRADING_STATS':
        console.log('Trading stats:', data.data);
        break;
      
      case 'WHITELIST_TRADE':
        console.log('New trade:', data.data);
        break;
    }
  }

  private sendMessage(message: IframeMessage): void {
    if (!this.isReady) {
      this.messageQueue.push(message);
      return;
    }
    this.iframe.contentWindow?.postMessage(message, '*');
  }

  // Public API
  addWallets(wallets: (string | Wallet)[]): void {
    this.sendMessage({ type: 'ADD_WALLETS', wallets });
  }

  clearWallets(): void {
    this.sendMessage({ type: 'CLEAR_WALLETS' });
  }

  getCurrentWallets(): void {
    this.sendMessage({ type: 'GET_WALLETS' });
  }
}

React Hook

import { useEffect, useRef, useState } from 'react';

export function useTradingIframe(iframeRef: React.RefObject<HTMLIFrameElement>) {
  const [isReady, setIsReady] = useState(false);
  const [tradingStats, setTradingStats] = useState(null);
  const [recentTrades, setRecentTrades] = useState([]);

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      if (event.source !== iframeRef.current?.contentWindow) return;
      
      switch (event.data.type) {
        case 'IFRAME_READY':
          setIsReady(true);
          break;
        case 'WHITELIST_TRADING_STATS':
          setTradingStats(event.data.data);
          break;
        case 'WHITELIST_TRADE':
          setRecentTrades(prev => [event.data.data, ...prev].slice(0, 50));
          break;
      }
    };

    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, [iframeRef]);

  const sendMessage = (message: any) => {
    iframeRef.current?.contentWindow?.postMessage(message, '*');
  };

  return {
    isReady,
    tradingStats,
    recentTrades,
    addWallets: (wallets: any[]) => sendMessage({ type: 'ADD_WALLETS', wallets }),
    clearWallets: () => sendMessage({ type: 'CLEAR_WALLETS' }),
    getWallets: () => sendMessage({ type: 'GET_WALLETS' })
  };
}

Security Considerations

Origin Validation

Always validate the origin of messages in production:
window.addEventListener('message', (event) => {
  // Validate origin
  if (event.origin !== 'https://frame.raze.sh') {
    console.warn('Untrusted origin:', event.origin);
    return;
  }
  
  handleMessage(event.data);
});

Content Security Policy

Add CSP headers to allow iframe embedding:
Content-Security-Policy: frame-ancestors 'self' https://trusted-domain.com;

Input Validation

Validate wallet addresses before sending:
function isValidSolanaAddress(address: string): boolean {
  return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
}

Customization

Theme Customization

Create custom themes by editing CSS variables:
:root {
  /* Primary Colors */
  --color-primary: #02b36d;
  --color-primary-light: #04d47c;
  --color-primary-dark: #01a35f;
  
  /* Background Colors */
  --color-bg-primary: #050a0e;
  --color-bg-secondary: #0a1419;
  --color-bg-tertiary: #091217;
  
  /* Text Colors */
  --color-text-primary: #e4fbf2;
  --color-text-secondary: #7ddfbd;
  
  /* Effects */
  --backdrop-blur: 10px;
  --shadow-intensity: 0.3;
  --glow-intensity: 0.5;
}

Whitelabel Setup

  1. Update brand.json with your branding
  2. Replace src/logo.png with your logo
  3. Create a custom CSS theme
  4. Run npm run generate-html
  5. Build and deploy

Full Customization Guide

See all customization options

Best Practices

1

Wait for Ready Signal

Always wait for IFRAME_READY before sending commands
2

Queue Messages

Queue messages if iframe isn’t ready yet
3

Validate Input

Validate wallet addresses before sending
4

Handle Timeouts

Implement timeouts for async operations
5

Error Handling

Always handle potential errors and edge cases