{"version":3,"sources":["../src/logger.ts","../src/kv-store.ts","../src/utils.ts","../src/prediction-contract-store.ts","../src/market-store.ts","../src/user-balance-store.ts","../src/user-stats-store.ts","../src/prediction-store.ts"],"names":["kv","STACKS_MAINNET","broadcastTransaction","makeContractCall","createClient","cvToHex","cvToValue","hexToCV","errorMessage","uintCV","stringAsciiCV","receiptInfo","name","listCV","PostConditionMode","tupleCV","bufferCV","Cl","createClerkClient","fetchCallReadOnlyFunction","ClarityType"],"mappings":"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","file":"prediction-store.cjs","sourcesContent":["// Simple logger interface\nexport interface Logger {\n  info: (obj: Record<string, unknown>, msg?: string) => void;\n  error: (obj: Record<string, unknown>, msg?: string) => void;\n  warn: (obj: Record<string, unknown>, msg?: string) => void;\n  debug: (obj: Record<string, unknown>, msg?: string) => void;\n  child: (bindings: object) => Logger;\n}\n\n/**\n * Centralized logger configuration\n * \n * This provides consistent logging across all modules with proper\n * context and standardized error handling.\n */\n\n// Simple console-based logger factory - no external dependencies\nconst createLogger = (): Logger => {\n  // Get log level from environment or default to 'info'\n  const logLevel = process.env.LOG_LEVEL || 'info';\n  \n  // Map log levels to numeric values for comparison\n  const logLevels = {\n    debug: 0,\n    info: 1,\n    warn: 2,\n    error: 3\n  } as const;\n  \n  // Current log level\n  const currentLevelValue = logLevel in logLevels \n    ? logLevels[logLevel as keyof typeof logLevels] \n    : logLevels.info;\n  \n  // Format a log message with timestamp and metadata\n  const formatLog = (level: string, obj: Record<string, unknown>, msg?: string): string => {\n    const timestamp = new Date().toISOString();\n    const service = 'wisdom-sdk';\n    const objStr = JSON.stringify(obj);\n    return `[${timestamp}] ${level.toUpperCase()} [${service}] ${msg || ''} ${objStr}`;\n  };\n  \n  // Simple implementation using console methods\n  return {\n    debug: (obj: Record<string, unknown>, msg?: string) => {\n      if (currentLevelValue <= 0) { // debug level\n        console.debug(formatLog('debug', obj, msg));\n      }\n    },\n    info: (obj: Record<string, unknown>, msg?: string) => {\n      if (currentLevelValue <= 1) { // info level\n        console.info(formatLog('info', obj, msg));\n      }\n    },\n    warn: (obj: Record<string, unknown>, msg?: string) => {\n      if (currentLevelValue <= 2) { // warn level\n        console.warn(formatLog('warn', obj, msg));\n      }\n    },\n    error: (obj: Record<string, unknown>, msg?: string) => {\n      if (currentLevelValue <= 3) { // error level\n        console.error(formatLog('error', obj, msg));\n      }\n    },\n    child: (bindings: object) => {\n      // For child loggers, we merge the bindings with the log objects\n      const childLogger = createLogger();\n      \n      // Override methods to include the bindings\n      return {\n        debug: (obj: Record<string, unknown>, msg?: string) => \n          childLogger.debug({ ...obj, ...bindings }, msg),\n        info: (obj: Record<string, unknown>, msg?: string) => \n          childLogger.info({ ...obj, ...bindings }, msg),\n        warn: (obj: Record<string, unknown>, msg?: string) => \n          childLogger.warn({ ...obj, ...bindings }, msg),\n        error: (obj: Record<string, unknown>, msg?: string) => \n          childLogger.error({ ...obj, ...bindings }, msg),\n        child: (nestedBindings: object) => \n          childLogger.child({ ...bindings, ...nestedBindings })\n      };\n    }\n  };\n};\n\n// Default logger instance\nexport const logger = createLogger();\n\n// Create a child logger with context\nexport function getContextLogger(context: string): Logger {\n  return logger.child({ context });\n}\n\n// Error handling utilities\nexport class AppError extends Error {\n  public readonly context: string;\n  public readonly code: string;\n  public readonly originalError?: Error;\n  public readonly data?: Record<string, unknown>;\n\n  constructor({\n    message,\n    context = 'general',\n    code = 'INTERNAL_ERROR',\n    originalError,\n    data,\n  }: {\n    message: string;\n    context?: string;\n    code?: string;\n    originalError?: Error;\n    data?: Record<string, unknown>;\n  }) {\n    super(message);\n    this.name = 'AppError';\n    this.context = context;\n    this.code = code;\n    this.originalError = originalError;\n    this.data = data;\n    // Preserve stack trace\n    Error.captureStackTrace(this, this.constructor);\n  }\n\n  // Logs this error with appropriate context and returns it\n  log() {\n    const contextLogger = getContextLogger(this.context);\n    const logObj = {\n      code: this.code,\n      error: this.message,\n      ...(this.originalError && { originalError: this.originalError.message }),\n      ...(this.data && { data: this.data }),\n    };\n\n    contextLogger.error(logObj, this.message);\n    return this;\n  }\n}\n\nexport default logger;","import { kv } from '@vercel/kv';\nimport { AppError, logger } from './logger';\n\n/**\n * Centralized KV Store Helper\n * \n * This provides standardized methods for interacting with Vercel KV storage,\n * ensuring consistent key formats, serialization/deserialization, and error handling.\n * \n * Also provides transaction support to ensure data consistency for complex operations.\n */\n\n// Create a logger instance for this module\nconst kvLogger = logger.child({ context: 'kv-store' });\n\n// Define constant prefixes for all entity types\nexport const KV_PREFIXES = {\n  MARKET: 'market',\n  MARKET_IDS: 'market_ids',\n  USER_MARKETS: 'user_markets',\n  MARKET_PARTICIPANTS: 'market_participants',\n  MARKET_CATEGORY: 'market_category',  // Index for markets by category\n  MARKET_STATUS: 'market_status',      // Index for markets by status\n  PREDICTION: 'prediction',\n  USER_PREDICTIONS: 'user_predictions',\n  MARKET_PREDICTIONS: 'market_predictions',\n  PREDICTION_NFT: 'prediction_nft',\n  USER_BALANCE: 'user_balance',\n  USER_STATS: 'user_stats',\n  LEADERBOARD: 'leaderboard',\n  LEADERBOARD_EARNINGS: 'leaderboard_earnings',\n  LEADERBOARD_ACCURACY: 'leaderboard_accuracy',\n  BUG_REPORT: 'bug_report',\n  BUG_REPORT_IDS: 'bug_report_ids',\n  USER_BUG_REPORTS: 'user_bug_reports',\n  // Transaction custody-related prefixes\n  CUSTODY_TRANSACTION: 'custody_transaction',\n  CUSTODY_TRANSACTION_IDS: 'custody_transaction_ids',\n  USER_TRANSACTIONS: 'user_transactions',\n  SIGNER_TRANSACTIONS: 'signer_transactions',\n  MARKET_TRANSACTIONS: 'market_transactions',\n  CUSTODY_NFT_RECEIPT: 'custody_nft_receipt',\n  // Claim reward transaction prefixes\n  CLAIM_REWARD_TRANSACTION: 'claim_reward_transaction',\n  USER_CLAIM_REWARDS: 'user_claim_rewards'\n} as const;\n\n// Type safety for valid entity types\nexport type EntityType = keyof typeof KV_PREFIXES;\n\n/**\n * Get a formatted key for a specific entity\n */\nexport function getKey(entityType: EntityType, id?: string): string {\n  const prefix = KV_PREFIXES[entityType];\n\n  // Special handling for MARKET_IDS - it doesn't use a colon format\n  if (entityType === 'MARKET_IDS' && !id) {\n    return prefix;\n  }\n\n  return id ? `${prefix}:${id}` : prefix;\n}\n\n/**\n * Store an entity in KV\n */\nexport async function storeEntity<T>(entityType: EntityType, id: string, data: T): Promise<T> {\n  try {\n    const key = getKey(entityType, id);\n    await kv.set(key, JSON.stringify(data));\n    return data;\n  } catch (error) {\n    throw new AppError({\n      message: `Failed to store ${entityType} with ID ${id}`,\n      context: 'kv-store',\n      code: 'KV_STORE_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { entityType, id, operation: 'store' }\n    }).log();\n  }\n}\n\n/**\n * Get an entity from KV - with backward compatibility\n */\nexport async function getEntity<T>(entityType: EntityType, id: string): Promise<T | null> {\n  try {\n    // Try with new key format\n    const key = getKey(entityType, id);\n    let data = await kv.get<string>(key);\n\n    // If not found and it's a MARKET, try the old plural format (markets:id)\n    if (!data && entityType === 'MARKET') {\n      data = await kv.get<string>(`markets:${id}`);\n    }\n\n    if (!data) {\n      // Not an error, just not found\n      kvLogger.debug({ entityType, id }, `Entity not found: ${entityType}:${id}`);\n      return null;\n    }\n\n    // If data is already in object format (newer KV might handle JSON automatically)\n    if (typeof data !== 'string') {\n      return data as unknown as T;\n    }\n\n    // Parse JSON string\n    try {\n      return JSON.parse(data) as T;\n    } catch (e) {\n      throw new AppError({\n        message: `Error parsing JSON for ${entityType} with ID ${id}`,\n        context: 'kv-store',\n        code: 'KV_JSON_PARSE_ERROR',\n        originalError: e instanceof Error ? e : new Error(String(e)),\n        data: { entityType, id, operation: 'parse' }\n      }).log();\n    }\n  } catch (error) {\n    // Only throw AppError if it's not already one\n    if (error instanceof AppError) {\n      throw error;\n    }\n\n    throw new AppError({\n      message: `Failed to retrieve ${entityType} with ID ${id}`,\n      context: 'kv-store',\n      code: 'KV_RETRIEVE_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { entityType, id, operation: 'get' }\n    }).log();\n  }\n}\n\n/**\n * Delete an entity from KV\n */\nexport async function deleteEntity(entityType: EntityType, id: string): Promise<boolean> {\n  try {\n    const key = getKey(entityType, id);\n    await kv.del(key);\n\n    // If it's a MARKET, also try to delete the legacy format\n    if (entityType === 'MARKET') {\n      await kv.del(`markets:${id}`);\n    }\n\n    return true;\n  } catch (error) {\n    // Log error but don't throw - deletion errors are often non-critical\n    new AppError({\n      message: `Failed to delete ${entityType} with ID ${id}`,\n      context: 'kv-store',\n      code: 'KV_DELETE_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { entityType, id, operation: 'delete' }\n    }).log();\n\n    return false;\n  }\n}\n\n/**\n * Add an ID to a set - with backward compatibility\n */\nexport async function addToSet(setType: EntityType, id: string, memberId: string): Promise<boolean> {\n  try {\n    const key = getKey(setType, id);\n    await kv.sadd(key, memberId);\n\n    // If it's MARKET_IDS, also add to the old format for backward compatibility\n    if (setType === 'MARKET_IDS') {\n      await kv.sadd('market_ids', memberId);\n    }\n\n    return true;\n  } catch (error) {\n    new AppError({\n      message: `Failed to add member ${memberId} to set ${setType}:${id}`,\n      context: 'kv-store',\n      code: 'KV_SET_ADD_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { setType, id, memberId, operation: 'sadd' }\n    }).log();\n\n    return false;\n  }\n}\n\n/**\n * Remove an ID from a set\n */\nexport async function removeFromSet(setType: EntityType, id: string, memberId: string): Promise<boolean> {\n  try {\n    const key = getKey(setType, id);\n    await kv.srem(key, memberId);\n\n    // If it's MARKET_IDS, also remove from the old format for backward compatibility\n    if (setType === 'MARKET_IDS') {\n      await kv.srem('market_ids', memberId);\n    }\n\n    return true;\n  } catch (error) {\n    new AppError({\n      message: `Failed to remove member ${memberId} from set ${setType}:${id}`,\n      context: 'kv-store',\n      code: 'KV_SET_REMOVE_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { setType, id, memberId, operation: 'srem' }\n    }).log();\n\n    return false;\n  }\n}\n\n/**\n * Get all members of a set - with backward compatibility\n */\nexport async function getSetMembers(setType: EntityType, id: string): Promise<string[]> {\n  try {\n    const key = getKey(setType, id);\n    let members = await kv.smembers(key) as string[];\n\n    // For backward compatibility with market_ids\n    if (setType === 'MARKET_IDS' && members.length === 0) {\n      const legacyMembers = await kv.smembers('market_ids') as string[];\n      if (legacyMembers.length > 0) {\n        // Migrate the data to the new format\n        for (const marketId of legacyMembers) {\n          await addToSet('MARKET_IDS', '', marketId);\n        }\n        members = legacyMembers;\n      }\n    }\n\n    return members;\n  } catch (error) {\n    new AppError({\n      message: `Failed to get members from set ${setType}:${id}`,\n      context: 'kv-store',\n      code: 'KV_SET_MEMBERS_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { setType, id, operation: 'smembers' }\n    }).log();\n\n    return [];\n  }\n}\n\n/**\n * Check if a member is in a set\n */\nexport async function isSetMember(setType: EntityType, id: string, memberId: string): Promise<boolean> {\n  try {\n    const key = getKey(setType, id);\n    const result = await kv.sismember(key, memberId);\n    return !!result;\n  } catch (error) {\n    console.error(`Error checking set membership for ${setType} with ID ${id}:`, error);\n    return false;\n  }\n}\n\n/**\n * Add a member to a sorted set with score\n */\nexport async function addToSortedSet(setType: EntityType, memberId: string, score: number): Promise<boolean> {\n  try {\n    const key = getKey(setType);\n    await kv.zadd(key, { score, member: memberId });\n    return true;\n  } catch (error) {\n    console.error(`Error adding to sorted set ${setType}:`, error);\n    return false;\n  }\n}\n\n/**\n * Get top members from a sorted set\n */\nexport async function getTopFromSortedSet(setType: EntityType, limit: number = 10, reverse: boolean = true): Promise<string[]> {\n  try {\n    const key = getKey(setType);\n    return await kv.zrange(key, 0, limit - 1, { rev: reverse }) as string[];\n  } catch (error) {\n    console.error(`Error getting top members from sorted set ${setType}:`, error);\n    return [];\n  }\n}\n\n/**\n * Get scores for specific members from a sorted set\n * Returns a map of memberId -> score\n */\nexport async function getScoresFromSortedSet(setType: EntityType, memberIds: string[]): Promise<Record<string, number>> {\n  try {\n    const key = getKey(setType);\n    const result: Record<string, number> = {};\n\n    // Process members in batches if there are many\n    const batchSize = 50;\n    for (let i = 0; i < memberIds.length; i += batchSize) {\n      const batch = memberIds.slice(i, i + batchSize);\n\n      // Get scores for this batch\n      const batchScores = await Promise.all(\n        batch.map(async (memberId) => {\n          const score = await kv.zscore(key, memberId);\n          return { memberId, score: score ? Number(score) : null };\n        })\n      );\n\n      // Add scores to result map\n      batchScores.forEach(({ memberId, score }) => {\n        if (score !== null) {\n          result[memberId] = score;\n        }\n      });\n    }\n\n    return result;\n  } catch (error) {\n    console.error(`Error getting scores from sorted set ${setType}:`, error);\n    return {};\n  }\n}\n\n/**\n * Get all keys matching a pattern\n */\nexport async function getKeys(pattern: string): Promise<string[]> {\n  try {\n    return await kv.keys(pattern) as string[];\n  } catch (error) {\n    console.error(`Error getting keys with pattern ${pattern}:`, error);\n    return [];\n  }\n}\n\n/**\n * Check if a key exists\n */\nexport async function keyExists(entityType: EntityType, id: string): Promise<boolean> {\n  try {\n    const key = getKey(entityType, id);\n    const result = await kv.exists(key);\n    return result === 1;\n  } catch (error) {\n    console.error(`Error checking if key exists for ${entityType} with ID ${id}:`, error);\n    return false;\n  }\n}\n\n/**\n * Debug function to get information about KV store\n */\nexport async function getDebugInfo(): Promise<Record<string, unknown>> {\n  try {\n    const allKeys = await kv.keys('*');\n    const patterns = [\n      'market:*',\n      'markets:*',\n      'market_ids',\n      'prediction:*',\n      'predictions:*',\n      'user_predictions:*',\n      'market_predictions:*',\n      'prediction_nft:*',\n      'prediction_nfts:*'\n    ];\n\n    const result: Record<string, unknown> = {\n      totalKeys: allKeys.length,\n      keysByPattern: {} as Record<string, { count: number; sample: string[] }>\n    };\n\n    const keysByPattern = result.keysByPattern as Record<string, { count: number; sample: string[] }>;\n\n    for (const pattern of patterns) {\n      const keys = await kv.keys(pattern);\n      keysByPattern[pattern] = {\n        count: keys.length,\n        sample: keys.slice(0, 5) as string[]\n      };\n    }\n\n    return result;\n  } catch (error) {\n    console.error('Error getting debug info:', error);\n    return { error: String(error) };\n  }\n}\n\n/**\n * Transaction interface for atomic operations\n */\nexport interface KvTransaction {\n  operations: Array<{\n    type: 'entity' | 'set' | 'sortedSet';\n    entityType: EntityType;\n    id: string;\n    data?: unknown;\n  }>;\n  addEntity<T>(entityType: EntityType, id: string, data: T): Promise<void>;\n  addToSetInTransaction(setType: EntityType, id: string, memberId: string): Promise<void>;\n  addToSortedSetInTransaction(setType: EntityType, memberId: string, score: number): Promise<void>;\n  execute(): Promise<boolean>;\n}\n\n/**\n * Start a Redis transaction for atomic operations\n * @returns A transaction object with methods that queue commands to be executed atomically\n */\nexport async function startTransaction(): Promise<KvTransaction> {\n  try {\n    // @vercel/kv supports Redis transactions via the multi() method\n    const transaction = kv.multi();\n\n    // Track operations for potential rollback planning\n    const operations: Array<{\n      type: 'entity' | 'set' | 'sortedSet';\n      entityType: EntityType;\n      id: string;\n      data?: unknown;\n    }> = [];\n\n    const txObject: KvTransaction = {\n      operations,\n\n      // Add entity to transaction\n      async addEntity<T>(entityType: EntityType, id: string, data: T): Promise<void> {\n        const key = getKey(entityType, id);\n        transaction.set(key, JSON.stringify(data));\n        operations.push({ type: 'entity', entityType, id, data });\n      },\n\n      // Add to set in transaction\n      async addToSetInTransaction(setType: EntityType, id: string, memberId: string): Promise<void> {\n        const key = getKey(setType, id);\n        transaction.sadd(key, memberId);\n        operations.push({ type: 'set', entityType: setType, id: memberId });\n\n        // Handle backward compatibility if needed\n        if (setType === 'MARKET_IDS') {\n          transaction.sadd('market_ids', memberId);\n        }\n      },\n\n      // Add to sorted set in transaction\n      async addToSortedSetInTransaction(setType: EntityType, memberId: string, score: number): Promise<void> {\n        const key = getKey(setType);\n        transaction.zadd(key, { score, member: memberId });\n        operations.push({ type: 'sortedSet', entityType: setType, id: memberId, data: score });\n      },\n\n      // Execute all queued commands atomically\n      async execute(): Promise<boolean> {\n        try {\n          kvLogger.debug(\n            { operationCount: operations.length },\n            `Executing transaction with ${operations.length} operations`\n          );\n\n          await transaction.exec();\n          return true;\n        } catch (error) {\n          const appError = new AppError({\n            message: 'Transaction execution failed',\n            context: 'kv-store',\n            code: 'TRANSACTION_FAILED',\n            originalError: error instanceof Error ? error : new Error(String(error)),\n            data: { operationCount: operations.length }\n          });\n\n          appError.log();\n\n          // Note: Redis transactions are atomic - they either all succeed or all fail\n          // No manual rollback is needed as failed transactions don't apply any changes\n\n          return false;\n        }\n      }\n    };\n\n    return txObject;\n  } catch (error) {\n    throw new AppError({\n      message: 'Failed to start transaction',\n      context: 'kv-store',\n      code: 'TRANSACTION_START_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error))\n    }).log();\n  }\n}","/**\n * Utility functions for OP Predict\n */\n\n// Admin user IDs\nexport const ADMIN_USER_IDS = [\n  'user_2tjVcbojjJk2bkQd856eNE1Ax0S', // rozar\n  'user_2tkBcBEVGanm3LHkg6XK7j91DRj', // kraken\n];\n\n// Check if a user is an admin\nexport function isAdmin(userId: string): boolean {\n  return ADMIN_USER_IDS.includes(userId);\n}\n\n/**\n * Generates a UUID using the Web Crypto API which is available in both\n * Node.js and edge runtime environments. This replaces the Node.js-specific\n * crypto.randomUUID() function.\n * \n * @returns A UUID v4 string\n */\nexport function generateUUID(): string {\n  // Use crypto.randomUUID() from Web Crypto API if available (modern browsers and Node.js 16+)\n  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n    return crypto.randomUUID();\n  }\n\n  // Fallback implementation for environments where crypto.randomUUID() is not available\n  // Based on the RFC4122 specification for UUID v4\n  const getRandomBytes = (n: number): Uint8Array => {\n    const bytes = new Uint8Array(n);\n    if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n      crypto.getRandomValues(bytes);\n    } else {\n      // Final fallback for extremely unlikely case - not cryptographically secure\n      for (let i = 0; i < n; i++) {\n        bytes[i] = Math.floor(Math.random() * 256);\n      }\n    }\n    return bytes;\n  };\n\n  const randomBytes = getRandomBytes(16);\n\n  // Set version (4) and variant bits\n  // Use non-null assertion as we know index 6 and 8 exist in our 16-byte array\n  randomBytes[6] = (randomBytes[6]! & 0x0f) | 0x40; // version 4\n  randomBytes[8] = (randomBytes[8]! & 0x3f) | 0x80; // variant 10\n\n  // Convert to hex string with proper formatting\n  let hex = '';\n  for (let i = 0; i < 16; i++) {\n    // We know all indexes exist in our 16-byte array\n    hex += randomBytes[i]!.toString(16).padStart(2, '0');\n    if (i === 3 || i === 5 || i === 7 || i === 9) {\n      hex += '-';\n    }\n  }\n\n  return hex;\n}\n\n/**\n * Calculate outcome percentages based on staked amounts with fallback to votes\n * @param outcomes Market outcomes\n * @returns Outcomes with percentages and a flag indicating if vote-based fallback was used\n */\nexport function calculateOutcomePercentages(outcomes: { id: number; name: string; amount?: number; votes?: number }[]) {\n  // Calculate total amount staked for percentage\n  const totalAmount = outcomes.reduce((sum, outcome) => sum + (outcome.amount || 0), 0);\n  const useFallbackVotes = totalAmount === 0;\n\n  // If no amount data is available, fall back to votes\n  const totalVotes = useFallbackVotes\n    ? outcomes.reduce((sum, outcome) => sum + (outcome.votes || 0), 0)\n    : 0;\n\n  // Update percentages\n  const outcomesWithPercentages = outcomes.map(outcome => ({\n    ...outcome,\n    percentage: useFallbackVotes\n      ? (totalVotes > 0 ? Math.round(((outcome.votes || 0) / totalVotes) * 100) : 0)\n      : (totalAmount > 0 ? Math.round(((outcome.amount || 0) / totalAmount) * 100) : 0)\n  }));\n\n  return {\n    outcomesWithPercentages,\n    useFallbackVotes\n  };\n}\n\n/**\n * Safely get the base URL of the application without causing SSR issues\n * with window access\n */\nexport function getBaseUrl(): string {\n  // Check for environment variable first\n  if (process.env.NEXT_PUBLIC_APP_URL) {\n    return process.env.NEXT_PUBLIC_APP_URL;\n  }\n\n  // Then check if window is available (client-side only)\n  if (typeof window !== 'undefined') {\n    // In development, use window.location.origin\n    if (process.env.NODE_ENV === 'development') {\n      return window.location.origin;\n    }\n  }\n\n  // Default fallback for SSR and production without env var\n  return 'https://oppredict.com';\n}\n\n// Market query and search utilities\n\nexport type MarketStatus = 'active' | 'resolved' | 'cancelled' | 'closed' | 'all';\nexport type MarketType = 'binary' | 'multiple' | 'all';\nexport type SortField = 'createdAt' | 'endDate' | 'poolAmount' | 'participants';\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface MarketQueryOptions {\n  status?: MarketStatus;\n  category?: string;\n  type?: MarketType;\n  search?: string;\n  creatorId?: string;\n  limit?: number;\n  offset?: number;\n  cursor?: string;\n  sortBy?: SortField;\n  sortDirection?: SortDirection;\n  resolvedOutcomeId?: number;\n  resolvedAt?: string;\n  resolvedBy?: string;\n  adminFee?: number;\n  remainingPot?: number;\n  totalWinningAmount?: number;\n}\n\nexport interface PaginatedResult<T> {\n  items: T[];\n  total: number;\n  hasMore: boolean;\n  nextCursor?: string;\n}\n\n/**\n * Simple text search for markets\n * Searches for terms in name and description\n */\nexport function searchMarketText(market: any, searchText: string): boolean {\n  if (!searchText) return true;\n\n  const text = `${market.name} ${market.description}`.toLowerCase();\n  const terms = searchText.toLowerCase().split(/\\s+/).filter(Boolean);\n\n  return terms.every(term => text.includes(term));\n}\n\n/**\n * Filter markets by multiple criteria\n */\nexport function filterMarkets(markets: any[], options: MarketQueryOptions = {}): any[] {\n  return markets.filter(market => {\n    console.log(options.status, market.status)\n    // Status filter\n    if (options.status && options.status !== 'all' && market.status !== options.status) {\n      return false;\n    }\n\n    // Category filter\n    if (options.category && market.category !== options.category) {\n      return false;\n    }\n\n    // Type filter\n    if (options.type && options.type !== 'all' && market.type !== options.type) {\n      return false;\n    }\n\n    // Creator filter\n    if (options.creatorId && market.createdBy !== options.creatorId) {\n      return false;\n    }\n\n    // Text search\n    if (options.search && !searchMarketText(market, options.search)) {\n      return false;\n    }\n\n    return true;\n  });\n}\n\n/**\n * Sort markets by specified field and direction\n */\nexport function sortMarkets(markets: any[], sortBy: SortField = 'createdAt', sortDirection: SortDirection = 'desc'): any[] {\n  return [...markets].sort((a, b) => {\n    let comparison = 0;\n\n    // Handle different field types\n    if (sortBy === 'createdAt' || sortBy === 'endDate') {\n      const dateA = new Date(a[sortBy] || 0).getTime();\n      const dateB = new Date(b[sortBy] || 0).getTime();\n      comparison = dateA - dateB;\n    } else {\n      // Numeric fields\n      const valA = a[sortBy] || 0;\n      const valB = b[sortBy] || 0;\n      comparison = valA - valB;\n    }\n\n    // Apply sort direction\n    return sortDirection === 'asc' ? comparison : -comparison;\n  });\n}\n\n/**\n * Apply pagination to results\n */\nexport function paginateResults<T>(items: T[], options: { limit?: number; offset?: number }): PaginatedResult<T> {\n  const limit = options.limit || 20;\n  const offset = options.offset || 0;\n  const paginatedItems = items.slice(offset, offset + limit);\n\n  return {\n    items: paginatedItems,\n    total: items.length,\n    hasMore: offset + paginatedItems.length < items.length,\n    nextCursor: offset + paginatedItems.length < items.length\n      ? `${offset + limit}`\n      : undefined\n  };\n}","/**\n * Prediction Contract Store: Direct interface to the Clarity smart contract\n * \n * This module provides function wrappers for interacting with the\n * prediction market contract. It abstracts the complexity of making direct\n * contract calls and provides a cleaner interface for the rest of the application.\n * \n * Includes both read-only functions and functions for state-changing operations.\n * \n * Uses a robust client implementation with:\n * - Multiple API endpoint fallbacks\n * - API key rotation\n * - Automatic retries\n * - Request batching\n */\n\nimport { logger } from './logger';\nimport { AppError } from './logger';\nimport { STACKS_MAINNET, StacksNetwork } from '@stacks/network';\nimport { createClient, Client } from \"@stacks/blockchain-api-client\";\nimport { paths } from \"@stacks/blockchain-api-client/lib/generated/schema\";\n\n// Import the types and functions we need for contract calls\nimport {\n  makeContractCall,\n  broadcastTransaction,\n  uintCV,\n  stringAsciiCV,\n  tupleCV,\n  listCV,\n  noneCV,\n  someCV,\n  bufferCV,\n  ClarityType,\n  ClarityValue,\n  OptionalCV,\n  ResponseCV,\n  BooleanCV,\n  BufferCV,\n  StringAsciiCV,\n  UIntCV,\n  ListCV,\n  TupleCV,\n  cvToValue,\n  hexToCV,\n  cvToHex,\n  PostConditionMode,\n  TxBroadcastResult,\n  Cl,\n} from '@stacks/transactions';\n\n/**\n * API endpoints for Stacks blockchain\n * Multiple endpoints for redundancy and load balancing\n */\nconst API_ENDPOINTS = [\n  \"https://api.hiro.so/\",\n  \"https://api.mainnet.hiro.so/\",\n  \"https://stacks-node-api.mainnet.stacks.co/\",\n];\n\n// Default retry settings\nconst DEFAULT_RETRY_COUNT = 3;\nconst DEFAULT_RETRY_DELAY = 1000; // ms\n\n// Contract configuration - consistent with other stores\nconst contractConfig = {\n  contractAddress: process.env.PREDICTION_CONTRACT_ADDRESS || 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS',\n  contractName: process.env.PREDICTION_CONTRACT_NAME || 'blaze-welsh-predictions-v1',\n  network: STACKS_MAINNET,\n  privateKey: process.env.MARKET_CREATOR_PRIVATE_KEY || '',\n  apiKey: process.env.HIRO_API_KEY || '',\n  apiKeys: process.env.HIRO_API_KEYS ? process.env.HIRO_API_KEYS.split(',') : [],\n  apiKeyRotation: process.env.API_KEY_ROTATION || 'loop', // 'loop' or 'random'\n  retryCount: parseInt(process.env.API_RETRY_COUNT || '3', 10),\n  retryDelay: parseInt(process.env.API_RETRY_DELAY || '1000', 10),\n};\n\n// Create a logger instance for this module\nconst contractLogger = logger.child({ context: 'prediction-contract-store' });\n\n// Initialize API clients with API key rotation\nconst stacksClients: Client<paths, `${string}/${string}`>[] = [];\nlet currentClientIndex = 0;\nlet currentKeyIndex = 0;\n\n// Track metadata cache to avoid redundant calls\ninterface MetadataCache {\n  marketInfo: Map<string, { data: PredictionMarketInfo | null, timestamp: number }>;\n  receiptInfo: Map<number, { data: PredictionReceiptInfo | null, timestamp: number }>;\n  rewardQuote: Map<number, { data: PredictionRewardQuote | null, timestamp: number }>;\n  receiptOwner: Map<number, { data: string | null, timestamp: number }>;\n}\n\n// Default cache expiration time in milliseconds (15 seconds)\nconst CACHE_EXPIRATION = 15 * 1000;\n\nconst metadataCache: MetadataCache = {\n  marketInfo: new Map(),\n  receiptInfo: new Map(),\n  rewardQuote: new Map(),\n  receiptOwner: new Map()\n};\n\n/**\n * Check if cached data is still valid (not expired)\n * @param timestamp The timestamp when the data was cached\n * @returns Boolean indicating if the cache is still valid\n */\nconst isCacheValid = (timestamp: number): boolean => {\n  return Date.now() - timestamp < CACHE_EXPIRATION;\n};\n\n/**\n * Helper function to validate a broadcast result is successful\n * @param result The broadcast result to validate\n * @returns True if the transaction appears successful, false otherwise\n */\nconst isBroadcastSuccessful = (result: any): boolean => {\n  // Check for essential properties\n  if (!result.txid) {\n    return false;\n  }\n\n  // Check for error indicators in the response\n  if (result.error || result.reason) {\n    return false;\n  }\n\n  // For Stacks, check tx_status if available\n  if (result.tx_status && result.tx_status !== 'success' && result.tx_status !== 'pending') {\n    return false;\n  }\n\n  return true;\n};\n\n/**\n * Helper function to broadcast a transaction with automatic fee adjustment\n * @param transaction The transaction to broadcast\n * @param makeContractCallOptions Options to recreate the transaction with adjusted fee\n * @param logContext Context information for logging\n * @returns The broadcast result\n */\nconst broadcastWithFeeAdjustment = async (\n  transaction: any,\n  makeContractCallOptions: any,\n  logContext: Record<string, any> = {}\n): Promise<TxBroadcastResult> => {\n  try {\n    // First attempt with the provided fee\n    const result: any = await broadcastTransaction({ transaction });\n\n    // Check if the result indicates success\n    if (!isBroadcastSuccessful(result)) {\n      // If we have a txid but there's an error, log it for debugging\n      if (result.txid && (result.error || result.reason)) {\n        contractLogger.warn({\n          ...logContext,\n          txid: result.txid,\n          error: result.error,\n          reason: result.reason,\n          status: result.tx_status\n        }, 'Transaction broadcast returned a txid but has error indicators');\n      }\n\n      throw new AppError({\n        message: `Transaction broadcast failed: ${result.reason || result.error || 'Unknown error'}`,\n        context: 'prediction-contract-store',\n        code: 'BROADCAST_ERROR',\n        data: {\n          result, ...logContext,\n          error: result.error,\n          reason: result.reason,\n        }\n      })\n    }\n\n    return result;\n  } catch (error: any) {\n    // Check for fee too low error\n    if (error.data.result.reason === 'FeeTooLow' && error.data.result.reason_data) {\n      const actualFee = error.data.result.reason_data.actual || 0;\n      const expectedFee = error.data.result.reason_data.expected || 0;\n      const feePadding = 10; // Add a little extra to be safe\n\n      contractLogger.warn({\n        ...logContext,\n        error: 'Fee too low',\n        txid: error.txid,\n        actualFee,\n        expectedFee,\n        newFee: expectedFee + feePadding\n      }, 'Transaction rejected due to fee too low, retrying with adjusted fee');\n\n      // Create a new transaction with the suggested fee (plus padding)\n      const adjustedOptions = {\n        ...makeContractCallOptions,\n        fee: expectedFee + feePadding\n      };\n\n      const newTransaction = await makeContractCall(adjustedOptions);\n\n      // Try broadcasting again with the new fee\n      const retryResult: any = await broadcastTransaction({ transaction: newTransaction });\n\n      // Validate the retry result\n      if (!isBroadcastSuccessful(retryResult)) {\n        throw new AppError({\n          message: `Retry transaction broadcast failed: ${retryResult.error || retryResult.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'RETRY_BROADCAST_ERROR',\n          data: { retryResult, adjustedFee: expectedFee + feePadding, ...logContext }\n        }).log();\n      }\n\n      return retryResult;\n    }\n\n    // Re-throw other errors\n    throw error;\n  }\n};\n\n/**\n * Initialize API clients\n */\nconst initClients = () => {\n  if (stacksClients.length > 0) return; // Already initialized\n\n  for (const endpoint of API_ENDPOINTS) {\n    const client = createClient({ baseUrl: endpoint });\n\n    // Add API key handling middleware\n    client.use({\n      onRequest({ request }) {\n        const apiKeys = contractConfig.apiKeys.length\n          ? contractConfig.apiKeys\n          : contractConfig.apiKey ? [contractConfig.apiKey] : [];\n\n        if (!apiKeys.length) return;\n\n        // Get next API key based on rotation strategy\n        const rotationStrategy = contractConfig.apiKeyRotation;\n        let key: string;\n\n        if (rotationStrategy === \"random\") {\n          const randomIndex = Math.floor(Math.random() * apiKeys.length);\n          key = apiKeys[randomIndex]!;\n        } else {\n          // Default loop strategy\n          key = apiKeys[currentKeyIndex]!;\n          currentKeyIndex = (currentKeyIndex + 1) % apiKeys.length;\n        }\n        request.headers.set(\"x-api-key\", key);\n      },\n    });\n\n    stacksClients.push(client);\n  }\n\n  contractLogger.info({\n    endpointCount: API_ENDPOINTS.length,\n    apiKeyCount: contractConfig.apiKeys.length + (contractConfig.apiKey ? 1 : 0)\n  }, 'Initialized Stacks API clients');\n};\n\n/**\n * Get the next client with rotation\n */\nconst getNextClient = (): Client<paths, `${string}/${string}`> => {\n  // Initialize clients on first use\n  if (stacksClients.length === 0) {\n    initClients();\n  }\n\n  const client = stacksClients[currentClientIndex]!;\n  currentClientIndex = (currentClientIndex + 1) % stacksClients.length;\n  return client;\n};\n\n/**\n * Helper function to fetch transaction status using client with API key rotation\n */\nconst getTransactionStatus = async (txid: string): Promise<any> => {\n  try {\n    const client = getNextClient();\n\n    contractLogger.debug({ txid }, 'Getting transaction status');\n\n    try {\n      const response = await client.GET(\n        \"/extended/v1/tx/{tx_id}\",\n        { params: { path: { tx_id: txid } } }\n      );\n\n      return response.data;\n    } catch (error: any) {\n      // Handle 404 specially - might just be pending\n      if (error.status === 404) {\n        return { status: 'not_found' };\n      }\n      throw error;\n    }\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n    contractLogger.error({ txid, error: errorMessage }, 'Error getting transaction status');\n\n    throw new AppError({\n      message: `Failed to get transaction status for ${txid}`,\n      context: 'prediction-contract-store',\n      code: 'TX_STATUS_ERROR',\n      originalError: error instanceof Error ? error : new Error(String(error)),\n      data: { txid }\n    }).log();\n  }\n};\n\n/**\n * Call a read-only contract function using client with API key rotation\n */\nconst enhancedReadOnlyCall = async <T = any>(\n  contractAddress: string,\n  contractName: string,\n  functionName: string,\n  functionArgs: ClarityValue[] = [],\n  senderAddress?: string\n): Promise<T> => {\n  const retryCount = contractConfig.retryCount;\n  const retryDelay = contractConfig.retryDelay;\n  let lastError: any;\n\n  for (let attempt = 0; attempt < retryCount; attempt++) {\n    try {\n      // Get client with API key rotation handled by middleware\n      const client = getNextClient();\n\n      contractLogger.debug({\n        contractId: `${contractAddress}.${contractName}`,\n        function: functionName,\n        attempt: attempt + 1\n      }, 'Calling read-only function');\n\n      // Convert function arguments to hex strings for API\n      const args = functionArgs.map(arg => cvToHex(arg));\n\n      // Make the contract call via API client\n      const response = await client.POST(\n        `/v2/contracts/call-read/${contractAddress}/${contractName}/${functionName}` as any,\n        {\n          body: {\n            sender: senderAddress || contractAddress,\n            arguments: args\n          }\n        }\n      );\n\n      if (!response?.data?.result) {\n        throw new Error(`No result from contract call ${functionName}`);\n      }\n\n      // Convert the hex result back to a JS object\n      const result = cvToValue(hexToCV(response.data.result)) as T;\n      return result\n\n    } catch (error) {\n      lastError = error;\n\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.warn({\n        contractId: `${contractAddress}.${contractName}`,\n        function: functionName,\n        attempt: attempt + 1,\n        maxAttempts: retryCount,\n        error: errorMessage\n      }, 'Read-only function call failed, retrying');\n\n      // Last attempt failed, wait before retrying with exponential backoff\n      if (attempt < retryCount - 1) {\n        await new Promise(resolve => setTimeout(resolve, retryDelay * Math.pow(2, attempt)));\n      }\n    }\n  }\n\n  // All attempts failed\n  const errorMessage = lastError instanceof Error ? lastError.message : String(lastError);\n  contractLogger.error({\n    contractId: `${contractAddress}.${contractName}`,\n    function: functionName,\n    attempts: retryCount,\n    error: errorMessage\n  }, 'All read-only function call attempts failed');\n\n  throw new AppError({\n    message: `Failed to call read-only function ${functionName} after ${retryCount} attempts`,\n    context: 'prediction-contract-store',\n    code: 'READ_ONLY_CALL_FAILED',\n    originalError: lastError instanceof Error ? lastError : new Error(errorMessage),\n    data: { contractAddress, contractName, functionName }\n  }).log();\n};\n\n/**\n * Helper interface for market structure in the contract\n */\nexport interface PredictionMarketInfo {\n  creator: string;\n  name: string;\n  description: string;\n  'outcome-names': string[];\n  'outcome-pools': number[];\n  'total-pool': number;\n  'is-open': boolean;\n  'is-resolved': boolean;\n  'winning-outcome': number;\n  resolver?: string;\n  'creation-time': number;\n  'resolution-time': number;\n}\n\n/**\n * Helper interface for prediction receipt information\n */\nexport interface PredictionReceiptInfo {\n  'market-id': string;\n  'outcome-id': number;\n  amount: number;\n  predictor?: string;\n}\n\n/**\n * Interface for prediction reward quote\n */\nexport interface PredictionRewardQuote {\n  dx: string; // market id\n  dy: number; // reward amount\n  dk: number; // receipt id\n}\n\n/**\n * Interface for market creation result\n */\nexport interface MarketCreationResult {\n  marketId: string;\n  creator: string;\n  creationTime: number;\n}\n\n/**\n * Interface for market resolution request\n */\nexport interface MarketResolutionRequest {\n  marketId: string;\n  winningOutcomeId: number;\n}\n\n/**\n * Interface for prediction transaction result\n */\nexport interface PredictionTransactionResult {\n  dx: string; // market id\n  dy: number; // pool amount\n  dk: number; // receipt id\n}\n\n/**\n * Interface for signed transaction parameters\n */\nexport interface SignedTransactionParams {\n  signature: string; // hex string of signature buffer\n  nonce: number;\n}\n\n/**\n * Interface for batch prediction operation\n */\nexport interface BatchPredictionOperation {\n  signet: SignedTransactionParams;\n  marketId: string;\n  outcomeId: number;\n  amount: number;\n}\n\n/**\n * Interface for batch claim reward operation\n */\nexport interface BatchClaimOperation {\n  signet: SignedTransactionParams;\n  receiptId: number;\n}\n\n/**\n * Prediction contract store with functions to query and interact with the contract\n */\nexport const predictionContractStore = {\n  /**\n   * Utility functions for managing the metadata cache\n   */\n  cache: {\n    /**\n     * Clear all metadata caches\n     */\n    clearAll(): void {\n      metadataCache.marketInfo.clear();\n      metadataCache.receiptInfo.clear();\n      metadataCache.rewardQuote.clear();\n      metadataCache.receiptOwner.clear();\n      contractLogger.info({ message: 'Cleared all metadata caches' });\n    },\n\n    /**\n     * Clear market info cache for a specific market\n     * @param marketId The ID of the market to clear from cache\n     */\n    clearMarketInfo(marketId: string): void {\n      metadataCache.marketInfo.delete(marketId);\n      contractLogger.debug({ marketId }, 'Cleared market info from cache');\n    },\n\n    /**\n     * Clear receipt info cache for a specific receipt\n     * @param receiptId The ID of the receipt to clear from cache\n     */\n    clearReceiptInfo(receiptId: number): void {\n      metadataCache.receiptInfo.delete(receiptId);\n      metadataCache.receiptOwner.delete(receiptId);\n      metadataCache.rewardQuote.delete(receiptId);\n      contractLogger.debug({ receiptId }, 'Cleared receipt data from cache');\n    },\n\n    /**\n     * Get cache statistics\n     * @returns Object with cache counts\n     */\n    getStats(): {\n      marketInfoCount: number;\n      receiptInfoCount: number;\n      rewardQuoteCount: number;\n      receiptOwnerCount: number;\n      cacheExpirationMs: number;\n    } {\n      return {\n        marketInfoCount: metadataCache.marketInfo.size,\n        receiptInfoCount: metadataCache.receiptInfo.size,\n        rewardQuoteCount: metadataCache.rewardQuote.size,\n        receiptOwnerCount: metadataCache.receiptOwner.size,\n        cacheExpirationMs: CACHE_EXPIRATION\n      };\n    }\n  },\n  /**\n   * Check if a receipt ID exists on the blockchain by checking if it has an owner\n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns True if the receipt exists and has an owner, false otherwise\n   */\n  async doesReceiptExist(receiptId: number, skipCache: boolean = false): Promise<boolean> {\n    try {\n      // We can leverage the getReceiptOwner method which is already cache-aware\n      const owner = await this.getReceiptOwner(receiptId, skipCache);\n      return owner !== null;\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error checking if receipt exists');\n\n      // Return false in case of error, assume it doesn't exist\n      return false;\n    }\n  },\n\n  /**\n   * Get the owner of a receipt from the contract\n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns The principal address of the owner, or null if not found or error\n   */\n  async getReceiptOwner(receiptId: number, skipCache: boolean = false): Promise<string | null> {\n    try {\n      // Check cache first if not skipping cache\n      if (!skipCache) {\n        const cached = metadataCache.receiptOwner.get(receiptId);\n        if (cached && isCacheValid(cached.timestamp)) {\n          contractLogger.debug({ receiptId, fromCache: true }, 'Got receipt owner from cache');\n          return cached.data;\n        }\n      }\n\n      contractLogger.debug({ receiptId }, 'Getting receipt owner from chain');\n\n      const result = await enhancedReadOnlyCall(\n        contractConfig.contractAddress,\n        contractConfig.contractName,\n        'get-owner',\n        [uintCV(receiptId)]\n      );\n\n      // If we get a successful response with an owner, return the owner\n      let owner: string | null = null;\n      if (result && result.value && result.value.type !== 'none') {\n        owner = result.value.value;\n        contractLogger.debug({ receiptId, owner }, 'Found receipt owner');\n      } else {\n        contractLogger.debug({ receiptId }, 'No owner found for receipt');\n      }\n\n      // Update cache with the result\n      metadataCache.receiptOwner.set(receiptId, {\n        data: owner,\n        timestamp: Date.now()\n      });\n\n      return owner;\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error getting receipt owner');\n\n      return null;\n    }\n  },\n\n  /**\n   * Get information about a specific market from the contract\n   * @param marketId The ID of the market to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns Market information or null if not found or error\n   */\n  async getMarketInfo(marketId: string, skipCache: boolean = false): Promise<PredictionMarketInfo | null> {\n    try {\n      // Check cache first if not skipping cache\n      if (!skipCache) {\n        const cached = metadataCache.marketInfo.get(marketId);\n        if (cached && isCacheValid(cached.timestamp)) {\n          contractLogger.debug({ marketId, fromCache: true }, 'Got market info from cache');\n          return cached.data;\n        }\n      }\n\n      contractLogger.debug({ marketId }, 'Getting market info from chain');\n\n      const result = await enhancedReadOnlyCall(\n        contractConfig.contractAddress,\n        contractConfig.contractName,\n        'get-market-info',\n        [stringAsciiCV(marketId)]\n      );\n\n      // If we get a successful response, parse the market info\n      let marketInfo: PredictionMarketInfo | null = null;\n      if (result) {\n        marketInfo = {\n          creator: result.value.creator.value,\n          name: result.value.name.value,\n          description: result.value.description.value,\n          'outcome-names': result.value['outcome-names'].value,\n          'outcome-pools': result.value['outcome-pools'].value,\n          'total-pool': Number(result.value['total-pool'].value),\n          'is-open': result.value['is-open'].value,\n          'is-resolved': result.value['is-resolved'].value,\n          'winning-outcome': Number(result.value['winning-outcome'].value),\n          resolver: result.value.resolver.value,\n          'creation-time': result.value['creation-time'].value,\n          'resolution-time': result.value['resolution-time'].value\n        } as PredictionMarketInfo;\n\n        contractLogger.debug({\n          marketId,\n          name: marketInfo.name,\n          isResolved: marketInfo['is-resolved']\n        }, 'Found market info');\n      } else {\n        contractLogger.debug({ marketId }, 'Market not found on chain');\n      }\n\n      // Update cache with the result\n      metadataCache.marketInfo.set(marketId, {\n        data: marketInfo,\n        timestamp: Date.now()\n      });\n\n      return marketInfo;\n    } catch (error) {\n      contractLogger.error({\n        marketId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error getting market info');\n\n      return null;\n    }\n  },\n\n  /**\n   * Get information about a specific prediction receipt from the contract\n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns Receipt information or null if not found or error\n   */\n  async getReceiptInfo(receiptId: number, skipCache: boolean = false): Promise<PredictionReceiptInfo | null> {\n    try {\n      // Check cache first if not skipping cache\n      if (!skipCache) {\n        const cached = metadataCache.receiptInfo.get(receiptId);\n        if (cached && isCacheValid(cached.timestamp)) {\n          contractLogger.debug({ receiptId, fromCache: true }, 'Got receipt info from cache');\n          return cached.data;\n        }\n      }\n\n      contractLogger.debug({ receiptId }, 'Getting receipt info from chain');\n\n      const result = await enhancedReadOnlyCall(\n        contractConfig.contractAddress,\n        contractConfig.contractName,\n        'get-receipt-info',\n        [uintCV(receiptId)]\n      );\n\n      // If we get a successful response, parse the receipt info\n      let receiptInfo: PredictionReceiptInfo | null = null;\n      if (result.success) {\n        receiptInfo = {\n          'market-id': result.value['market-id'].value,\n          'outcome-id': result.value['outcome-id'].value,\n          amount: result.value.amount.value,\n          predictor: result.value.predictor.value\n        } as PredictionReceiptInfo;\n\n        contractLogger.debug({\n          receiptId,\n          marketId: receiptInfo['market-id'],\n          outcomeId: receiptInfo['outcome-id'],\n          predictor: receiptInfo.predictor\n        }, 'Found receipt info');\n      } else {\n        contractLogger.debug({ receiptId }, 'Receipt not found on chain');\n      }\n\n      // Update cache with the result\n      metadataCache.receiptInfo.set(receiptId, {\n        data: receiptInfo,\n        timestamp: Date.now()\n      });\n\n      return receiptInfo;\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error getting receipt info');\n\n      return null;\n    }\n  },\n\n  /**\n   * Check if a prediction is eligible for reward based on the resolved market\n   * This calls the quote-reward function to see if there's any reward available\n   * \n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns Object with reward info or null if not found or error\n   */\n  async getRewardQuote(receiptId: number, skipCache: boolean = false): Promise<PredictionRewardQuote | null> {\n    try {\n      // Check cache first if not skipping cache\n      if (!skipCache) {\n        const cached = metadataCache.rewardQuote.get(receiptId);\n        if (cached && isCacheValid(cached.timestamp)) {\n          contractLogger.debug({ receiptId, fromCache: true }, 'Got reward quote from cache');\n          return cached.data;\n        }\n      }\n\n      contractLogger.debug({ receiptId }, 'Getting reward quote from chain');\n\n      const result = await enhancedReadOnlyCall(\n        contractConfig.contractAddress,\n        contractConfig.contractName,\n        'quote-reward',\n        [uintCV(receiptId)]\n      );\n\n      // If we get a successful response, parse the reward quote\n      let quote: PredictionRewardQuote | null = null;\n      if (result) {\n        quote = {\n          dx: result.value.dx.value,\n          dy: Number(result.value.dy.value),\n          dk: Number(result.value.dk.value)\n        } as PredictionRewardQuote;\n\n        contractLogger.debug({\n          receiptId,\n          marketId: quote.dx,\n          reward: quote.dy\n        }, 'Got reward quote');\n      } else {\n        contractLogger.debug({ receiptId }, 'Failed to get reward quote');\n      }\n\n      // Update cache with the result\n      metadataCache.rewardQuote.set(receiptId, {\n        data: quote,\n        timestamp: Date.now()\n      });\n\n      return quote;\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error getting reward quote');\n\n      return null;\n    }\n  },\n\n  /**\n   * Check if a prediction has won in a resolved market\n   * \n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns Boolean indicating if the prediction is a winner (with reward > 0)\n   */\n  async isPredictionWinner(receiptId: number, skipCache: boolean = false): Promise<boolean> {\n    try {\n      // Get the reward quote to see if there's a payout\n      const quote = await this.getRewardQuote(receiptId, skipCache);\n\n      // If there's a reward and it's greater than 0, it's a winner\n      if (quote && quote.dy > 0) {\n        contractLogger.debug({\n          receiptId,\n          reward: quote.dy\n        }, 'Prediction is a winner');\n        return true;\n      }\n\n      contractLogger.debug({ receiptId }, 'Prediction is not a winner');\n      return false;\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error checking if prediction is a winner');\n\n      return false;\n    }\n  },\n\n  /**\n   * Get the status of a prediction based on market resolution and outcome\n   * This combines multiple contract calls to determine the full status\n   * \n   * @param receiptId The ID of the receipt to check\n   * @param skipCache Whether to skip the cache and force a fresh lookup\n   * @returns 'unresolved' | 'won' | 'lost' | 'redeemed' | null (if error or not found)\n   */\n  async getPredictionStatus(receiptId: number, skipCache: boolean = false): Promise<'unresolved' | 'won' | 'lost' | 'redeemed' | null> {\n    try {\n      contractLogger.debug({ receiptId, skipCache }, 'Determining prediction status from chain');\n\n      // First check if the receipt exists (has an owner)\n      const owner = await this.getReceiptOwner(receiptId, skipCache);\n\n      // If no owner, it's been redeemed (NFT burned) or doesn't exist\n      if (!owner) {\n        // Get receipt info to check if it's just not found or was redeemed\n        const receiptInfo = await this.getReceiptInfo(receiptId, skipCache);\n\n        if (receiptInfo) {\n          contractLogger.debug({ receiptId }, 'Prediction has been redeemed (NFT burned)');\n          return 'redeemed';\n        } else {\n          contractLogger.debug({ receiptId }, 'Prediction not found on chain');\n          return null;\n        }\n      }\n\n      // If we have an owner, get the receipt info\n      const receiptInfo = await this.getReceiptInfo(receiptId, skipCache);\n      if (!receiptInfo) {\n        contractLogger.debug({ receiptId }, 'Receipt info not found even though owner exists');\n        return null;\n      }\n\n      // Get the market info to check if it's resolved\n      const marketInfo = await this.getMarketInfo(receiptInfo['market-id'], skipCache);\n      if (!marketInfo) {\n        contractLogger.debug({ receiptId, marketId: receiptInfo['market-id'] }, 'Market not found');\n        return null;\n      }\n\n      // If market isn't resolved, prediction is unresolved\n      if (!marketInfo['is-resolved']) {\n        contractLogger.debug({ receiptId, marketId: receiptInfo['market-id'] }, 'Market not resolved, prediction is unresolved');\n        return 'unresolved';\n      }\n\n      // Market is resolved, check if prediction is a winner\n      const isWinner = await this.isPredictionWinner(receiptId, skipCache);\n\n      if (isWinner) {\n        return 'won';\n      } else {\n        return 'lost';\n      }\n    } catch (error) {\n      contractLogger.error({\n        receiptId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error determining prediction status');\n\n      return null;\n    }\n  },\n\n  /**\n   * Get predictions that should be marked as won or lost based on market resolution\n   * This checks for receipts with 'pending' status in custody but that should be 'won' or 'lost'\n   * based on the blockchain state\n   * \n   * @param pendingIds List of receipt IDs that are currently 'pending' in custody\n   * @param skipCache Whether to skip the cache and force a fresh lookup for all predictions\n   * @returns Object containing arrays of 'won' and 'lost' IDs\n   */\n  async getStatusUpdatesForPendingPredictions(\n    pendingIds: number[],\n    skipCache: boolean = false\n  ): Promise<{\n    won: number[];\n    lost: number[];\n    errors: number[];\n  }> {\n    try {\n      contractLogger.info({\n        pendingCount: pendingIds.length,\n        skipCache\n      }, 'Getting status updates for pending predictions');\n\n      const results = {\n        won: [] as number[],\n        lost: [] as number[],\n        errors: [] as number[],\n      };\n\n      // Process in batches of 10 to avoid rate limits or timeouts\n      const batchSize = 10;\n\n      for (let i = 0; i < pendingIds.length; i += batchSize) {\n        const batch = pendingIds.slice(i, i + batchSize);\n\n        // Process each receipt in the batch concurrently\n        const statusPromises = batch.map(async (receiptId) => {\n          try {\n            // Use cached data by default for performance if not explicitly skipping cache\n            const status = await this.getPredictionStatus(receiptId, skipCache);\n            return { receiptId, status };\n          } catch (error) {\n            contractLogger.error({\n              receiptId,\n              error: error instanceof Error ? error.message : String(error)\n            }, 'Error getting prediction status in batch');\n\n            return { receiptId, status: 'error' };\n          }\n        });\n\n        // Wait for all statuses in this batch\n        const statuses = await Promise.all(statusPromises);\n\n        // Sort into appropriate categories\n        for (const { receiptId, status } of statuses) {\n          if (status === 'won') {\n            results.won.push(receiptId);\n          } else if (status === 'lost') {\n            results.lost.push(receiptId);\n          } else if (status === 'error' || status === null) {\n            results.errors.push(receiptId);\n          }\n          // Ignore 'pending' and 'redeemed' as they don't need updates\n        }\n\n        // Small delay between batches to avoid rate limiting\n        if (i + batchSize < pendingIds.length) {\n          await new Promise(resolve => setTimeout(resolve, 100));\n        }\n      }\n\n      contractLogger.info({\n        pendingCount: pendingIds.length,\n        wonCount: results.won.length,\n        lostCount: results.lost.length,\n        errorCount: results.errors.length,\n        cacheUsed: !skipCache\n      }, 'Finished getting status updates for pending predictions');\n\n      return results;\n    } catch (error) {\n      contractLogger.error({\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Error getting status updates for pending predictions');\n\n      throw new AppError({\n        message: 'Failed to get status updates for pending predictions',\n        context: 'prediction-contract-store',\n        code: 'STATUS_UPDATE_ERROR',\n        originalError: error instanceof Error ? error : new Error(String(error)),\n        data: { pendingCount: pendingIds.length, skipCache }\n      }).log();\n    }\n  },\n\n  /**\n   * Create a new prediction market on the blockchain\n   * @param marketId Unique identifier for the market (max 64 ASCII chars)\n   * @param name Name of the market (max 64 ASCII chars)\n   * @param description Description of the market (max 128 ASCII chars)\n   * @param outcomeNames List of possible outcome names (max 16 outcomes, each max 32 chars)\n   * @param senderKey Private key of the sender (defaults to contract config)\n   * @returns Result of the transaction with market creation details\n   */\n  async createMarket(\n    marketId: string,\n    name: string,\n    description: string,\n    outcomeNames: string[],\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    result?: MarketCreationResult;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({\n        marketId,\n        name,\n        descriptionLength: description.length,\n        outcomeCount: outcomeNames.length\n      }, 'Creating new prediction market on-chain');\n\n      // Validate input\n      if (!marketId || !name || !description || !outcomeNames.length) {\n        throw new AppError({\n          message: 'Invalid market data',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_DATA',\n          data: { marketId, name, descriptionLength: description.length, outcomeCount: outcomeNames.length }\n        }).log();\n      }\n\n      // Validate string lengths according to contract constraints\n      if (marketId.length > 64) {\n        throw new AppError({\n          message: 'Market ID exceeds maximum length of 64 ASCII characters',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_ID_LENGTH',\n          data: { marketId, length: marketId.length }\n        }).log();\n      }\n\n      if (name.length > 64) {\n        throw new AppError({\n          message: 'Market name exceeds maximum length of 64 ASCII characters',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_NAME_LENGTH',\n          data: { name, length: name.length }\n        }).log();\n      }\n\n      if (description.length > 128) {\n        throw new AppError({\n          message: 'Market description exceeds maximum length of 128 ASCII characters',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_DESCRIPTION_LENGTH',\n          data: { descriptionLength: description.length }\n        }).log();\n      }\n\n      if (outcomeNames.length > 16) {\n        throw new AppError({\n          message: 'Too many outcomes, maximum is 16',\n          context: 'prediction-contract-store',\n          code: 'TOO_MANY_OUTCOMES',\n          data: { outcomeCount: outcomeNames.length }\n        }).log();\n      }\n\n      // Check if any outcome name is too long\n      const longOutcomes = outcomeNames.filter(name => name.length > 32);\n      if (longOutcomes.length > 0) {\n        throw new AppError({\n          message: 'One or more outcome names exceed maximum length of 32 ASCII characters',\n          context: 'prediction-contract-store',\n          code: 'INVALID_OUTCOME_NAME_LENGTH',\n          data: { longOutcomes: longOutcomes.map(name => ({ name, length: name.length })) }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'create-market',\n        functionArgs: [\n          stringAsciiCV(marketId),\n          stringAsciiCV(name),\n          stringAsciiCV(description),\n          listCV(outcomeNames.map(name => stringAsciiCV(name)))\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { marketId, name }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast market creation transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        marketId,\n        name\n      }, 'Successfully submitted market creation transaction');\n\n      // Clear the cache for this market ID if it exists\n      this.cache.clearMarketInfo(marketId);\n\n      return {\n        success: true,\n        txid: result.txid,\n        result: {\n          marketId,\n          creator: transaction.auth.spendingCondition.signer,\n          creationTime: Math.floor(Date.now() / 1000)\n        }\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        marketId,\n        error: errorMessage\n      }, 'Error creating market on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to create market: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Close a market (no more predictions allowed)\n   * @param marketId The ID of the market to close\n   * @param senderKey Private key of the sender (must be admin or deployer)\n   * @returns Result of the transaction\n   */\n  async closeMarket(\n    marketId: string,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({ marketId }, 'Closing market on-chain');\n\n      // Validate input\n      if (!marketId) {\n        throw new AppError({\n          message: 'Invalid market ID',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_ID',\n          data: { marketId }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'close-market',\n        functionArgs: [\n          stringAsciiCV(marketId)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { marketId, operation: 'closeMarket' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast market close transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        marketId\n      }, 'Successfully submitted market close transaction');\n\n      // Clear the cache for this market ID\n      this.cache.clearMarketInfo(marketId);\n\n      return {\n        success: true,\n        txid: result.txid\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        marketId,\n        error: errorMessage\n      }, 'Error closing market on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to close market: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Resolve a market by setting the winning outcome\n   * @param marketId The ID of the market to resolve\n   * @param winningOutcomeId The ID of the winning outcome\n   * @param senderKey Private key of the sender (must be admin or deployer)\n   * @returns Result of the transaction\n   */\n  async resolveMarket(\n    marketId: string,\n    winningOutcomeId: number,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({ marketId, winningOutcomeId }, 'Resolving market on-chain');\n\n      // Validate input\n      if (!marketId) {\n        throw new AppError({\n          message: 'Invalid market ID',\n          context: 'prediction-contract-store',\n          code: 'INVALID_MARKET_ID',\n          data: { marketId }\n        }).log();\n      }\n\n      if (winningOutcomeId < 0) {\n        throw new AppError({\n          message: 'Invalid winning outcome ID',\n          context: 'prediction-contract-store',\n          code: 'INVALID_OUTCOME_ID',\n          data: { winningOutcomeId }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'resolve-market',\n        functionArgs: [\n          stringAsciiCV(marketId),\n          uintCV(winningOutcomeId)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { marketId, winningOutcomeId, operation: 'resolveMarket' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast market resolution transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        marketId,\n        winningOutcomeId\n      }, 'Successfully submitted market resolution transaction');\n\n      // Clear the cache for this market ID since its state has changed\n      this.cache.clearMarketInfo(marketId);\n\n      return {\n        success: true,\n        txid: result.txid\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        marketId,\n        winningOutcomeId,\n        error: errorMessage\n      }, 'Error resolving market on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to resolve market: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Make a prediction on a market outcome (direct transaction)\n   * @param marketId The ID of the market\n   * @param outcomeId The ID of the outcome being predicted\n   * @param amount The amount to stake on this prediction\n   * @param senderKey Private key of the sender\n   * @returns Result of the transaction with prediction details\n   */\n  async makePrediction(\n    marketId: string,\n    outcomeId: number,\n    amount: number,\n    senderKey: string\n  ): Promise<{\n    success: boolean;\n    result?: PredictionTransactionResult;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({\n        marketId,\n        outcomeId,\n        amount\n      }, 'Making prediction on-chain');\n\n      // Validate input\n      if (!marketId || outcomeId < 0 || amount <= 0) {\n        throw new AppError({\n          message: 'Invalid prediction data',\n          context: 'prediction-contract-store',\n          code: 'INVALID_PREDICTION_DATA',\n          data: { marketId, outcomeId, amount }\n        }).log();\n      }\n\n      if (!senderKey) {\n        throw new AppError({\n          message: 'No private key provided for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'make-prediction',\n        functionArgs: [\n          stringAsciiCV(marketId),\n          uintCV(outcomeId),\n          uintCV(amount)\n        ],\n        senderKey: senderKey,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { marketId, outcomeId, amount, operation: 'makePrediction' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast prediction transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        marketId,\n        outcomeId,\n        amount\n      }, 'Successfully submitted prediction transaction');\n\n      // We don't know the receipt ID yet - it will be assigned by the contract\n      // The receipt ID should be retrieved by monitoring the transaction result\n      return {\n        success: true,\n        txid: result.txid,\n        result: {\n          dx: marketId,\n          dy: Number(amount),\n          dk: 0 // We don't know the actual receipt ID yet\n        }\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        marketId,\n        outcomeId,\n        amount,\n        error: errorMessage\n      }, 'Error making prediction on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to make prediction: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Make a prediction using a signed transaction\n   * @param signet Signature and nonce for the transaction\n   * @param marketId The ID of the market\n   * @param outcomeId The ID of the outcome being predicted\n   * @param amount The amount to stake on this prediction\n   * @param senderKey Private key for sending the transaction (admin key)\n   * @returns Result of the transaction with prediction details\n   */\n  async signedPredict(\n    signet: SignedTransactionParams,\n    marketId: string,\n    outcomeId: number,\n    amount: number,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    result?: PredictionTransactionResult;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({\n        marketId,\n        outcomeId,\n        amount,\n        nonce: signet.nonce\n      }, 'Making signed prediction on-chain');\n\n      // Validate input\n      if (!marketId || outcomeId < 0 || amount <= 0) {\n        throw new AppError({\n          message: 'Invalid prediction data',\n          context: 'prediction-contract-store',\n          code: 'INVALID_PREDICTION_DATA',\n          data: { marketId, outcomeId, amount }\n        }).log();\n      }\n\n      if (!signet.signature || signet.nonce === undefined) {\n        throw new AppError({\n          message: 'Invalid signet data',\n          context: 'prediction-contract-store',\n          code: 'INVALID_SIGNET',\n          data: { hasSignature: !!signet.signature, hasNonce: signet.nonce !== undefined }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'signed-predict',\n        functionArgs: [\n          tupleCV({\n            signature: bufferCV(Buffer.from(signet.signature, 'hex')),\n            nonce: uintCV(signet.nonce)\n          }),\n          stringAsciiCV(marketId),\n          uintCV(outcomeId),\n          uintCV(amount)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { marketId, outcomeId, amount, nonce: signet.nonce, operation: 'signedPredict' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast signed prediction transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        marketId,\n        outcomeId,\n        amount,\n        nonce: signet.nonce\n      }, 'Successfully submitted signed prediction transaction');\n\n      // The receipt ID should be the same as the nonce in signed transactions\n      return {\n        success: true,\n        txid: result.txid,\n        result: {\n          dx: marketId,\n          dy: Number(amount),\n          dk: signet.nonce\n        }\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        marketId,\n        outcomeId,\n        amount,\n        nonce: signet.nonce,\n        error: errorMessage\n      }, 'Error making signed prediction on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to make signed prediction: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Claim a reward for a winning prediction\n   * @param receiptId The ID of the winning prediction receipt\n   * @param senderKey Private key of the receipt owner\n   * @returns Result of the transaction with reward details\n   */\n  async claimReward(\n    receiptId: number,\n    senderKey: string\n  ): Promise<{\n    success: boolean;\n    result?: PredictionTransactionResult;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({ receiptId }, 'Claiming prediction reward on-chain');\n\n      // Validate input\n      if (receiptId <= 0) {\n        throw new AppError({\n          message: 'Invalid receipt ID',\n          context: 'prediction-contract-store',\n          code: 'INVALID_RECEIPT_ID',\n          data: { receiptId }\n        }).log();\n      }\n\n      if (!senderKey) {\n        throw new AppError({\n          message: 'No private key provided for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'claim-reward',\n        functionArgs: [\n          uintCV(receiptId)\n        ],\n        senderKey: senderKey,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { receiptId, operation: 'claimReward' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast claim reward transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        receiptId\n      }, 'Successfully submitted claim reward transaction');\n\n      // Clear the cache for this receipt ID since its state has changed\n      this.cache.clearReceiptInfo(receiptId);\n\n      return {\n        success: true,\n        txid: result.txid,\n        result: {\n          dx: \"\", // We don't know the market ID yet\n          dy: 0,  // We don't know the reward amount yet\n          dk: receiptId\n        }\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        receiptId,\n        error: errorMessage\n      }, 'Error claiming reward on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to claim reward: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Claim a reward using a signed transaction\n   * @param signet Signature and nonce for the transaction\n   * @param receiptId The ID of the winning prediction receipt\n   * @param senderKey Private key for sending the transaction (admin key)\n   * @returns Result of the transaction with reward details\n   */\n  async signedClaimReward(\n    signet: SignedTransactionParams,\n    receiptId: number,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    result?: PredictionTransactionResult;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({\n        receiptId,\n        nonce: signet.nonce\n      }, 'Claiming reward with signed transaction on-chain');\n\n      // Validate input\n      if (receiptId <= 0) {\n        throw new AppError({\n          message: 'Invalid receipt ID',\n          context: 'prediction-contract-store',\n          code: 'INVALID_RECEIPT_ID',\n          data: { receiptId }\n        }).log();\n      }\n\n      if (!signet.signature || signet.nonce === undefined) {\n        throw new AppError({\n          message: 'Invalid signet data',\n          context: 'prediction-contract-store',\n          code: 'INVALID_SIGNET',\n          data: { hasSignature: !!signet.signature, hasNonce: signet.nonce !== undefined }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'signed-claim-reward',\n        functionArgs: [\n          tupleCV({\n            signature: bufferCV(Buffer.from(signet.signature, 'hex')),\n            nonce: uintCV(signet.nonce)\n          }),\n          uintCV(receiptId)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { receiptId, nonce: signet.nonce, operation: 'signedClaimReward' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast signed claim reward transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        receiptId,\n        nonce: signet.nonce\n      }, 'Successfully submitted signed claim reward transaction');\n\n      // Clear the cache for this receipt ID since its state has changed\n      this.cache.clearReceiptInfo(receiptId);\n\n      return {\n        success: true,\n        txid: result.txid,\n        result: {\n          dx: \"\", // We don't know the market ID yet\n          dy: 0,  // We don't know the reward amount yet\n          dk: receiptId\n        }\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        receiptId,\n        nonce: signet.nonce,\n        error: errorMessage\n      }, 'Error claiming reward with signed transaction on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to claim reward with signed transaction: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Process a batch of prediction operations in a single transaction\n   * @param operations Array of prediction operations to execute\n   * @param senderKey Private key for sending the transaction (admin key)\n   * @returns Result of the batch operation\n   */\n  async batchPredict(\n    operations: BatchPredictionOperation[],\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    results?: boolean[];\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({\n        operationCount: operations.length\n      }, 'Processing batch predictions on-chain');\n\n      // Validate input\n      if (!operations.length) {\n        throw new AppError({\n          message: 'No operations provided for batch processing',\n          context: 'prediction-contract-store',\n          code: 'EMPTY_BATCH',\n          data: { operationCount: 0 }\n        }).log();\n      }\n\n      // Check maximum batch size (from contract constant)\n      const MAX_BATCH_SIZE = 200; // From contract\n      if (operations.length > MAX_BATCH_SIZE) {\n        throw new AppError({\n          message: `Batch size exceeds maximum of ${MAX_BATCH_SIZE} operations`,\n          context: 'prediction-contract-store',\n          code: 'BATCH_TOO_LARGE',\n          data: { operationCount: operations.length, maxSize: MAX_BATCH_SIZE }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Transform operations into contract format\n      const operationCVs = operations.map(op => {\n        return tupleCV({\n          signet: tupleCV({\n            signature: Cl.bufferFromHex(op.signet.signature),\n            nonce: uintCV(op.signet.nonce)\n          }),\n          \"market-id\": stringAsciiCV(op.marketId),\n          \"outcome-id\": uintCV(op.outcomeId),\n          amount: uintCV(op.amount)\n        });\n      });\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'batch-predict',\n        functionArgs: [\n          listCV(operationCVs)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        // Set fee proportional to batch size, with a higher base\n        fee: Math.min(100000, 1100 * operations.length)\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { operationCount: operations.length, operation: 'batchPredict' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast batch predict transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        operationCount: operations.length\n      }, 'Successfully submitted batch predict transaction');\n\n      // Clear market cache for all markets in the batch\n      // We use a Set to remove duplicates in case multiple predictions are for the same market\n      const uniqueMarketIds = new Set(operations.map(op => op.marketId));\n      uniqueMarketIds.forEach(marketId => {\n        this.cache.clearMarketInfo(marketId);\n      });\n\n      return {\n        success: true,\n        txid: result.txid,\n        // We don't know the actual results until the transaction is processed\n        results: Array(operations.length).fill(true)\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        operationCount: operations.length,\n        error: errorMessage\n      }, 'Error processing batch predictions on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to process batch predictions: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Process a batch of claim reward operations in a single transaction\n   * @param operations Array of claim reward operations to execute\n   * @param senderKey Private key for sending the transaction (admin key)\n   * @param waitForStatus Whether to wait for transaction status to be confirmed\n   * @returns Result of the batch operation\n   */\n  async batchClaimReward(\n    operations: BatchClaimOperation[],\n    senderKey?: string,\n    waitForStatus: boolean = false\n  ): Promise<{\n    success: boolean;\n    results?: boolean[];\n    txid?: string;\n    error?: string;\n    status?: string;\n  }> {\n    try {\n      contractLogger.info({\n        operationCount: operations.length\n      }, 'Processing batch claim rewards on-chain');\n\n      // Validate input\n      if (!operations.length) {\n        throw new AppError({\n          message: 'No operations provided for batch processing',\n          context: 'prediction-contract-store',\n          code: 'EMPTY_BATCH',\n          data: { operationCount: 0 }\n        }).log();\n      }\n\n      // Check maximum batch size (from contract constant)\n      const MAX_BATCH_SIZE = 200; // From contract\n      if (operations.length > MAX_BATCH_SIZE) {\n        throw new AppError({\n          message: `Batch size exceeds maximum of ${MAX_BATCH_SIZE} operations`,\n          context: 'prediction-contract-store',\n          code: 'BATCH_TOO_LARGE',\n          data: { operationCount: operations.length, maxSize: MAX_BATCH_SIZE }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Transform operations into contract format\n      const operationCVs = operations.map(op => {\n        return tupleCV({\n          signet: tupleCV({\n            signature: bufferCV(Buffer.from(op.signet.signature, 'hex')),\n            nonce: uintCV(op.signet.nonce)\n          }),\n          \"receipt-id\": uintCV(op.receiptId)\n        });\n      });\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'batch-claim-reward',\n        functionArgs: [\n          listCV(operationCVs)\n        ],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        // Set fee proportional to batch size, with a higher base\n        fee: Math.min(100000, 110 * operations.length)\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { operationCount: operations.length, operation: 'batchClaimReward' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast batch claim reward transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        operationCount: operations.length\n      }, 'Successfully submitted batch claim reward transaction');\n\n      // Clear cache for all receipt IDs in the batch\n      operations.forEach(op => {\n        this.cache.clearReceiptInfo(op.receiptId);\n      });\n\n      // If we want to wait for status, check the transaction with API keys\n      if (waitForStatus) {\n        try {\n          // Wait for the transaction to be confirmed - with a timeout\n          const txStatus = await getTransactionStatus(result.txid);\n\n          return {\n            success: true,\n            txid: result.txid,\n            status: txStatus.tx_status || txStatus.status,\n            results: Array(operations.length).fill(true)\n          };\n        } catch (error) {\n          // Transaction was broadcast but we couldn't get status\n          // This is not a failure, just return the txid\n          contractLogger.warn({\n            txid: result.txid,\n            error: error instanceof Error ? error.message : String(error)\n          }, 'Transaction submitted but status check failed');\n\n          return {\n            success: true,\n            txid: result.txid,\n            results: Array(operations.length).fill(true),\n            status: 'unknown'\n          };\n        }\n      }\n\n      return {\n        success: true,\n        txid: result.txid,\n        // We don't know the actual results until the transaction is processed\n        results: Array(operations.length).fill(true)\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        operationCount: operations.length,\n        error: errorMessage\n      }, 'Error processing batch claim rewards on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to process batch claim rewards: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Add an admin to the contract\n   * @param adminAddress The principal address to add as admin\n   * @param senderKey Private key of the contract deployer (required)\n   * @returns Result of the transaction\n   */\n  async addAdmin(\n    adminAddress: string,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({ adminAddress }, 'Adding admin on-chain');\n\n      // Validate input\n      if (!adminAddress) {\n        throw new AppError({\n          message: 'Invalid admin address',\n          context: 'prediction-contract-store',\n          code: 'INVALID_ADMIN_ADDRESS',\n          data: { adminAddress }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'add-admin',\n        functionArgs: [Cl.principal(adminAddress)],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500 // Starting with higher default fee\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { adminAddress, operation: 'addAdmin' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast add admin transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        adminAddress\n      }, 'Successfully submitted add admin transaction');\n\n      return {\n        success: true,\n        txid: result.txid\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        adminAddress,\n        error: errorMessage\n      }, 'Error adding admin on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to add admin: ${errorMessage}`\n      };\n    }\n  },\n\n  /**\n   * Remove an admin from the contract\n   * @param adminAddress The principal address to remove as admin\n   * @param senderKey Private key of the contract deployer (required)\n   * @returns Result of the transaction\n   */\n  async removeAdmin(\n    adminAddress: string,\n    senderKey?: string\n  ): Promise<{\n    success: boolean;\n    txid?: string;\n    error?: string;\n  }> {\n    try {\n      contractLogger.info({ adminAddress }, 'Removing admin on-chain');\n\n      // Validate input\n      if (!adminAddress) {\n        throw new AppError({\n          message: 'Invalid admin address',\n          context: 'prediction-contract-store',\n          code: 'INVALID_ADMIN_ADDRESS',\n          data: { adminAddress }\n        }).log();\n      }\n\n      // Use provided senderKey or fall back to config\n      const key = senderKey || contractConfig.privateKey;\n      if (!key) {\n        throw new AppError({\n          message: 'No private key available for transaction',\n          context: 'prediction-contract-store',\n          code: 'NO_PRIVATE_KEY'\n        }).log();\n      }\n\n      // Prepare contract call options\n      const contractCallOptions = {\n        contractAddress: contractConfig.contractAddress,\n        contractName: contractConfig.contractName,\n        functionName: 'remove-admin',\n        functionArgs: [Cl.address(adminAddress)],\n        senderKey: key,\n        validateWithAbi: true,\n        network: contractConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 500 // Starting with higher default fee\n      };\n\n      // Create the transaction\n      const transaction = await makeContractCall(contractCallOptions);\n\n      // Broadcast the transaction with fee adjustment if needed\n      const result: any = await broadcastWithFeeAdjustment(\n        transaction,\n        contractCallOptions,\n        { adminAddress, operation: 'removeAdmin' }\n      );\n\n      // Extra validation to catch any errors that might have been missed\n      if (!isBroadcastSuccessful(result)) {\n        throw new AppError({\n          message: `Failed to broadcast remove admin transaction: ${result.error || result.reason || 'Unknown error'}`,\n          context: 'prediction-contract-store',\n          code: 'BROADCAST_ERROR',\n          data: { result }\n        }).log();\n      }\n\n      contractLogger.info({\n        txid: result.txid,\n        adminAddress\n      }, 'Successfully submitted remove admin transaction');\n\n      return {\n        success: true,\n        txid: result.txid\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      contractLogger.error({\n        adminAddress,\n        error: errorMessage\n      }, 'Error removing admin on blockchain');\n\n      if (error instanceof AppError) {\n        return {\n          success: false,\n          error: error.message\n        };\n      }\n\n      return {\n        success: false,\n        error: `Failed to remove admin: ${errorMessage}`\n      };\n    }\n  }\n};","import * as kvStore from './kv-store';\nimport {\n  generateUUID,\n  MarketQueryOptions,\n  filterMarkets,\n  sortMarkets,\n  paginateResults,\n  PaginatedResult\n} from './utils';\nimport { AppError, logger } from './logger';\nimport {\n  makeContractCall,\n  broadcastTransaction,\n  stringAsciiCV,\n  listCV,\n  PostConditionMode,\n  TxBroadcastResult\n} from \"@stacks/transactions\";\nimport { STACKS_MAINNET } from '@stacks/network';\nimport { predictionContractStore, PredictionMarketInfo } from './prediction-contract-store';\n\n// Create a logger instance for this module\nconst marketLogger = logger.child({ context: 'market-store' });\n\n// On-chain market creation configuration\nconst onChainConfig = {\n  enabled: process.env.ENABLE_ONCHAIN_MARKETS === 'true',\n  privateKey: process.env.MARKET_CREATOR_PRIVATE_KEY || '',\n  network: STACKS_MAINNET,\n  contractAddress: process.env.PREDICTION_CONTRACT_ADDRESS || 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS',\n  contractName: process.env.PREDICTION_CONTRACT_NAME || 'blaze-welsh-predictions-v1',\n};\n\n// Auto close configuration\nconst autoCloseConfig = {\n  enabled: process.env.ENABLE_AUTO_CLOSE_MARKETS !== 'false', // Enabled by default\n  batchSize: Number(process.env.AUTO_CLOSE_BATCH_SIZE || '50'),\n  closeOnChain: process.env.AUTO_CLOSE_ON_CHAIN === 'true',\n};\n\nexport interface Market {\n  id: string;\n  type: 'binary' | 'multiple';\n  name: string;\n  description: string;\n  outcomes: { id: number; name: string; votes?: number; amount?: number }[];\n  createdBy: string;\n  category: string;\n  endDate: string;\n  imageUrl?: string;\n  createdAt: string;\n  participants: number;\n  poolAmount: number;\n  status: string;\n  resolvedOutcomeId?: number;\n  resolvedAt?: string;\n  resolvedBy?: string;\n  adminFee?: number;\n  remainingPot?: number;\n  totalWinningAmount?: number;\n}\n\n// Market store with Vercel KV\n// Interface for blockchain verification result\nexport interface MarketSyncResult {\n  marketId: string;\n  name: string;\n  status: 'already_synced' | 'updated' | 'error';\n  onChainData?: {\n    'is-open': boolean;\n    'is-resolved': boolean;\n    'winning-outcome'?: number;\n  };\n  localData?: {\n    status: string;\n    resolvedOutcomeId?: number;\n  };\n  error?: string;\n}\n\nexport const marketStore = {\n  // Get all markets\n  async getMarkets(options?: MarketQueryOptions): Promise<PaginatedResult<Market>> {\n    let marketIds: string[] = [];\n\n    // Use indexes when possible for more efficient retrieval\n    if (options?.category) {\n      // Get markets by category\n      marketIds = await kvStore.getSetMembers('MARKET_CATEGORY', options.category);\n    } else if (options?.status && options.status !== 'all') {\n      // Get markets by status\n      marketIds = await kvStore.getSetMembers('MARKET_STATUS', options.status);\n    } else {\n      // Get all market IDs\n      marketIds = await kvStore.getSetMembers('MARKET_IDS', '');\n    }\n\n    // If no markets found, return empty result\n    if (marketIds.length === 0) {\n      return {\n        items: [],\n        total: 0,\n        hasMore: false\n      };\n    }\n\n    // Get markets in parallel - limit the number if options are provided to avoid loading everything\n    const limit = options?.limit || 100;\n    const offset = options?.offset || (options?.cursor ? parseInt(options.cursor, 10) : 0);\n\n    // Apply sorting before fetching if we know the sort field is createdAt\n    // This allows us to fetch only what we need\n    let idsToFetch = marketIds;\n    if (options?.sortBy === 'createdAt') {\n      // We'll sort markets after fetching them\n      // For now, just take the slice we need based on offset/limit\n      idsToFetch = marketIds.slice(offset, offset + limit * 2); // Fetch extra items for filtering\n    }\n\n    // Get markets in parallel\n    const markets = await Promise.all(\n      idsToFetch.map(id => this.getMarket(id))\n    );\n\n    // Filter out any undefined markets (in case of data inconsistency)\n    const validMarkets = markets.filter(Boolean) as Market[];\n\n    if (validMarkets.length < idsToFetch.length) {\n      marketLogger.warn(\n        { expected: idsToFetch.length, found: validMarkets.length },\n        'Some markets could not be retrieved'\n      );\n    }\n\n    // Apply filtering, sorting, and pagination\n    let filteredMarkets = validMarkets;\n\n    // Apply filtering if options are provided\n    if (options) {\n      // Skip category and status filtering if we already used indexes\n      const filterOpts = {\n        ...options,\n        category: options.category && idsToFetch === marketIds ? options.category : undefined,\n        status: options.status && idsToFetch === marketIds ? options.status : undefined\n      };\n      console.log(filterOpts)\n\n      filteredMarkets = filterMarkets(validMarkets, filterOpts);\n\n      // Apply sorting\n      const sortedMarkets = sortMarkets(\n        filteredMarkets,\n        options.sortBy || 'createdAt',\n        options.sortDirection || 'desc'\n      );\n\n      // Apply pagination\n      return paginateResults(sortedMarkets, {\n        limit: options.limit,\n        offset: options.offset || (options.cursor ? parseInt(options.cursor, 10) : 0)\n      });\n    }\n\n    // Return all markets if no options provided\n    return {\n      items: validMarkets,\n      total: validMarkets.length,\n      hasMore: false\n    };\n  },\n\n  // Get a specific market by ID and verify its state with blockchain\n  async getMarket(id: string, options?: { verifyWithBlockchain?: boolean }) {\n    try {\n      const market = await kvStore.getEntity('MARKET', id) as Market;\n\n      // Return undefined if market not found in KV store\n      if (!market) {\n        return undefined;\n      }\n\n      // If verification with blockchain is requested, check on-chain state\n      if (options?.verifyWithBlockchain) {\n        try {\n          // Get the on-chain market information\n          const onChainMarket = await this.getMarketInfo(id);\n\n          // If market exists on-chain, verify and potentially update its state\n          if (onChainMarket) {\n            // Extract the blockchain state\n            const isOpenOnChain = onChainMarket['is-open'];\n            const isResolvedOnChain = (onChainMarket['is-resolved']);\n            const winningOutcomeOnChain = Number(onChainMarket['winning-outcome']);\n\n            // Create a copy of the market to update without modifying the original\n            const verifiedMarket = { ...market };\n\n            // Update status based on blockchain state\n            if (isResolvedOnChain && market.status !== 'resolved') {\n              marketLogger.info({\n                marketId: id,\n                localStatus: market.status,\n                blockchainStatus: 'resolved'\n              }, 'Local market status differs from blockchain state');\n\n              verifiedMarket.status = 'resolved';\n              verifiedMarket.resolvedOutcomeId = winningOutcomeOnChain;\n\n              // Only set these if they're not already set\n              if (!verifiedMarket.resolvedAt) {\n                verifiedMarket.resolvedAt = new Date().toISOString();\n              }\n\n              if (!verifiedMarket.resolvedBy) {\n                verifiedMarket.resolvedBy = 'blockchain-verification';\n              }\n            } else if (!isOpenOnChain && !isResolvedOnChain && market.status !== 'closed') {\n              marketLogger.info({\n                marketId: id,\n                localStatus: market.status,\n                blockchainStatus: 'closed'\n              }, 'Local market status differs from blockchain state');\n\n              verifiedMarket.status = 'closed';\n            } else if (isOpenOnChain && !isResolvedOnChain && market.status !== 'active') {\n              marketLogger.info({\n                marketId: id,\n                localStatus: market.status,\n                blockchainStatus: 'active'\n              }, 'Local market status differs from blockchain state');\n\n              verifiedMarket.status = 'active';\n            }\n\n            // If resolved, ensure the winning outcome ID matches\n            if (isResolvedOnChain &&\n              verifiedMarket.resolvedOutcomeId !== winningOutcomeOnChain) {\n              marketLogger.warn({\n                marketId: id,\n                localOutcome: verifiedMarket.resolvedOutcomeId,\n                blockchainOutcome: winningOutcomeOnChain\n              }, 'Local winning outcome differs from blockchain state');\n\n              verifiedMarket.resolvedOutcomeId = winningOutcomeOnChain;\n            }\n\n            // If the market was updated, save the changes to the KV store\n            if (JSON.stringify(market) !== JSON.stringify(verifiedMarket)) {\n              marketLogger.info({ marketId: id }, 'Updating market in KV store to match blockchain state');\n              await kvStore.storeEntity('MARKET', id, verifiedMarket);\n            }\n\n            return verifiedMarket;\n          }\n        } catch (verificationError) {\n          // Log the error but don't fail the market retrieval\n          marketLogger.error({\n            marketId: id,\n            error: verificationError instanceof Error\n              ? verificationError.message\n              : String(verificationError)\n          }, 'Error verifying market with blockchain');\n        }\n      }\n\n      return market;\n    } catch (error) {\n      if (error instanceof AppError) {\n        // Just rethrow AppErrors\n        throw error;\n      } else {\n        throw new AppError({\n          message: `Failed to retrieve market ${id}`,\n          context: 'market-store',\n          code: 'MARKET_GET_ERROR',\n          originalError: error instanceof Error ? error : new Error(String(error)),\n          data: { marketId: id }\n        }).log();\n      }\n    }\n  },\n\n  /**\n   * Get market information directly from the blockchain\n   * This calls the prediction contract store to get the on-chain market data\n   * @param id Market ID\n   * @returns Market information from blockchain or null if not found\n   */\n  async getMarketInfo(id: string): Promise<PredictionMarketInfo | null> {\n    try {\n      // Use the prediction contract store to get the market info from the blockchain\n      const marketInfo = await predictionContractStore.getMarketInfo(id);\n      return marketInfo;\n    } catch (error) {\n      marketLogger.error(\n        { marketId: id, error: error instanceof Error ? error.message : String(error) },\n        'Failed to get market info from blockchain'\n      );\n      return null;\n    }\n  },\n\n  /**\n   * Helper function to create a market on-chain\n   * @param marketId Unique ID for the market\n   * @param name Name of the market\n   * @param description Description of the market\n   * @param outcomes List of outcome names\n   * @returns Promise resolving to the broadcast transaction result\n   */\n  async createMarketOnChain(\n    marketId: string,\n    name: string,\n    description: string,\n    outcomes: { id: number; name: string; }[]\n  ): Promise<TxBroadcastResult | null> {\n    try {\n      // Skip if on-chain creation is disabled\n      if (!onChainConfig.enabled) {\n        marketLogger.info({ marketId }, 'On-chain market creation is disabled');\n        return null;\n      }\n\n      // Validate private key is available\n      if (!onChainConfig.privateKey) {\n        throw new Error('Private key is required for on-chain market creation');\n      }\n\n      // Extract just the outcome names for the contract call\n      const outcomeNames = outcomes.map(outcome => outcome.name);\n\n      // Prepare the contract call\n      const transaction = await makeContractCall({\n        contractAddress: onChainConfig.contractAddress,\n        contractName: onChainConfig.contractName,\n        functionName: 'create-market',\n        functionArgs: [\n          stringAsciiCV(marketId),\n          stringAsciiCV(name.substring(0, 64)), // Limit to 64 chars for Clarity string-ascii 64\n          stringAsciiCV(description.substring(0, 128)), // Limit to 128 chars for Clarity string-ascii 128\n          listCV(outcomeNames.map(name => stringAsciiCV(name.substring(0, 32)))) // Limit each name to 32 chars\n        ],\n        senderKey: onChainConfig.privateKey,\n        validateWithAbi: true,\n        network: onChainConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 1000, // Set appropriate fee\n      });\n\n      // Broadcast the transaction\n      const result = await broadcastTransaction({ transaction });\n\n      marketLogger.info({\n        marketId,\n        txId: result.txid || 'unknown',\n        successful: !!result.txid\n      }, 'On-chain market creation transaction broadcast');\n\n      return result;\n    } catch (error) {\n      marketLogger.error({\n        marketId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Failed to create market on-chain');\n\n      // We don't throw here - just log the error and return null\n      // This is to prevent the entire market creation from failing if on-chain creation fails\n      return null;\n    }\n  },\n\n  // Create a new market\n  async createMarket(\n    data: {\n      type: 'binary' | 'multiple';\n      name: string;\n      description: string;\n      outcomes: { id: number; name: string; }[];\n      createdBy: string;\n      category: string;\n      endDate: string;\n      imageUrl?: string;\n    }\n  ) {\n    try {\n      // Validate required fields\n      if (!data.name || !data.description || !data.outcomes || data.outcomes.length === 0) {\n        throw new AppError({\n          message: 'Missing required market data',\n          context: 'market-store',\n          code: 'MARKET_VALIDATION_ERROR',\n          data: {\n            hasName: !!data.name,\n            hasDescription: !!data.description,\n            outcomeCount: data.outcomes?.length || 0\n          }\n        }).log();\n      }\n\n      // Start a transaction for atomic operation\n      const tx = await kvStore.startTransaction();\n      const id = generateUUID();\n      const now = new Date().toISOString();\n\n      const market = {\n        id,\n        type: data.type,\n        name: data.name,\n        description: data.description,\n        outcomes: data.outcomes,\n        createdBy: data.createdBy,\n        category: data.category,\n        endDate: data.endDate,\n        imageUrl: data.imageUrl,\n        createdAt: now,\n        participants: 0,\n        poolAmount: 0,\n        status: 'active'\n      };\n\n      // Store market by ID\n      await tx.addEntity('MARKET', id, market);\n\n      // Add to market_ids set\n      await tx.addToSetInTransaction('MARKET_IDS', '', id);\n\n      // Add to user's markets set\n      if (data.createdBy) {\n        await tx.addToSetInTransaction('USER_MARKETS', data.createdBy, id);\n      }\n\n      // Add to category index\n      if (data.category) {\n        await tx.addToSetInTransaction('MARKET_CATEGORY', data.category, id);\n      }\n\n      // Add to status index\n      await tx.addToSetInTransaction('MARKET_STATUS', 'active', id);\n\n      // Execute the transaction\n      const success = await tx.execute();\n\n      if (!success) {\n        throw new AppError({\n          message: 'Failed to create market - transaction failed',\n          context: 'market-store',\n          code: 'MARKET_CREATE_TRANSACTION_ERROR',\n          data: { marketId: id }\n        }).log();\n      }\n\n      // Create the market on-chain asynchronously\n      // We don't await this call to prevent blocking the main flow\n      this.createMarketOnChain(id, data.name, data.description, data.outcomes)\n        .then(result => {\n          if (result?.txid) {\n            marketLogger.info({\n              marketId: id,\n              txId: result.txid\n            }, 'Market created on-chain successfully');\n          }\n        })\n        .catch(error => {\n          marketLogger.error({\n            marketId: id,\n            error: error instanceof Error ? error.message : String(error)\n          }, 'Error in on-chain market creation');\n        });\n\n      marketLogger.info({ marketId: id }, `Created new market: ${market.name}`);\n      return market;\n    } catch (error) {\n      if (error instanceof AppError) {\n        // Just rethrow AppErrors\n        throw error;\n      } else {\n        throw new AppError({\n          message: 'Failed to create market',\n          context: 'market-store',\n          code: 'MARKET_CREATE_ERROR',\n          originalError: error instanceof Error ? error : new Error(String(error)),\n          data: { marketName: data.name }\n        }).log();\n      }\n    }\n  },\n\n  /**\n   * Resolve a market on-chain with the winning outcome\n   * @param marketId Unique ID for the market\n   * @param winningOutcomeId The ID of the winning outcome\n   * @returns Promise resolving to the broadcast transaction result\n   */\n  async resolveMarketOnChain(\n    marketId: string,\n    winningOutcomeId: number\n  ): Promise<TxBroadcastResult | null> {\n    try {\n      // Skip if on-chain market interaction is disabled\n      if (!onChainConfig.enabled) {\n        marketLogger.info({ marketId }, 'On-chain market resolution is disabled');\n        return null;\n      }\n\n      // Validate private key is available\n      if (!onChainConfig.privateKey) {\n        throw new Error('Private key is required for on-chain market resolution');\n      }\n\n      // Import the needed CV constructor only when needed\n      const { uintCV } = await import('@stacks/transactions');\n\n      // Prepare the contract call\n      const transaction = await makeContractCall({\n        contractAddress: onChainConfig.contractAddress,\n        contractName: onChainConfig.contractName,\n        functionName: 'resolve-market',\n        functionArgs: [\n          stringAsciiCV(marketId),\n          uintCV(winningOutcomeId)\n        ],\n        senderKey: onChainConfig.privateKey,\n        validateWithAbi: true,\n        network: onChainConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 1000, // Set appropriate fee\n      });\n\n      // Broadcast the transaction\n      const result = await broadcastTransaction({ transaction });\n\n      marketLogger.info({\n        marketId,\n        txId: result.txid || 'unknown',\n        successful: !!result?.txid\n      }, 'On-chain market resolution transaction broadcast');\n\n      return result;\n    } catch (error) {\n      marketLogger.error({\n        marketId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Failed to resolve market on-chain');\n\n      // We don't throw here - just log the error and return null\n      return null;\n    }\n  },\n\n  // Update a market\n  async updateMarket(id: string, marketData: any) {\n    try {\n      const market: any = await this.getMarket(id);\n      if (!market) {\n        marketLogger.warn({ marketId: id }, `Cannot update non-existent market with ID ${id}`);\n        return undefined;\n      }\n\n      // Ensure we don't change critical fields like ID\n      const safeData = { ...marketData };\n      if (safeData.id && safeData.id !== id) {\n        delete safeData.id;\n        marketLogger.warn(\n          { marketId: id, attemptedId: marketData.id },\n          'Attempted to change market ID during update - ignoring'\n        );\n      }\n\n      const updatedMarket = { ...market, ...safeData };\n\n      // Start a transaction for atomic update\n      const tx = await kvStore.startTransaction();\n\n      // Store the updated market\n      await tx.addEntity('MARKET', id, updatedMarket);\n\n      // Update category index if category changed\n      if (marketData.category && marketData.category !== market.category) {\n        // Remove from old category\n        await kvStore.removeFromSet('MARKET_CATEGORY', market.category, id);\n\n        // Add to new category\n        await tx.addToSetInTransaction('MARKET_CATEGORY', marketData.category, id);\n      }\n\n      // Update status index if status changed\n      if (marketData.status && marketData.status !== market.status) {\n        // Remove from old status\n        await kvStore.removeFromSet('MARKET_STATUS', market.status, id);\n\n        // Add to new status\n        await tx.addToSetInTransaction('MARKET_STATUS', marketData.status, id);\n      }\n\n      // Execute transaction\n      await tx.execute();\n\n      // Check if this is a market resolution update (is_resolved changed to true)\n      if (marketData.is_resolved === true && marketData.winning_outcome !== undefined &&\n        (!market.is_resolved || market.is_resolved === false)) {\n\n        // Asynchronously resolve the market on-chain\n        this.resolveMarketOnChain(id, marketData.winning_outcome)\n          .then(result => {\n            if (result?.txid) {\n              marketLogger.info({\n                marketId: id,\n                txId: result.txid,\n                winningOutcome: marketData.winning_outcome\n              }, 'Market resolved on-chain successfully');\n            }\n          })\n          .catch(error => {\n            marketLogger.error({\n              marketId: id,\n              error: error instanceof Error ? error.message : String(error)\n            }, 'Error in on-chain market resolution');\n          });\n      }\n\n      marketLogger.debug(\n        { marketId: id },\n        `Updated market: ${market.name}`\n      );\n\n      return updatedMarket;\n    } catch (error) {\n      if (error instanceof AppError) {\n        // Just rethrow AppErrors\n        throw error;\n      } else {\n        throw new AppError({\n          message: `Failed to update market ${id}`,\n          context: 'market-store',\n          code: 'MARKET_UPDATE_ERROR',\n          originalError: error instanceof Error ? error : new Error(String(error)),\n          data: { marketId: id }\n        }).log();\n      }\n    }\n  },\n\n  // Delete a market\n  async deleteMarket(id: string): Promise<boolean> {\n    try {\n      // Get the market to know its category and status\n      const market = await this.getMarket(id) as Market | null;\n      if (!market) {\n        return false;\n      }\n\n      // Start a transaction for atomic deletion\n      await kvStore.startTransaction();\n\n      // Delete the market\n      await kvStore.deleteEntity('MARKET', id);\n\n      // Remove the market ID from the set of all market IDs\n      await kvStore.removeFromSet('MARKET_IDS', '', id);\n\n      // Remove from category index\n      if (market.category) {\n        await kvStore.removeFromSet('MARKET_CATEGORY', market.category, id);\n      }\n\n      // Remove from status index\n      if (market.status) {\n        await kvStore.removeFromSet('MARKET_STATUS', market.status, id);\n      }\n\n      // Remove from creator's markets\n      if (market.createdBy) {\n        await kvStore.removeFromSet('USER_MARKETS', market.createdBy, id);\n      }\n\n      return true;\n    } catch (error) {\n      console.error(`Error deleting market ${id}:`, error);\n      return false;\n    }\n  },\n\n  // Update market stats when a prediction is made\n  async updateMarketStats(marketId: string, outcomeId: number, amount: number, userId: string) {\n    const market: any = await this.getMarket(marketId);\n    if (!market) return undefined;\n\n    // Check if this user has already participated in this market\n    const userParticipated = await kvStore.isSetMember('MARKET_PARTICIPANTS', marketId, userId);\n\n    // Update the market stats - only increment participants if it's a new user\n    if (!userParticipated) {\n      market.participants = (market.participants || 0) + 1;\n      // Add user to the set of participants for this market\n      await kvStore.addToSet('MARKET_PARTICIPANTS', marketId, userId);\n    }\n\n    market.poolAmount = (market.poolAmount || 0) + amount;\n\n    // Update the outcome stats\n    const outcome = market.outcomes.find((o: any) => o.id === outcomeId);\n    if (outcome) {\n      outcome.votes = (outcome.votes || 0) + 1;\n      outcome.amount = (outcome.amount || 0) + amount;\n    }\n\n    // Save the updated market\n    return this.updateMarket(marketId, market);\n  },\n\n  // Get related markets based on category and similarity\n  async getRelatedMarkets(marketId: string, limit: number = 3) {\n    try {\n      const market: any = await this.getMarket(marketId);\n      if (!market) return [];\n\n      // Get all markets with filtering\n      const result = await this.getMarkets({\n        status: 'active',\n        limit: 50 // Get enough markets to find good related ones\n      });\n\n      const allMarkets = result.items;\n\n      // Filter out the current market\n      const candidates = allMarkets.filter((m: any) =>\n        m.id !== marketId &&\n        (\n          // Same category\n          m.category === market.category ||\n          // Or contains similar keywords in name/description\n          this.calculateSimilarity(m, market) > 0.3\n        )\n      );\n\n      // Sort by similarity score\n      const sortedMarkets = candidates.sort((a, b) =>\n        this.calculateSimilarity(b, market) - this.calculateSimilarity(a, market)\n      );\n\n      return sortedMarkets.slice(0, limit);\n    } catch (error) {\n      console.error('Error getting related markets:', error);\n      return [];\n    }\n  },\n\n  // Get markets by category\n  async getMarketsByCategory(category: string, options?: Omit<MarketQueryOptions, 'category'>): Promise<PaginatedResult<Market>> {\n    return this.getMarkets({\n      ...options,\n      category\n    });\n  },\n\n  // Search markets by text\n  async searchMarkets(searchText: string, options?: Omit<MarketQueryOptions, 'search'>): Promise<PaginatedResult<Market>> {\n    return this.getMarkets({\n      ...options,\n      search: searchText\n    });\n  },\n\n  // Get trending markets (highest participation or pool amount)\n  async getTrendingMarkets(limit: number = 10): Promise<Market[]> {\n    const result = await this.getMarkets({\n      status: 'active',\n      sortBy: 'poolAmount',\n      sortDirection: 'desc',\n      limit\n    });\n\n    return result.items;\n  },\n\n  // Calculate similarity score between two markets\n  calculateSimilarity(market1: any, market2: any): number {\n    const text1 = `${market1.name} ${market1.description}`.toLowerCase();\n    const text2 = `${market2.name} ${market2.description}`.toLowerCase();\n\n    // Get unique words\n    const words1 = new Set(text1.split(/\\W+/));\n    const words2 = new Set(text2.split(/\\W+/));\n\n    // Calculate intersection\n    const intersection = new Set(Array.from(words1).filter(x => words2.has(x)));\n\n    // Calculate Jaccard similarity\n    const union = new Set(Array.from(words1).concat(Array.from(words2)));\n    return intersection.size / union.size;\n  },\n\n  // Migration: Build indexes for existing markets\n  async buildMarketIndexes(): Promise<{ success: boolean; indexed: number }> {\n    try {\n      // Get all market IDs\n      const marketIds = await kvStore.getSetMembers('MARKET_IDS', '');\n\n      // Get all markets\n      const markets = await Promise.all(\n        marketIds.map(id => this.getMarket(id))\n      );\n\n      // Filter out any undefined markets\n      const validMarkets = markets.filter(Boolean) as Market[];\n\n      let indexedCount = 0;\n\n      // Process each market\n      for (const market of validMarkets) {\n        // Add to category index\n        if (market.category) {\n          await kvStore.addToSet('MARKET_CATEGORY', market.category, market.id);\n        }\n\n        // Add to status index\n        if (market.status) {\n          await kvStore.addToSet('MARKET_STATUS', market.status, market.id);\n        }\n\n        indexedCount++;\n      }\n\n      marketLogger.info(\n        { total: marketIds.length, indexed: indexedCount },\n        'Market indexes built successfully'\n      );\n\n      return { success: true, indexed: indexedCount };\n    } catch (error) {\n      marketLogger.error(\n        { error: error instanceof Error ? error.message : String(error) },\n        'Error building market indexes'\n      );\n      return { success: false, indexed: 0 };\n    }\n  },\n\n  /**\n   * Close a market on-chain\n   * @param marketId Unique ID for the market\n   * @returns Promise resolving to the broadcast transaction result\n   */\n  async closeMarketOnChain(\n    marketId: string\n  ): Promise<TxBroadcastResult | null> {\n    try {\n      // Skip if on-chain market interaction is disabled\n      if (!onChainConfig.enabled) {\n        marketLogger.info({ marketId }, 'On-chain market close is disabled');\n        return null;\n      }\n\n      // Validate private key is available\n      if (!onChainConfig.privateKey) {\n        throw new Error('Private key is required for on-chain market close');\n      }\n\n      // Prepare the contract call\n      const transaction = await makeContractCall({\n        contractAddress: onChainConfig.contractAddress,\n        contractName: onChainConfig.contractName,\n        functionName: 'close-market',\n        functionArgs: [\n          stringAsciiCV(marketId)\n        ],\n        senderKey: onChainConfig.privateKey,\n        validateWithAbi: true,\n        network: onChainConfig.network,\n        postConditionMode: PostConditionMode.Allow,\n        fee: 1000,\n      });\n\n      // Broadcast the transaction\n      const result = await broadcastTransaction({ transaction });\n\n      marketLogger.info({\n        marketId,\n        txId: result.txid || 'unknown',\n        successful: !!result.txid\n      }, 'On-chain market close transaction broadcast');\n\n      return result;\n    } catch (error) {\n      marketLogger.error({\n        marketId,\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Failed to close market on-chain');\n\n      // We don't throw here - just log the error and return null\n      return null;\n    }\n  },\n\n  /**\n   * Automatically close markets that have passed their end date\n   * This function is meant to be called by a cron job\n   * @returns Object with stats about markets that were closed\n   */\n  async autoCloseExpiredMarkets(): Promise<{\n    success: boolean;\n    processed: number;\n    closed: number;\n    errors: number;\n    onChainSucceeded?: number;\n    onChainFailed?: number;\n  }> {\n    try {\n      // Skip if auto-close is disabled\n      if (!autoCloseConfig.enabled) {\n        return { success: true, processed: 0, closed: 0, errors: 0 };\n      }\n\n      // Get active markets\n      const activeMarkets = await kvStore.getSetMembers('MARKET_STATUS', 'active');\n\n      // Initialize counters\n      let processed = 0;\n      let closed = 0;\n      let errors = 0;\n      let onChainSucceeded = 0;\n      let onChainFailed = 0;\n\n      // Current time for comparison\n      const now = new Date().toISOString();\n\n      // Process markets in batches\n      for (let i = 0; i < activeMarkets.length; i += autoCloseConfig.batchSize) {\n        const batch = activeMarkets.slice(i, i + autoCloseConfig.batchSize);\n\n        // Get market data in parallel\n        const markets = await Promise.all(\n          batch.map(id => this.getMarket(id))\n        );\n\n        // Filter for valid markets with expired end dates\n        const expiredMarkets = markets\n          .filter(Boolean)\n          .filter((market: any) => market.endDate < now && market.status === 'active') as Market[];\n\n        // Process each expired market\n        for (const market of expiredMarkets) {\n          processed++;\n\n          try {\n            // Update the market to closed\n            await this.updateMarket(market.id, {\n              status: 'closed',\n              is_open: false\n            });\n\n            closed++;\n\n            // Close on-chain if enabled\n            if (autoCloseConfig.closeOnChain) {\n              const onChainResult = await this.closeMarketOnChain(market.id);\n\n              if (onChainResult?.txid) {\n                onChainSucceeded++;\n\n                marketLogger.info({\n                  marketId: market.id,\n                  txId: onChainResult.txid\n                }, 'Market closed on-chain successfully');\n              } else {\n                onChainFailed++;\n\n                marketLogger.warn({\n                  marketId: market.id\n                }, 'Failed to close market on-chain');\n              }\n            }\n\n            marketLogger.info({\n              marketId: market.id,\n              name: market.name,\n              endDate: market.endDate\n            }, 'Automatically closed expired market');\n          } catch (error) {\n            errors++;\n            marketLogger.error({\n              marketId: market.id,\n              error: error instanceof Error ? error.message : String(error)\n            }, 'Error closing expired market');\n          }\n        }\n      }\n\n      // Log summary\n      marketLogger.info({\n        processed,\n        closed,\n        errors,\n        onChainSucceeded,\n        onChainFailed\n      }, 'Completed auto-close of expired markets');\n\n      return {\n        success: true,\n        processed,\n        closed,\n        errors,\n        onChainSucceeded,\n        onChainFailed\n      };\n    } catch (error) {\n      marketLogger.error({\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Failed to auto-close expired markets');\n\n      return { success: false, processed: 0, closed: 0, errors: 1 };\n    }\n  },\n\n  /**\n   * Synchronize market statuses with blockchain state\n   * This checks all markets against their on-chain state and updates them if they don't match\n   * @returns Results of the synchronization operation\n   */\n  async syncMarketsWithBlockchain(): Promise<{\n    success: boolean;\n    processed: number;\n    updated: number;\n    errors: number;\n    syncResults: MarketSyncResult[];\n  }> {\n    try {\n      marketLogger.info({}, 'Starting market synchronization with blockchain');\n\n      // Get all markets\n      const marketsResult = await this.getMarkets({ limit: 500 });\n      const markets = marketsResult.items;\n\n      if (markets.length === 0) {\n        return {\n          success: true,\n          processed: 0,\n          updated: 0,\n          errors: 0,\n          syncResults: []\n        };\n      }\n\n      // Initialize counters and results\n      let processed = 0;\n      let updated = 0;\n      let errors = 0;\n      const syncResults: MarketSyncResult[] = [];\n\n      // Process each market\n      for (const market of markets) {\n        try {\n          processed++;\n          marketLogger.debug({ marketId: market.id }, `Checking on-chain state for market ${market.name}`);\n\n          // Get the on-chain market information\n          const onChainMarket = await this.getMarketInfo(market.id);\n\n          // Skip if market not found on chain\n          if (!onChainMarket) {\n            marketLogger.warn({ marketId: market.id }, `Market ${market.name} not found on blockchain`);\n            syncResults.push({\n              marketId: market.id,\n              name: market.name,\n              status: 'error',\n              error: 'Market not found on blockchain'\n            });\n            errors++;\n            continue;\n          }\n\n          // Extract the blockchain state\n          const isOpenOnChain = onChainMarket['is-open'];\n          const isResolvedOnChain = onChainMarket['is-resolved'];\n          const winningOutcomeOnChain = onChainMarket['winning-outcome'];\n\n          // Check if the local state matches the on-chain state\n          const isStatusMatch = (\n            (market.status === 'active' && isOpenOnChain && !isResolvedOnChain) ||\n            (market.status === 'resolved' && isResolvedOnChain) ||\n            (market.status === 'closed' && !isOpenOnChain)\n          );\n\n          // Check if outcome matches when both are resolved\n          // If market is resolved on-chain but has no resolvedOutcomeId in database,\n          // we should consider this a mismatch\n          const isOutcomeMatch = (\n            !isResolvedOnChain ||\n            (isResolvedOnChain && market.resolvedOutcomeId !== undefined &&\n              market.resolvedOutcomeId === winningOutcomeOnChain)\n          );\n\n          // If states match, continue to next market\n          if (isStatusMatch && isOutcomeMatch) {\n            marketLogger.debug({ marketId: market.id }, `Market ${market.name} is already synced with blockchain`);\n            syncResults.push({\n              marketId: market.id,\n              name: market.name,\n              status: 'already_synced',\n              onChainData: {\n                'is-open': isOpenOnChain,\n                'is-resolved': isResolvedOnChain,\n                'winning-outcome': winningOutcomeOnChain\n              },\n              localData: {\n                status: market.status,\n                resolvedOutcomeId: market.resolvedOutcomeId\n              }\n            });\n            continue;\n          }\n\n          // Update the market to match blockchain state\n          const updates: any = {};\n\n          // Update status based on on-chain state\n          if (!isStatusMatch) {\n            if (isResolvedOnChain) {\n              updates.status = 'resolved';\n              updates.resolvedAt = new Date().toISOString();\n\n              // If we're changing to resolved status, we should set resolvedBy to indicate this was done by the system\n              if (!market.resolvedBy) {\n                updates.resolvedBy = 'blockchain-sync';\n              }\n            } else if (!isOpenOnChain) {\n              updates.status = 'closed';\n            } else {\n              updates.status = 'active';\n            }\n          }\n\n          // Update resolved outcome if needed\n          // This handles both the case where resolvedOutcomeId doesn't match winningOutcomeOnChain\n          // and the case where resolvedOutcomeId is undefined but the market is resolved on-chain\n          if (isResolvedOnChain &&\n            (market.resolvedOutcomeId === undefined || market.resolvedOutcomeId !== winningOutcomeOnChain)) {\n            updates.resolvedOutcomeId = winningOutcomeOnChain;\n\n            // If we're adding a resolved outcome ID, also ensure resolved status and timestamps are set\n            if (!updates.status) {\n              updates.status = 'resolved';\n            }\n\n            if (!updates.resolvedAt) {\n              updates.resolvedAt = new Date().toISOString();\n            }\n\n            if (!market.resolvedBy && !updates.resolvedBy) {\n              updates.resolvedBy = 'blockchain-sync';\n            }\n          }\n\n          // Apply updates to the market\n          if (Object.keys(updates).length > 0) {\n            marketLogger.info({\n              marketId: market.id,\n              updates\n            }, `Updating market ${market.name} to match blockchain state`);\n\n            // Update the market\n            await this.updateMarket(market.id, updates);\n            updated++;\n\n            syncResults.push({\n              marketId: market.id,\n              name: market.name,\n              status: 'updated',\n              onChainData: {\n                'is-open': isOpenOnChain,\n                'is-resolved': isResolvedOnChain,\n                'winning-outcome': winningOutcomeOnChain\n              },\n              localData: {\n                status: market.status,\n                resolvedOutcomeId: market.resolvedOutcomeId\n              }\n            });\n          }\n\n        } catch (error) {\n          errors++;\n          marketLogger.error({\n            marketId: market.id,\n            error: error instanceof Error ? error.message : String(error)\n          }, `Error syncing market ${market.name} with blockchain`);\n\n          syncResults.push({\n            marketId: market.id,\n            name: market.name,\n            status: 'error',\n            error: error instanceof Error ? error.message : String(error)\n          });\n        }\n      }\n\n      // Log summary\n      marketLogger.info({\n        processed,\n        updated,\n        errors\n      }, 'Completed market synchronization with blockchain');\n\n      return {\n        success: true,\n        processed,\n        updated,\n        errors,\n        syncResults\n      };\n    } catch (error) {\n      marketLogger.error({\n        error: error instanceof Error ? error.message : String(error)\n      }, 'Failed to synchronize markets with blockchain');\n\n      return {\n        success: false,\n        processed: 0,\n        updated: 0,\n        errors: 1,\n        syncResults: []\n      };\n    }\n  }\n};","import { fetchCallReadOnlyFunction, Cl, ClarityType } from '@stacks/transactions';\nimport { STACKS_MAINNET } from '@stacks/network';\nimport { createClerkClient } from '@clerk/backend';\n\nconst CONTRACT_ADDRESS = 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS';\nconst CONTRACT_NAME = 'blaze-welsh-v1';\n\nconst clerkClient = createClerkClient({\n  secretKey: process.env.CLERK_SECRET_KEY,\n  publishableKey: process.env.CLERK_PUBLISHABLE_KEY\n});\n\n// User balance store with Clerk integration\nexport const userBalanceStore = {\n  /**\n   * Get the user's Stacks address from Clerk's publicMetadata\n   */\n  async getUserStacksAddress(userId: string): Promise<string | null> {\n    try {\n      // Get the user from Clerk\n      const user = await clerkClient.users.getUser(userId);\n\n      // Check for Stacks address in public metadata\n      if (user.publicMetadata && typeof user.publicMetadata === 'object') {\n        const metadata = user.publicMetadata as Record<string, any>;\n        if (metadata.stacksAddress) {\n          return metadata.stacksAddress as string;\n        }\n      }\n\n      // No Stacks address found\n      console.warn(`No Stacks address found for user ${userId}`);\n      return null;\n    } catch (error) {\n      console.error(`Error getting Stacks address for user ${userId}:`, error);\n      return null;\n    }\n  },\n\n  /**\n   * Fetch a user's on-chain balance from the contract\n   */\n  async fetchContractBalance(user: string): Promise<number> {\n    try {\n      const result = await fetchCallReadOnlyFunction({\n        contractAddress: CONTRACT_ADDRESS,\n        contractName: CONTRACT_NAME,\n        functionName: 'get-balance',\n        functionArgs: [Cl.principal(user)],\n        network: STACKS_MAINNET,\n        senderAddress: user\n      });\n      const balance = result.type === ClarityType.UInt ? Number(result.value) : 0;\n\n      return balance;\n    } catch (error: unknown) {\n      console.error('Failed to fetch contract balance:', error);\n      return 0;\n    }\n  },\n\n  /**\n   * Get user balance using their Clerk ID\n   * Fetches directly from blockchain if Stacks address is available\n   */\n  async getUserBalance(userId: string) {\n    try {\n      if (!userId) return null;\n\n      // Get stacks address from Clerk\n      const stacksAddress = await this.getUserStacksAddress(userId);\n\n      // Get stored balance data\n      let balance = await kvStore.getEntity('USER_BALANCE', userId);\n\n      // If no balance exists, initialize it\n      if (!balance) {\n        balance = {\n          userId,\n          availableBalance: 0,\n          totalDeposited: 0,\n          totalWithdrawn: 0,\n          inPredictions: 0,\n          lastUpdated: new Date().toISOString(),\n          stacksAddress: null\n        };\n      }\n\n      // If we have a Stacks address, update with real blockchain balance\n      if (stacksAddress) {\n        balance.stacksAddress = stacksAddress;\n        const contractBalance = await this.fetchContractBalance(stacksAddress);\n        balance.availableBalance = contractBalance;\n      }\n\n      return balance;\n    } catch (error) {\n      console.error(`Error getting user balance for ${userId}:`, error);\n      return null;\n    }\n  },\n\n  // Update user balance when making a prediction\n  async updateBalanceForPrediction(userId: string, amount: number) {\n    try {\n      const balance: any = await this.getUserBalance(userId);\n      if (!balance) return null;\n\n      // Check if user has enough balance\n      if (balance.availableBalance < amount) {\n        throw new Error('Insufficient balance');\n      }\n\n      const updatedBalance = {\n        ...balance,\n        availableBalance: balance.availableBalance - amount,\n        inPredictions: balance.inPredictions + amount,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_BALANCE', userId, updatedBalance);\n      return updatedBalance;\n    } catch (error) {\n      console.error(`Error updating balance for prediction, user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Update user balance when a prediction is resolved\n  async updateBalanceForResolvedPrediction(\n    userId: string,\n    originalAmount: number,\n    winnings: number = 0\n  ) {\n    try {\n      const balance: any = await this.getUserBalance(userId);\n      if (!balance) return null;\n\n      const updatedBalance = {\n        ...balance,\n        availableBalance: balance.availableBalance + winnings,\n        inPredictions: balance.inPredictions - originalAmount,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_BALANCE', userId, updatedBalance);\n      return updatedBalance;\n    } catch (error) {\n      console.error(`Error updating balance for resolved prediction, user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Add funds to user balance (for deposit functionality)\n  async addFunds(userId: string, amount: number) {\n    try {\n      const balance: any = await this.getUserBalance(userId);\n      if (!balance) return null;\n\n      const updatedBalance = {\n        ...balance,\n        availableBalance: balance.availableBalance + amount,\n        totalDeposited: balance.totalDeposited + amount,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_BALANCE', userId, updatedBalance);\n      return updatedBalance;\n    } catch (error) {\n      console.error(`Error adding funds for user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Withdraw funds from user balance\n  async withdrawFunds(userId: string, amount: number) {\n    try {\n      const balance: any = await this.getUserBalance(userId);\n      if (!balance) return null;\n\n      // Check if user has enough balance\n      if (balance.availableBalance < amount) {\n        throw new Error('Insufficient balance');\n      }\n\n      const updatedBalance = {\n        ...balance,\n        availableBalance: balance.availableBalance - amount,\n        totalWithdrawn: balance.totalWithdrawn + amount,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_BALANCE', userId, updatedBalance);\n      return updatedBalance;\n    } catch (error) {\n      console.error(`Error withdrawing funds for user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Force refresh a user's balance from the blockchain\n  async refreshBalance(userId: string) {\n    try {\n      const stacksAddress = await this.getUserStacksAddress(userId);\n      if (!stacksAddress) {\n        throw new Error(`No Stacks address found for user ${userId}`);\n      }\n\n      const contractBalance = await this.fetchContractBalance(stacksAddress);\n      const balance = await kvStore.getEntity('USER_BALANCE', userId) || {\n        userId,\n        availableBalance: 0,\n        totalDeposited: 0,\n        totalWithdrawn: 0,\n        inPredictions: 0,\n        lastUpdated: new Date().toISOString()\n      };\n\n      const updatedBalance = {\n        ...balance,\n        availableBalance: contractBalance,\n        stacksAddress,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_BALANCE', userId, updatedBalance);\n      return updatedBalance;\n    } catch (error) {\n      console.error(`Error refreshing balance for user ${userId}:`, error);\n      throw error;\n    }\n  }\n};\n\nconst kvStore = {\n  async getEntity(collection: string, id: string) {\n    console.log({ collection, id });\n    // Get the user's Stacks address\n    const stacksAddress = await userBalanceStore.getUserStacksAddress(id);\n\n    let availableBalance = 0;\n    if (stacksAddress) {\n      availableBalance = await userBalanceStore.fetchContractBalance(stacksAddress);\n    }\n\n    const balance = {\n      userId: id,\n      availableBalance,\n      totalDeposited: 0,\n      totalWithdrawn: 0,\n      inPredictions: 0,\n      lastUpdated: new Date().toISOString(),\n      stacksAddress\n    };\n    return balance;\n  },\n\n  async storeEntity(collection: string, id: string, entity: any) {\n    console.log({ collection, id, entity });\n    return null;\n  }\n};","import * as kvStore from './kv-store';\n\n// User stats store with Vercel KV\nexport const userStatsStore = {\n  // Helper to calculate user score consistently across the app\n  calculateUserScore(stats: any): number {\n    // Only count users with at least 5 predictions for the accuracy component\n    const accuracyComponent = stats.totalPredictions >= 5 ? stats.accuracy : 0;\n\n    // Normalize earnings (0-100 scale typically)\n    const normalizedEarnings = stats.totalEarnings / 100;\n\n    // Prediction volume factor (logarithmic scale to prevent domination by volume)\n    const volumeFactor = stats.totalPredictions > 0 ? Math.log10(stats.totalPredictions + 1) * 10 : 0;\n\n    // Consistency factor - higher for users who maintain accuracy across more predictions\n    const consistencyFactor = stats.totalPredictions >= 10 ?\n      (accuracyComponent * Math.min(stats.totalPredictions / 20, 1.5)) :\n      accuracyComponent;\n\n    // Final composite score\n    return (consistencyFactor * 0.4) +\n      (normalizedEarnings * 0.3) +\n      (Math.min(volumeFactor, 25) * 0.3);\n  },\n\n  // Get user stats for a specific user\n  async getUserStats(userId: string) {\n    try {\n      if (!userId) return null;\n\n      const stats = await kvStore.getEntity('USER_STATS', userId);\n      return stats || null;\n    } catch (error) {\n      console.error(`Error getting user stats for ${userId}:`, error);\n      return null;\n    }\n  },\n\n  // Update user stats when a prediction is made\n  async updateStatsForNewPrediction(userId: string, prediction: any) {\n    try {\n      // Get current stats or create new ones\n      const currentStats: any = await this.getUserStats(userId) || {\n        userId,\n        totalPredictions: 0,\n        correctPredictions: 0,\n        accuracy: 0,\n        totalAmount: 0,\n        totalEarnings: 0,\n        lastUpdated: new Date().toISOString()\n      };\n\n      // Update stats\n      const updatedStats = {\n        ...currentStats,\n        totalPredictions: currentStats.totalPredictions + 1,\n        totalAmount: currentStats.totalAmount + prediction.amount,\n        lastUpdated: new Date().toISOString()\n      };\n\n      // Recalculate accuracy\n      updatedStats.accuracy =\n        updatedStats.totalPredictions > 0\n          ? (updatedStats.correctPredictions / updatedStats.totalPredictions) * 100\n          : 0;\n\n      // Store updated stats\n      await kvStore.storeEntity('USER_STATS', userId, updatedStats);\n\n      // Update leaderboard sorted sets for efficient querying\n      await this.updateLeaderboardEntries(updatedStats);\n\n      return updatedStats;\n    } catch (error) {\n      console.error(`Error updating stats for user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Update user stats when a prediction is resolved\n  async updateStatsForResolvedPrediction(\n    userId: string,\n    prediction: any,\n    isCorrect: boolean,\n    earnings: number\n  ) {\n    try {\n      // Handle anonymous/test users specially\n      if (!userId || userId === 'anonymous') {\n        console.log('Skipping stats update for anonymous user');\n        return {\n          userId,\n          totalPredictions: 1,\n          correctPredictions: isCorrect ? 1 : 0,\n          accuracy: isCorrect ? 100 : 0,\n          totalAmount: prediction?.amount || 0,\n          totalEarnings: earnings,\n          lastUpdated: new Date().toISOString()\n        };\n      }\n\n      // Get current stats\n      const currentStats: any = await this.getUserStats(userId);\n      if (!currentStats) {\n        console.log(`Creating new stats for user ${userId}`);\n        // Create default stats if not found\n        const newStats = {\n          userId,\n          totalPredictions: 1,\n          correctPredictions: isCorrect ? 1 : 0,\n          accuracy: isCorrect ? 100 : 0,\n          totalAmount: prediction?.amount || 0,\n          totalEarnings: earnings,\n          lastUpdated: new Date().toISOString()\n        };\n        \n        // Store new stats\n        await kvStore.storeEntity('USER_STATS', userId, newStats);\n        \n        // Update leaderboard sorted sets\n        await this.updateLeaderboardEntries(newStats);\n        \n        return newStats;\n      }\n\n      // Update stats\n      const updatedStats = {\n        ...currentStats,\n        correctPredictions: isCorrect\n          ? currentStats.correctPredictions + 1\n          : currentStats.correctPredictions,\n        totalEarnings: currentStats.totalEarnings + earnings,\n        lastUpdated: new Date().toISOString()\n      };\n\n      // Recalculate accuracy\n      updatedStats.accuracy =\n        updatedStats.totalPredictions > 0\n          ? (updatedStats.correctPredictions / updatedStats.totalPredictions) * 100\n          : 0;\n\n      // Store updated stats\n      await kvStore.storeEntity('USER_STATS', userId, updatedStats);\n\n      // Update leaderboard sorted sets\n      await this.updateLeaderboardEntries(updatedStats);\n\n      return updatedStats;\n    } catch (error) {\n      console.error(`Error updating stats for resolved prediction, user ${userId}:`, error);\n      throw error;\n    }\n  },\n\n  // Update user's username (when available from auth provider)\n  async updateUsername(userId: string, username: string) {\n    try {\n      const stats: any = await this.getUserStats(userId);\n      if (!stats) return null;\n\n      const updatedStats = {\n        ...stats,\n        username,\n        lastUpdated: new Date().toISOString()\n      };\n\n      await kvStore.storeEntity('USER_STATS', userId, updatedStats);\n\n      // Update leaderboard entries\n      await this.updateLeaderboardEntries(updatedStats);\n\n      return updatedStats;\n    } catch (error) {\n      console.error(`Error updating username for user ${userId}:`, error);\n      return null;\n    }\n  },\n\n  // Update leaderboard sorted sets for efficient querying\n  async updateLeaderboardEntries(stats: any): Promise<void> {\n    try {\n      // Add to earnings leaderboard (sorted by total earnings)\n      await kvStore.addToSortedSet(\n        'LEADERBOARD_EARNINGS',\n        stats.userId,\n        stats.totalEarnings\n      );\n\n      // Add to accuracy leaderboard (sorted by accuracy)\n      // Only count users with at least 5 predictions for accuracy\n      const accuracyScore = stats.totalPredictions >= 5 ? stats.accuracy : 0;\n      await kvStore.addToSortedSet(\n        'LEADERBOARD_ACCURACY',\n        stats.userId,\n        accuracyScore\n      );\n\n      // Advanced scoring algorithm for leaderboard ranking\n      // Calculate the composite score using the helper method\n      const compositeScore = this.calculateUserScore(stats);\n\n      // Store in the main leaderboard\n      await kvStore.addToSortedSet(\n        'LEADERBOARD',\n        stats.userId,\n        compositeScore\n      );\n    } catch (error) {\n      console.error('Error updating leaderboard entries:', error);\n      throw error;\n    }\n  },\n\n  // Get top leaderboard entries by earnings\n  async getTopEarners(limit: number = 10) {\n    try {\n      // Get top user IDs sorted by earnings (highest first)\n      const userIds = await kvStore.getTopFromSortedSet('LEADERBOARD_EARNINGS', limit);\n\n      // Get full stats for each user ID\n      const leaderboard = await this.getUserStatsForIds(userIds);\n\n      // Get scores from the same sorted set to ensure consistency\n      const scoresMap = await kvStore.getScoresFromSortedSet('LEADERBOARD_EARNINGS', userIds);\n\n      // Add rank and use the actual scores from Redis\n      return leaderboard.map((entry: any, index) => {\n        return {\n          ...entry,\n          rank: index + 1,\n          score: scoresMap[entry.userId] || this.calculateUserScore(entry)\n        };\n      });\n    } catch (error) {\n      console.error('Error getting top earners:', error);\n      return [];\n    }\n  },\n\n  // Get top leaderboard entries by accuracy\n  async getTopAccurate(limit: number = 10) {\n    try {\n      // Get top user IDs sorted by accuracy (highest first)\n      const userIds = await kvStore.getTopFromSortedSet('LEADERBOARD_ACCURACY', limit);\n\n      // Get full stats for each user ID\n      const leaderboard = await this.getUserStatsForIds(userIds);\n\n      // Get scores from the same sorted set to ensure consistency\n      const scoresMap = await kvStore.getScoresFromSortedSet('LEADERBOARD_ACCURACY', userIds);\n\n      // Add rank and use the actual scores from Redis\n      return leaderboard.map((entry: any, index) => {\n        return {\n          ...entry,\n          rank: index + 1,\n          score: scoresMap[entry.userId] || this.calculateUserScore(entry)\n        };\n      });\n    } catch (error) {\n      console.error('Error getting top accuracy:', error);\n      return [];\n    }\n  },\n\n  // Get top leaderboard entries by combined score\n  async getTopUsers(limit: number = 10) {\n    try {\n      // Get top user IDs sorted by combined score (highest first)\n      const userIds = await kvStore.getTopFromSortedSet('LEADERBOARD', limit);\n\n      // Get full stats for each user ID\n      const leaderboard = await this.getUserStatsForIds(userIds);\n\n      // Get scores from the same sorted set to ensure consistency\n      const scoresMap = await kvStore.getScoresFromSortedSet('LEADERBOARD', userIds);\n\n      // Add rank and use the actual scores from Redis\n      return leaderboard.map((entry: any, index) => {\n        return {\n          ...entry,\n          rank: index + 1,\n          score: scoresMap[entry.userId] || this.calculateUserScore(entry)\n        };\n      });\n    } catch (error) {\n      console.error('Error getting leaderboard:', error);\n      return [];\n    }\n  },\n\n  // Helper to get multiple user stats by IDs\n  async getUserStatsForIds(userIds: string[]) {\n    try {\n      if (userIds.length === 0) return [];\n\n      // Get stats for each user ID\n      const statsPromises = userIds.map(id => this.getUserStats(id));\n      const statsResults = await Promise.all(statsPromises);\n\n      // Filter out any null results\n      return statsResults.filter(Boolean);\n    } catch (error) {\n      console.error('Error getting user stats for IDs:', error);\n      return [];\n    }\n  }\n};","import * as kvStore from './kv-store';\nimport { isAdmin, generateUUID } from './utils';\nimport { AppError, logger } from './logger';\nimport { marketStore } from './market-store';\nimport { userBalanceStore } from './user-balance-store';\nimport { userStatsStore } from './user-stats-store';\n\n// Create a logger instance for this module\nconst predictionLogger = logger.child({ context: 'prediction-store' });\n\n// Prediction store with Vercel KV\nexport const predictionStore = {\n  // Create a new prediction\n  async createPrediction(data: {\n    marketId: string;\n    marketName: string;\n    outcomeId: number;\n    outcomeName: string;\n    userId: string;\n    amount: number;\n  }) {\n    try {\n      // Validate input\n      if (!data.marketId || !data.userId || data.amount <= 0) {\n        throw new AppError({\n          message: 'Invalid prediction data',\n          context: 'prediction-store',\n          code: 'PREDICTION_VALIDATION_ERROR',\n          data: {\n            hasMarketId: !!data.marketId,\n            hasUserId: !!data.userId,\n            amount: data.amount\n          }\n        }).log();\n      }\n\n      const id = generateUUID();\n      const now = new Date().toISOString();\n\n      predictionLogger.debug(\n        { marketId: data.marketId, userId: data.userId, amount: data.amount },\n        'Creating new prediction'\n      );\n\n      // Generate NFT receipt\n      const nftReceipt = {\n        id: generateUUID(),\n        tokenId: `${data.marketId}-${data.userId}-${now}`,\n        image: this.generateNftImage(data.marketName, data.outcomeName, data.amount),\n        predictionId: id,\n        marketName: data.marketName,\n        outcomeName: data.outcomeName,\n        amount: data.amount,\n        createdAt: now\n      };\n\n      // Create the prediction\n      const prediction = {\n        id,\n        marketId: data.marketId,\n        outcomeId: data.outcomeId,\n        outcomeName: data.outcomeName,\n        userId: data.userId,\n        amount: data.amount,\n        createdAt: now,\n        nftReceipt,\n        status: 'active'\n      };\n\n      // Start a transaction for atomic operation\n      const tx = await kvStore.startTransaction();\n\n      try {\n        // Add all operations to the transaction\n        await tx.addEntity('PREDICTION', id, prediction);\n        await tx.addEntity('PREDICTION_NFT', nftReceipt.id, nftReceipt);\n        await tx.addToSetInTransaction('USER_PREDICTIONS', data.userId, id);\n        await tx.addToSetInTransaction('MARKET_PREDICTIONS', data.marketId, id);\n\n        // Execute the transaction\n        const success = await tx.execute();\n\n        if (!success) {\n          throw new AppError({\n            message: 'Failed to create prediction - transaction failed',\n            context: 'prediction-store',\n            code: 'PREDICTION_TRANSACTION_ERROR',\n            data: { predictionId: id }\n          }).log();\n        }\n\n        // Update market stats separately since it requires accessing the market store\n        // This is not included in the transaction since it involves another store\n        await marketStore.updateMarketStats(\n          data.marketId,\n          data.outcomeId,\n          data.amount,\n          data.userId\n        );\n\n        predictionLogger.info(\n          { predictionId: id, userId: data.userId },\n          'Prediction created successfully'\n        );\n\n        return prediction;\n      } catch (error) {\n        // Rethrow AppErrors, wrap others\n        if (error instanceof AppError) {\n          throw error;\n        } else {\n          throw new AppError({\n            message: 'Error during prediction creation transaction',\n            context: 'prediction-store',\n            code: 'PREDICTION_CREATE_ERROR',\n            originalError: error instanceof Error ? error : new Error(String(error)),\n            data: { marketId: data.marketId, userId: data.userId }\n          }).log();\n        }\n      }\n    } catch (error) {\n      if (error instanceof AppError) {\n        throw error;\n      } else {\n        throw new AppError({\n          message: 'Failed to create prediction',\n          context: 'prediction-store',\n          code: 'PREDICTION_CREATE_ERROR',\n          originalError: error instanceof Error ? error : new Error(String(error)),\n          data: {\n            marketId: data.marketId,\n            userId: data.userId,\n            amount: data.amount\n          }\n        }).log();\n      }\n    }\n  },\n\n  // Get all predictions for a user\n  async getUserPredictions(userId: string) {\n    try {\n      if (!userId) return [];\n\n      // Get all prediction IDs for the user\n      const predictionIds = await kvStore.getSetMembers('USER_PREDICTIONS', userId);\n\n      if (predictionIds.length === 0) {\n        return [];\n      }\n\n      // Get all predictions in parallel\n      const predictions = await Promise.all(\n        predictionIds.map(id => this.getPrediction(id))\n      );\n\n      // Filter out any undefined predictions (in case of data inconsistency)\n      return predictions.filter(Boolean);\n    } catch (error) {\n      console.error('Error getting user predictions:', error);\n      return [];\n    }\n  },\n\n  // Get all predictions for a market\n  async getMarketPredictions(marketId: string) {\n    try {\n      if (!marketId) return [];\n\n      // Get all prediction IDs for the market\n      const predictionIds = await kvStore.getSetMembers('MARKET_PREDICTIONS', marketId);\n\n      if (predictionIds.length === 0) {\n        return [];\n      }\n\n      // Get all predictions in parallel\n      const predictions = await Promise.all(\n        predictionIds.map(id => this.getPrediction(id))\n      );\n\n      // Filter out any undefined predictions (in case of data inconsistency)\n      return predictions.filter(Boolean);\n    } catch (error) {\n      console.error('Error getting market predictions:', error);\n      return [];\n    }\n  },\n\n  // Get a specific prediction by ID\n  async getPrediction(id: string) {\n    try {\n      if (!id) return undefined;\n\n      const prediction = await kvStore.getEntity('PREDICTION', id);\n      return prediction || undefined;\n    } catch (error) {\n      console.error(`Error getting prediction ${id}:`, error);\n      return undefined;\n    }\n  },\n\n  // Get a specific NFT receipt\n  async getNFTReceipt(id: string) {\n    try {\n      if (!id) return undefined;\n\n      const receipt = await kvStore.getEntity('PREDICTION_NFT', id);\n      return receipt || undefined;\n    } catch (error) {\n      console.error(`Error getting NFT receipt ${id}:`, error);\n      return undefined;\n    }\n  },\n\n  // Update prediction status\n  async updatePredictionStatus(\n    id: string,\n    status: 'active' | 'won' | 'lost' | 'redeemed' | 'cancelled'\n  ) {\n    try {\n      const prediction = await this.getPrediction(id);\n      if (!prediction) return undefined;\n\n      const updatedPrediction = { ...prediction, status };\n\n      // Store the updated prediction\n      await kvStore.storeEntity('PREDICTION', id, updatedPrediction);\n\n      return updatedPrediction;\n    } catch (error) {\n      console.error(`Error updating prediction ${id}:`, error);\n      return undefined;\n    }\n  },\n\n  // Generate a placeholder image URL for the NFT\n  // In a real app, this would generate or reference an actual image\n  generateNftImage(marketName: string, outcomeName: string, amount: number): string {\n    // Create a data URI for a simple SVG image\n    // This approach doesn't rely on external services and works in all environments\n    const bgColor = '#1a2026';\n    const textColor = '#ffffff';\n\n    // Sanitize text to prevent SVG injection\n    const sanitizedOutcome = outcomeName.replace(/[<>&\"']/g, '');\n    const sanitizedMarket = marketName.substring(0, 30).replace(/[<>&\"']/g, '');\n\n    const svg = `\n        <svg width=\"600\" height=\"400\" xmlns=\"http://www.w3.org/2000/svg\">\n            <rect width=\"600\" height=\"400\" fill=\"${bgColor}\" />\n            <text x=\"300\" y=\"170\" font-family=\"Arial, sans-serif\" font-size=\"24\" text-anchor=\"middle\" fill=\"${textColor}\">Prediction Receipt</text>\n            <text x=\"300\" y=\"210\" font-family=\"Arial, sans-serif\" font-size=\"20\" text-anchor=\"middle\" fill=\"${textColor}\">${sanitizedOutcome}</text>\n            <text x=\"300\" y=\"250\" font-family=\"Arial, sans-serif\" font-size=\"16\" text-anchor=\"middle\" fill=\"${textColor}\">${sanitizedMarket}</text>\n            <text x=\"300\" y=\"280\" font-family=\"Arial, sans-serif\" font-size=\"18\" text-anchor=\"middle\" fill=\"${textColor}\">$${amount.toFixed(2)}</text>\n        </svg>`;\n\n    // Convert SVG to a data URI\n    return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n  },\n\n  /**\n     * Create a prediction with balance update\n     * This function handles the complete process of:\n     * 1. Checking user balance and deducting funds\n     * 2. Creating the prediction and NFT receipt\n     * 3. Updating market stats\n     * 4. Updating user stats for leaderboard\n     * \n     * @param data Prediction data\n     * @returns Object with created prediction or error message\n     */\n  async createPredictionWithBalanceUpdate(data: {\n    marketId: string;\n    outcomeId: number;\n    userId: string;\n    amount: number;\n  }): Promise<{\n    success: boolean;\n    prediction?: any;\n    error?: string;\n    market?: Record<string, unknown>;\n    outcomeName?: string;\n  }> {\n    try {\n      // Set up structured logging for this operation\n      const opLogger = predictionLogger.child({\n        operation: 'createPredictionWithBalance',\n        marketId: data.marketId,\n        userId: data.userId,\n        amount: data.amount\n      });\n\n      opLogger.info({}, 'Starting prediction creation with balance update');\n\n      // Input validation\n      if (!data.marketId || !data.userId || data.amount <= 0) {\n        const error = new AppError({\n          message: 'Invalid prediction data',\n          context: 'prediction-store',\n          code: 'PREDICTION_VALIDATION_ERROR',\n          data: {\n            hasMarketId: !!data.marketId,\n            hasUserId: !!data.userId,\n            amount: data.amount\n          }\n        }).log();\n\n        return { success: false, error: error.message };\n      }\n\n      // Get the market to verify it exists and get outcome name\n      const market: any = await marketStore.getMarket(data.marketId);\n      if (!market) {\n        const error = new AppError({\n          message: `Market not found: ${data.marketId}`,\n          context: 'prediction-store',\n          code: 'MARKET_NOT_FOUND',\n          data: { marketId: data.marketId }\n        }).log();\n\n        return { success: false, error: error.message };\n      }\n\n      // Find the outcome\n      const outcome = market.outcomes.find((o: any) => o.id === data.outcomeId);\n      if (!outcome) {\n        const error = new AppError({\n          message: `Outcome ${data.outcomeId} not found in market ${data.marketId}`,\n          context: 'prediction-store',\n          code: 'OUTCOME_NOT_FOUND',\n          data: {\n            marketId: data.marketId,\n            outcomeId: data.outcomeId,\n            availableOutcomes: market.outcomes.map((o: any) => o.id)\n          }\n        }).log();\n\n        return { success: false, error: error.message };\n      }\n\n      // Check if market is already resolved\n      if (market.resolvedOutcomeId !== undefined) {\n        const error = new AppError({\n          message: `Market ${data.marketId} is already resolved`,\n          context: 'prediction-store',\n          code: 'MARKET_ALREADY_RESOLVED',\n          data: {\n            marketId: data.marketId,\n            resolvedOutcomeId: market.resolvedOutcomeId\n          }\n        }).log();\n\n        return { success: false, error: error.message };\n      }\n\n      // Check if market end date has passed\n      if (new Date(market.endDate) < new Date()) {\n        const error = new AppError({\n          message: `Market ${data.marketId} has ended`,\n          context: 'prediction-store',\n          code: 'MARKET_ENDED',\n          data: {\n            marketId: data.marketId,\n            endDate: market.endDate,\n            currentDate: new Date().toISOString()\n          }\n        }).log();\n\n        return { success: false, error: error.message };\n      }\n\n      opLogger.debug({}, 'Market validation completed, processing balance update');\n\n      // Deduct the amount from user's balance\n      try {\n        const balanceResult = await userBalanceStore.updateBalanceForPrediction(\n          data.userId,\n          data.amount\n        );\n\n        if (!balanceResult) {\n          throw new AppError({\n            message: 'Failed to update user balance',\n            context: 'prediction-store',\n            code: 'BALANCE_UPDATE_FAILED',\n            data: { userId: data.userId, amount: data.amount }\n          });\n        }\n\n        opLogger.debug({}, 'Balance updated successfully, creating prediction');\n      } catch (balanceError) {\n        // Handle insufficient balance case specifically\n        if (balanceError instanceof Error &&\n          balanceError.message.includes('Insufficient balance')) {\n          const error = new AppError({\n            message: 'Insufficient balance. Please add more funds to your account.',\n            context: 'prediction-store',\n            code: 'INSUFFICIENT_BALANCE',\n            originalError: balanceError,\n            data: { userId: data.userId, amount: data.amount }\n          }).log();\n\n          return { success: false, error: error.message };\n        }\n\n        // Rethrow other errors\n        throw balanceError;\n      }\n\n      // Create the prediction with NFT receipt\n      const prediction = await this.createPrediction({\n        marketId: market.id,\n        marketName: market.name,\n        outcomeId: data.outcomeId,\n        outcomeName: outcome.name,\n        userId: data.userId,\n        amount: data.amount\n      });\n\n      opLogger.debug(\n        { predictionId: prediction.id },\n        'Prediction created, updating user stats'\n      );\n\n      // Update user stats for leaderboard tracking\n      await userStatsStore.updateStatsForNewPrediction(data.userId, prediction);\n\n      opLogger.info(\n        { predictionId: prediction.id },\n        'Prediction with balance update completed successfully'\n      );\n\n      // Convert market to Record<string, unknown> to comply with return type\n      const marketData: Record<string, unknown> = { ...market };\n\n      return {\n        success: true,\n        prediction,\n        market: marketData,\n        outcomeName: outcome.name\n      };\n    } catch (error) {\n      // If it's already an AppError, just log and return it\n      if (error instanceof AppError) {\n        error.log();\n        return { success: false, error: error.message };\n      }\n\n      // Handle other errors\n      const appError = new AppError({\n        message: 'Failed to create prediction',\n        context: 'prediction-store',\n        code: 'PREDICTION_CREATE_ERROR',\n        originalError: error instanceof Error ? error : new Error(String(error)),\n        data: {\n          marketId: data.marketId,\n          userId: data.userId,\n          amount: data.amount\n        }\n      }).log();\n\n      return { success: false, error: appError.message };\n    }\n  },\n\n  // Delete a prediction and its associated NFT receipt\n  async deletePrediction(predictionId: string): Promise<boolean> {\n    try {\n      if (!predictionId) return false;\n\n      // Get the prediction to retrieve its data\n      const prediction: any = await this.getPrediction(predictionId);\n      if (!prediction) return false;\n\n      // Delete from the main predictions store\n      await kvStore.deleteEntity('PREDICTION', predictionId);\n\n      // Remove from user's predictions set\n      await kvStore.removeFromSet('USER_PREDICTIONS', prediction.userId, predictionId);\n\n      // Remove from market's predictions set\n      await kvStore.removeFromSet('MARKET_PREDICTIONS', prediction.marketId, predictionId);\n\n      // Delete the NFT receipt if it exists\n      if (prediction.nftReceipt?.id) {\n        await kvStore.deleteEntity('PREDICTION_NFT', prediction.nftReceipt.id);\n      }\n\n      return true;\n    } catch (error) {\n      console.error(`Error deleting prediction ${predictionId}:`, error);\n      return false;\n    }\n  },\n\n  /**\n     * Update a prediction with new data\n     */\n  async updatePrediction(predictionId: string, data: any) {\n    try {\n      // Get existing prediction\n      const prediction = await this.getPrediction(predictionId);\n      if (!prediction) {\n        return null;\n      }\n\n      // Update prediction data\n      const updatedPrediction = {\n        ...prediction,\n        ...data,\n      };\n\n      // Store updated prediction\n      await kvStore.storeEntity('PREDICTION', predictionId, updatedPrediction);\n\n      return updatedPrediction;\n    } catch (error) {\n      console.error(`Error updating prediction ${predictionId}:`, error);\n      return null;\n    }\n  },\n\n  /**\n     * Validate if a prediction is eligible for redemption\n     * \n     * @param predictionId ID of the prediction\n     * @param userId User attempting to redeem\n     * @returns Validation result with prediction if successful\n     */\n  async validateRedemptionEligibility(\n    predictionId: string,\n    userId: string\n  ): Promise<{\n    success: boolean;\n    prediction?: any;\n    error?: string;\n    isAdmin?: boolean;\n  }> {\n    try {\n      // Get prediction\n      const prediction: any = await this.getPrediction(predictionId);\n      if (!prediction) {\n        return { success: false, error: 'Prediction not found' };\n      }\n\n      // Use isAdmin function directly (already imported at the top)\n      const userIsAdmin = isAdmin(userId);\n\n      // Verify the prediction belongs to the user or user is admin\n      if (prediction.userId !== userId && !userIsAdmin) {\n        return { success: false, error: 'Unauthorized: This prediction does not belong to you' };\n      }\n\n      // Check if prediction is already redeemed\n      if (prediction.status === 'redeemed') {\n        return { success: false, error: 'Prediction has already been redeemed' };\n      }\n\n      // Check if prediction is eligible for redemption (must be won or lost)\n      if (prediction.status !== 'won' && prediction.status !== 'lost') {\n        return { success: false, error: 'Prediction is not eligible for redemption yet' };\n      }\n\n      return {\n        success: true,\n        prediction,\n        isAdmin: userIsAdmin\n      };\n    } catch (error) {\n      console.error(`Error validating redemption eligibility for prediction ${predictionId}:`, error);\n      return { success: false, error: 'Failed to validate prediction redemption eligibility' };\n    }\n  },\n\n  /**\n     * Redeem a prediction with balance update\n     * This function handles the complete process of:\n     * 1. Validating the prediction is eligible for redemption \n     * 2. Updating the prediction status\n     * 3. Updating the user's balance\n     * \n     * @param predictionId The ID of the prediction to redeem\n     * @param userId The ID of the user trying to redeem\n     * @returns Object with redemption result\n     */\n  async redeemPredictionWithBalanceUpdate(\n    predictionId: string,\n    userId: string\n  ): Promise<{\n    success: boolean;\n    prediction?: any;\n    payout?: number;\n    error?: string;\n  }> {\n    try {\n      // First validate eligibility\n      const validationResult = await this.validateRedemptionEligibility(predictionId, userId);\n      if (!validationResult.success) {\n        return { success: false, error: validationResult.error };\n      }\n\n      const prediction = validationResult.prediction!;\n\n      // Calculate payout (winners get their calculated payout, losers get 0)\n      const payout = prediction.status === 'won' ? prediction.potentialPayout || 0 : 0;\n\n      // Update prediction as redeemed\n      const updatedPrediction = await this.updatePrediction(predictionId, {\n        status: 'redeemed',\n        redeemedAt: new Date().toISOString()\n      });\n\n      if (!updatedPrediction) {\n        return { success: false, error: 'Failed to update prediction' };\n      }\n\n      // Update user's balance\n      if (payout > 0) {\n        await userBalanceStore.updateBalanceForResolvedPrediction(\n          userId,\n          prediction.amount,\n          payout\n        );\n      } else {\n        // For losers, just update to decrease the inPredictions amount\n        await userBalanceStore.updateBalanceForResolvedPrediction(\n          userId,\n          prediction.amount,\n          0\n        );\n      }\n\n      return {\n        success: true,\n        prediction: updatedPrediction,\n        payout\n      };\n    } catch (error) {\n      console.error(`Error redeeming prediction ${predictionId}:`, error);\n      return { success: false, error: 'Failed to redeem prediction' };\n    }\n  },\n\n  /**\n     * Redeem a prediction after market resolution\n     * This is kept for backward compatibility but we recommend using \n     * redeemPredictionWithBalanceUpdate for new code\n     */\n  async redeemPrediction(predictionId: string): Promise<{\n    prediction: any;\n    payout: number;\n  }> {\n    try {\n      // Get prediction\n      const prediction: any = await this.getPrediction(predictionId);\n      if (!prediction) {\n        return { prediction: null, payout: 0 };\n      }\n\n      // Check if prediction is already redeemed\n      if (prediction.status === 'redeemed') {\n        return { prediction: prediction, payout: 0 };\n      }\n\n      // Check if prediction is eligible for redemption (must be won or lost)\n      if (prediction.status !== 'won' && prediction.status !== 'lost') {\n        return { prediction: prediction, payout: 0 };\n      }\n\n      // Calculate payout (winners get their calculated payout, losers get 0)\n      const payout = prediction.status === 'won' ? prediction.potentialPayout || 0 : 0;\n\n      // Update prediction as redeemed\n      const updatedPrediction = await this.updatePrediction(predictionId, {\n        status: 'redeemed',\n        redeemedAt: new Date().toISOString()\n      });\n\n      return {\n        prediction: updatedPrediction,\n        payout: payout\n      };\n    } catch (error) {\n      console.error(`Error redeeming prediction ${predictionId}:`, error);\n      return { prediction: null, payout: 0 };\n    }\n  },\n\n  /**\n     * Get all predictions for a specific market with a specific status\n     */\n  async getMarketPredictionsByStatus(marketId: string, status: string) {\n    try {\n      const predictions = await this.getMarketPredictions(marketId);\n      return predictions.filter((p: any) => p.status === status);\n    } catch (error) {\n      console.error(`Error getting market predictions by status for market ${marketId}:`, error);\n      return [];\n    }\n  }\n};"]}