HUNCH API Reference

Overview

HUNCH provides both REST APIs through Supabase and direct blockchain interaction through smart contracts. This documentation covers all available endpoints and methods.

Authentication

Wallet-Based Authentication

HUNCH uses wallet signatures for authentication. Users sign a message to prove wallet ownership.

const signature = await signer.signMessage("Login to HUNCH");

REST API Endpoints

Base URL

  • Production: https://your-project.supabase.co/rest/v1/

  • Headers Required:

    • apikey: Your Supabase anon key

    • Authorization: Bearer token (for authenticated requests)

Markets

Get All Enhanced Markets

GET /markets_enhanced

Query Parameters:

  • select: Columns to return (default: all)

  • market_type: Filter by type (binary, multi_choice)

  • resolved: Filter by resolution status (true, false)

  • category: Filter by category

Response:

{
  "data": [
    {
      "id": "uuid",
      "market_id": "string",
      "question": "string",
      "description": "string",
      "category": "string",
      "market_type": "binary",
      "creator_address": "0x...",
      "end_time": "2024-12-31T23:59:59Z",
      "resolved": false,
      "winning_option_index": null,
      "total_volume": "1000000000000000000",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Create Enhanced Market

POST /markets_enhanced

Request Body:

{
  "market_id": "unique-market-id",
  "question": "Will Bitcoin reach $100k by 2024?",
  "description": "Detailed market description",
  "category": "Cryptocurrency",
  "market_type": "binary",
  "creator_address": "0x742d35Cc...",
  "end_time": "2024-12-31T23:59:59Z"
}

Update Market

PATCH /markets_enhanced?id=eq.{market_id}

Request Body:

{
  "resolved": true,
  "winning_option_index": 0,
  "total_volume": "5000000000000000000"
}

Market Options

Get Market Options

GET /market_options?market_id=eq.{market_id}

Response:

{
  "data": [
    {
      "id": "uuid",
      "market_id": "market-id",
      "option_index": 0,
      "option_text": "Yes",
      "shares_outstanding": "1000000000000000000",
      "total_volume": "500000000000000000",
      "current_price": "700000000000000000",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Create Market Options

POST /market_options

Request Body:

{
  "market_id": "market-id",
  "option_index": 0,
  "option_text": "Yes",
  "shares_outstanding": "0",
  "total_volume": "0",
  "current_price": "500000000000000000"
}

X (Twitter) Connections

Get User's X Connection

GET /x_connections?user_address=eq.{wallet_address}

Response:

{
  "data": [
    {
      "id": "uuid",
      "user_address": "0x742d35Cc...",
      "x_user_id": "123456789",
      "x_username": "username",
      "x_display_name": "Display Name",
      "x_profile_image_url": "https://...",
      "x_follower_count": 1000,
      "x_verified": true,
      "access_token": "encrypted_token",
      "access_token_secret": "encrypted_secret",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Smart Contract API

Contract Addresses

Mainnet

const CONTRACT_ADDRESSES = {
  marketFactory: "0x...",
  oracle: "0x...",
  multiOptionMarketFactory: "0x..."
};

Market Factory Functions

Create Market

const marketFactory = new ethers.Contract(address, abi, signer);

await marketFactory.createMarket(
  "Market question",
  "Detailed description", 
  endTimestamp,
  "Category"
);

Parameters:

  • question (string): Market question

  • description (string): Detailed description

  • endTime (uint256): Unix timestamp for market end

  • category (string): Market category

Returns: Transaction hash

Get Market

const marketInfo = await marketFactory.getMarket(marketId);

Returns:

{
  id: "market-address",
  question: "string",
  description: "string", 
  endTime: BigNumber,
  resolved: boolean,
  outcome: 0 | 1, // 0 = NO, 1 = YES
  yesShares: BigNumber,
  noShares: BigNumber,
  totalVolume: BigNumber,
  creator: "0x...",
  category: "string"
}

Market Functions

Buy Shares

const market = new ethers.Contract(marketAddress, marketABI, signer);

await market.buyShares(
  side, // 0 = NO, 1 = YES
  shares,
  { value: ethers.utils.parseEther("0.1") }
);

Sell Shares

await market.sellShares(side, shares);

Get Price

const price = await market.getPrice(side);
// Returns price in wei

Get User Shares

const [yesShares, noShares] = await market.getUserShares(userAddress);

Claim Winnings

await market.claimWinnings();

Oracle Functions

Resolve Market

const oracle = new ethers.Contract(oracleAddress, oracleABI, signer);

await oracle.resolveMarket(marketAddress, outcome);

Parameters:

  • marketAddress (address): Market contract address

  • outcome (uint8): 0 = NO, 1 = YES

WebSocket Events

Real-time Market Updates

// Using Supabase realtime
const supabase = createClient(url, key);

const subscription = supabase
  .channel('market-updates')
  .on('postgres_changes', 
    { 
      event: '*', 
      schema: 'public', 
      table: 'markets_enhanced' 
    },
    (payload) => {
      console.log('Market update:', payload);
    }
  )
  .subscribe();

Blockchain Events

// Listen to market creation events
marketFactory.on("MarketCreated", (marketId, marketAddress, creator, question) => {
  console.log("New market:", question);
});

// Listen to trade events
market.on("SharesPurchased", (buyer, side, shares, cost) => {
  console.log("Trade executed:", { buyer, side, shares, cost });
});

Rate Limits

REST API

  • Anonymous: 100 requests per minute

  • Authenticated: 1000 requests per minute

Blockchain

  • Limited by network: Gas and block time constraints

  • Recommended: Max 1 transaction per block

Error Handling

HTTP Status Codes

  • 200: Success

  • 201: Created

  • 400: Bad Request

  • 401: Unauthorized

  • 403: Forbidden

  • 404: Not Found

  • 429: Rate Limited

  • 500: Internal Server Error

Common Error Responses

{
  "error": {
    "code": "PGRST116",
    "message": "The result contains 0 rows",
    "details": "Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row"
  }
}

Smart Contract Errors

// Common revert reasons
"Market has ended"
"Insufficient shares"
"Market already resolved"
"Unauthorized access"
"Invalid parameters"

SDK Example

JavaScript/TypeScript SDK

import { HunchSDK } from '@hunch/sdk';

const hunch = new HunchSDK({
  network: 'mainnet', // or 'polygon', 'sepolia'
  provider: window.ethereum,
  supabaseUrl: 'your-supabase-url',
  supabaseKey: 'your-supabase-key'
});

// Create market
const market = await hunch.createMarket({
  question: "Will Bitcoin reach $100k?",
  description: "Resolves YES if BTC >= $100,000",
  endTime: new Date('2024-12-31'),
  category: 'Cryptocurrency'
});

// Buy shares
await hunch.buyShares(market.id, 'YES', '0.1');

// Get portfolio
const portfolio = await hunch.getPortfolio(userAddress);

Testing

Testnet Configuration

const config = {
  network: 'sepolia',
  contracts: {
    marketFactory: '0x...',
    oracle: '0x...'
  },
  rpcUrl: 'https://sepolia.infura.io/v3/your-key'
};

Mock Data

Test endpoints available with mock data for development:

  • /api/mock/markets

  • /api/mock/trades

  • /api/mock/portfolio

Last updated