Skip to content

Latest commit

ย 

History

History
791 lines (639 loc) ยท 23.8 KB

File metadata and controls

791 lines (639 loc) ยท 23.8 KB

Predictify Hybrid API Documentation

Version: v1.0.0
Platform: Stellar Soroban
Audience: Developers integrating with Predictify Hybrid smart contracts


๐Ÿ“‹ Table of Contents

  1. API Overview
  2. API Versioning
  3. Core API Reference
  4. Data Structures
  5. Error Codes
  6. Integration Examples
  7. Troubleshooting Guide
  8. Support and Resources

๐Ÿš€ API Overview

The Predictify Hybrid smart contract provides a comprehensive API for building prediction market applications on the Stellar network. The API supports market creation, voting, dispute resolution, oracle integration, and administrative functions.

Key Features

  • Market Management: Create, extend, and resolve prediction markets
  • Voting System: Stake-based voting with proportional payouts
  • Dispute Resolution: Community-driven dispute and resolution system
  • Oracle Integration: Support for Reflector, Pyth, and custom oracles
  • Fee Management: Automated fee collection and distribution
  • Admin Governance: Administrative functions for contract management

๐Ÿ“š API Versioning

Current Version: v1.0.0

The Predictify Hybrid smart contract follows semantic versioning (SemVer) for API compatibility and contract upgrades. This section provides comprehensive information about API versions, compatibility, and migration strategies.

๐Ÿท๏ธ Version Schema

We use Semantic Versioning (SemVer) with the format MAJOR.MINOR.PATCH:

  • MAJOR (1.x.x): Breaking changes that require client updates
  • MINOR (x.1.x): New features that are backward compatible
  • PATCH (x.x.1): Bug fixes and optimizations

๐Ÿ“‹ Version History

v1.0.0 (Current) - Production Release

Release Date: 2025-01-15
Status: โœ… Active

Core Features:

  • Complete prediction market functionality
  • Oracle integration (Reflector, Pyth)
  • Voting and dispute resolution system
  • Fee collection and distribution
  • Admin governance functions
  • Comprehensive validation system

API Endpoints:

  • initialize(admin: Address) - Contract initialization
  • create_market(...) - Market creation
  • vote(...) - User voting
  • dispute_market(...) - Dispute submission
  • claim_winnings(...) - Claim payouts
  • collect_fees(...) - Admin fee collection
  • resolve_market(...) - Market resolution

Breaking Changes from v0.x.x:

  • Renamed submit_vote() to vote()
  • Updated oracle configuration structure
  • Modified dispute threshold calculation
  • Enhanced validation error codes

๐Ÿ”„ Compatibility Matrix

Client Version Contract v1.0.x Contract v0.9.x Contract v0.8.x
Client v1.0.x โœ… Full โš ๏ธ Limited โŒ Incompatible
Client v0.9.x โš ๏ธ Limited โœ… Full โœ… Full
Client v0.8.x โŒ Incompatible โš ๏ธ Limited โœ… Full

Legend:

  • โœ… Full: Complete compatibility, all features supported
  • โš ๏ธ Limited: Basic functionality works, some features unavailable
  • โŒ Incompatible: Not supported, upgrade required

๐Ÿš€ Upgrade Strategies

For Contract Upgrades

1. Backward Compatible Updates (MINOR/PATCH)

# Deploy new version alongside existing
soroban contract deploy \
  --wasm target/wasm32-unknown-unknown/release/predictify_hybrid_v1_1_0.wasm \
  --network mainnet

# Update contract references gradually
# Old version continues to work

2. Breaking Changes (MAJOR)

# 1. Deploy new contract version
# 2. Migrate critical state (if supported)
# 3. Update all client applications
# 4. Deprecate old contract

# Migration example
soroban contract invoke \
  --id $NEW_CONTRACT_ID \
  --fn migrate_from_v0 \
  --arg old_contract=$OLD_CONTRACT_ID

For Client Applications

JavaScript/TypeScript Example:

// Version-aware client initialization
const contractVersion = await getContractVersion(contractId);

if (contractVersion.startsWith('1.0')) {
    // Use v1.0 API
    await contract.vote(marketId, outcome, stake);
} else if (contractVersion.startsWith('0.9')) {
    // Use legacy API
    await contract.submit_vote(marketId, outcome, stake);
} else {
    throw new Error(`Unsupported contract version: ${contractVersion}`);
}

๐Ÿ“– API Documentation by Version

Current API (v1.0.x)

Core Functions:

  • Market Management: create_market(), extend_market(), resolve_market()
  • Voting Operations: vote(), claim_winnings()
  • Dispute System: dispute_market(), vote_on_dispute()
  • Oracle Integration: submit_oracle_result(), update_oracle_config()
  • Admin Functions: collect_fees(), update_config(), pause_contract()

Data Structures:

  • Market: Core market data structure
  • Vote: User vote representation
  • OracleConfig: Oracle configuration
  • DisputeThreshold: Dynamic dispute thresholds

Error Codes:

  • 100-199: User operation errors
  • 200-299: Oracle errors
  • 300-399: Validation errors
  • 400-499: System errors

Legacy API (v0.9.x)

Deprecated Functions:

  • submit_vote() โ†’ Use vote() in v1.0+
  • create_prediction_market() โ†’ Use create_market() in v1.0+
  • get_market_stats() โ†’ Use get_market_analytics() in v1.0+

๐Ÿ” Version Detection

Check Contract Version:

# Using Soroban CLI
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_version \
  --network mainnet

JavaScript/TypeScript:

import { Contract } from '@stellar/stellar-sdk';

const getContractVersion = async (contractId: string): Promise<string> => {
    try {
        const result = await contract.call('get_version');
        return result.toString();
    } catch (error) {
        // Fallback for older contracts without version endpoint
        return '0.9.0';
    }
};

๐Ÿ›ก๏ธ Deprecation Policy

Timeline:

  • Announcement: 90 days before deprecation
  • Warning Period: 60 days with deprecation warnings
  • End of Support: 30 days notice before complete removal

Current Deprecations:

  • submit_vote(): Deprecated in v1.0.0, removal planned for v2.0.0
  • create_prediction_market(): Deprecated in v1.0.0, removal planned for v2.0.0

๐Ÿ“… Release Schedule

Planned Releases:

  • v1.1.0 (Q2 2025): Enhanced analytics, batch operations
  • v1.2.0 (Q3 2025): Multi-token support, advanced oracles
  • v2.0.0 (Q4 2025): Complete API redesign, performance improvements

๐Ÿ”— Version-Specific Resources

Documentation:

Contract Addresses:

  • v1.0.x Mainnet: CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQAHHAGK3HGU
  • v0.9.x Mainnet: CBLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQAHHAGK3ABC

Support Channels:


๐Ÿ”ง Core API Reference

Rustdoc Coverage Contract

All exported contract entrypoints in contracts/predictify-hybrid/src/lib.rs are documented with Rust doc comments (///) and include explicit # Errors and # Events sections.

This is intended to make API behavior auditable without reading all internals:

  • Errors: Each entrypoint documents how Error values are surfaced. Functions returning Result<_, Error> propagate errors directly. Non-Result entrypoints surface contract failures via panic.
  • Events: Each entrypoint documents event behavior. State-changing flows may emit events through internal managers (for example via EventEmitter), while read-only query flows emit no events.

For exact runtime behavior and error variants, also reference:

  • contracts/predictify-hybrid/src/err.rs
  • contracts/predictify-hybrid/src/events.rs

Market Management Functions

create_market()

Creates a new prediction market with specified parameters.

Signature:

pub fn create_market(
    env: Env,
    admin: Address,
    question: String,
    outcomes: Vec<String>,
    duration_days: u32,
    oracle_config: OracleConfig,
) -> Result<Symbol, Error>

Parameters:

  • admin: Market administrator address
  • question: Market question (max 200 characters)
  • outcomes: Possible outcomes (2-10 options)
  • duration_days: Market duration (1-365 days)
  • oracle_config: Oracle configuration for resolution

Returns: Market ID (Symbol)

Example:

const marketId = await contract.create_market(
    adminAddress,
    "Will Bitcoin reach $100,000 by end of 2025?",
    ["Yes", "No"],
    90, // 90 days
    oracleConfig
);

vote()

Submit a vote on a market outcome with stake.

Signature:

pub fn vote(
    env: Env,
    voter: Address,
    market_id: Symbol,
    outcome: String,
    stake: i128,
) -> Result<(), Error>

Parameters:

  • voter: Voter's address
  • market_id: Target market ID
  • outcome: Chosen outcome
  • stake: Stake amount (minimum 0.1 XLM)

Example:

await contract.vote(
    voterAddress,
    "BTC_100K",
    "Yes",
    5000000 // 0.5 XLM in stroops
);

claim_winnings()

Claim winnings from resolved markets.

Signature:

pub fn claim_winnings(
    env: Env,
    user: Address,
    market_id: Symbol,
) -> Result<i128, Error>

Returns: Amount claimed in stroops


๐Ÿ“Š Data Structures

Market

Core market data structure containing all market information.

pub struct Market {
    pub id: Symbol,
    pub question: String,
    pub outcomes: Vec<String>,
    pub creator: Address,
    pub created_at: u64,
    pub deadline: u64,
    pub resolved: bool,
    pub winning_outcome: Option<String>,
    pub total_stake: i128,
    pub oracle_config: OracleConfig,
}

Vote

Represents a user's vote on a market.

pub struct Vote {
    pub voter: Address,
    pub market_id: Symbol,
    pub outcome: String,
    pub stake: i128,
    pub timestamp: u64,
    pub claimed: bool,
}

OracleConfig

Configuration for oracle integration.

pub struct OracleConfig {
    pub provider: OracleProvider,
    pub feed_id: String,
    pub threshold: i128,
    pub timeout_seconds: u64,
}

โš ๏ธ Error Codes

User Operation Errors (100-199)

  • 100: UserNotAuthorized - User lacks required permissions
  • 101: MarketNotFound - Specified market doesn't exist
  • 102: MarketClosed - Market is closed for voting
  • 103: InvalidOutcome - Outcome not available for market
  • 104: AlreadyVoted - User has already voted on this market
  • 105: NothingToClaim - No winnings available to claim
  • 106: MarketNotResolved - Market resolution pending
  • 107: InsufficientStake - Stake below minimum requirement

Oracle Errors (200-299)

  • 200: OracleUnavailable - Oracle service unavailable
  • 201: InvalidOracleConfig - Oracle configuration invalid
  • 202: OracleTimeout - Oracle response timeout
  • 203: OracleDataInvalid - Oracle data format invalid

Validation Errors (300-399)

  • 300: InvalidInput - General input validation failure
  • 301: InvalidMarket - Market parameters invalid
  • 302: InvalidVote - Vote parameters invalid
  • 303: InvalidDispute - Dispute parameters invalid

System Errors (400-499)

  • 400: ContractNotInitialized - Contract requires initialization
  • 401: AdminRequired - Admin privileges required
  • 402: ContractPaused - Contract is paused
  • 403: InsufficientBalance - Account balance too low

๐Ÿ’ก Integration Examples

Basic Market Creation and Voting

import { Contract, Keypair, Networks } from '@stellar/stellar-sdk';

// Initialize contract
const contract = new Contract(contractId);

// Create market
const marketId = await contract.create_market(
    adminKeypair.publicKey(),
    "Will Ethereum reach $5,000 by Q2 2025?",
    ["Yes", "No"],
    120, // 120 days
    {
        provider: "Reflector",
        feed_id: "ETH/USD",
        threshold: 5000000000, // $5,000 in stroops
        timeout_seconds: 3600
    }
);

// Vote on market
await contract.vote(
    userKeypair.publicKey(),
    marketId,
    "Yes",
    10000000 // 1 XLM stake
);

// Check market status
const market = await contract.get_market(marketId);
console.log(`Market: ${market.question}`);
console.log(`Total stake: ${market.total_stake} stroops`);

// Claim winnings (after resolution)
const winnings = await contract.claim_winnings(
    userKeypair.publicKey(),
    marketId
);
console.log(`Claimed: ${winnings} stroops`);

Batch Operations

// Create multiple markets
const markets = await Promise.all([
    contract.create_market(admin, "BTC > $100K?", ["Yes", "No"], 90, btcConfig),
    contract.create_market(admin, "ETH > $5K?", ["Yes", "No"], 90, ethConfig),
    contract.create_market(admin, "SOL > $200?", ["Yes", "No"], 90, solConfig)
]);

// Vote on multiple markets
await Promise.all(
    markets.map(marketId => 
        contract.vote(user, marketId, "Yes", 5000000)
    )
);

๐Ÿ†˜ Troubleshooting Guide

Common Issues and Solutions

๐Ÿ”ง Deployment Issues

Problem: Contract deployment fails with "Insufficient Balance"

Error: Account has insufficient balance for transaction

Solution:

# Check account balance
soroban config identity address
soroban balance --id <your-address> --network mainnet

# Fund account if needed (minimum 100 XLM recommended)
# Use Stellar Laboratory or send from funded account

Problem: WASM file not found during deployment

Error: No such file or directory: target/wasm32-unknown-unknown/release/predictify_hybrid.wasm

Solution:

# Ensure contract is built first
cd contracts/predictify-hybrid
make build

# Verify WASM file exists
ls -la target/wasm32-unknown-unknown/release/

๐Ÿ”ฎ Oracle Integration Issues

Problem: Oracle results not being accepted

Error: InvalidOracleConfig (201)

Solution:

# Verify oracle configuration
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_oracle_config \
  --network mainnet

# Update oracle configuration if needed
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn update_oracle_config \
  --arg provider=Reflector \
  --arg feed_id="BTC/USD" \
  --network mainnet

Problem: Oracle price feeds timing out

Error: OracleUnavailable (200)

Solution:

  1. Check oracle service status
  2. Verify network connectivity
  3. Implement fallback oracle providers
  4. Add retry logic with exponential backoff

๐Ÿ—ณ๏ธ Voting and Market Issues

Problem: User unable to vote

Error: MarketClosed (102)

Solution:

# Check market status and deadline
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_market \
  --arg market_id="BTC_100K" \
  --network mainnet

# Extend market if authorized and appropriate
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn extend_market \
  --arg market_id="BTC_100K" \
  --arg additional_days=7 \
  --network mainnet

Problem: Insufficient stake error

Error: InsufficientStake (107)

Solution:

# Check minimum stake requirements
echo "Minimum vote stake: 1,000,000 stroops (0.1 XLM)"
echo "Minimum dispute stake: 100,000,000 stroops (10 XLM)"

# Verify user balance
soroban balance --id <user-address> --network mainnet

๐Ÿ›๏ธ Dispute Resolution Issues

Problem: Dispute submission rejected

Error: DisputeVotingNotAllowed (406)

Solution:

  1. Verify market is in resolved state
  2. Check dispute window timing (24-48 hours after resolution)
  3. Ensure sufficient dispute stake
  4. Verify user hasn't already disputed

Problem: Dispute threshold too high

Error: ThresholdExceedsMaximum (412)

Solution:

# Check current dispute threshold
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_dispute_threshold \
  --arg market_id="BTC_100K" \
  --network mainnet

# Admin can adjust if necessary
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn update_dispute_threshold \
  --arg market_id="BTC_100K" \
  --arg new_threshold=50000000 \
  --network mainnet

๐Ÿ’ฐ Fee and Payout Issues

Problem: Fee collection fails

Error: NoFeesToCollect (415)

Solution:

# Check if fees are available
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_collectable_fees \
  --arg market_id="BTC_100K" \
  --network mainnet

# Ensure market is resolved and fees haven't been collected

Problem: User cannot claim winnings

Error: NothingToClaim (105)

Solution:

  1. Verify user voted on winning outcome
  2. Check market resolution status
  3. Ensure user hasn't already claimed
  4. Verify market dispute period has ended

๐Ÿ” Debugging Tools

Contract State Inspection

# Get complete market information
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_market_analytics \
  --arg market_id="BTC_100K" \
  --network mainnet

# Check user voting history
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_user_votes \
  --arg user=<address> \
  --network mainnet

# Inspect contract configuration
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn get_config \
  --network mainnet

Transaction Analysis

# View transaction details
soroban events --id $CONTRACT_ID --network mainnet

# Check specific transaction
soroban transaction --hash <tx_hash> --network mainnet

Log Analysis

# Enable verbose logging
export RUST_LOG=debug

# Run with detailed output
soroban contract invoke \
  --id $CONTRACT_ID \
  --fn vote \
  --arg market_id="BTC_100K" \
  --arg outcome="yes" \
  --arg stake=5000000 \
  --network mainnet \
  --verbose

๐Ÿ“ž Support and Resources

Error Code Reference

  • 100-199: User operation errors - Check user permissions and market state
  • 200-299: Oracle errors - Verify oracle configuration and connectivity
  • 300-399: Validation errors - Check input parameters and formats
  • 400-499: System errors - Contact support for system-level issues

Support Channels

  1. GitHub Issues: Report bugs and request features
  2. Discord Support: #technical-support channel
  3. Developer Forum: Technical discussions
  4. Email Support: [email protected]

Before Contacting Support

  1. Check this troubleshooting guide
  2. Search existing GitHub issues
  3. Verify your environment and configuration
  4. Collect relevant error messages and transaction hashes
  5. Note your contract version and network

Additional Resources


๐Ÿ›ก๏ธ Validation Module

The validation module (contracts/predictify-hybrid/src/validation.rs) provides layered, composable validators for every contract operation. Each validator returns a ValidationResult or a Result<(), ValidationError> and can be used independently or composed through ComprehensiveValidator.

Validators

Validator Responsibility
InputValidator Primitives: string length, numeric range, array size, address format, timestamps
MarketValidator Market lifecycle guards: creation params, voting eligibility, resolution eligibility, fee collection eligibility
OracleValidator Oracle config fields: provider support, comparison operator, result presence and format
FeeValidator Fee config integrity: percentage bounds (0โ€“100), min/max fee amounts, collection threshold
VoteValidator Vote correctness: outcome membership, stake โ‰ฅ MIN_VOTE_STAKE, duplicate detection
DisputeValidator Dispute correctness: winning outcome required, stake โ‰ฅ MIN_DISPUTE_STAKE, duplicate detection
EventValidator Event creation: admin address, description format, outcome count (2โ€“10), future end time
OracleConfigValidator Deep oracle config: provider-specific threshold ranges, comparison operator support per provider, resolution timeout bounds
MarketParameterValidator Standalone parameter ranges: duration (days), stake amounts, threshold values
ConfigValidator Contract-level config: admin/token addresses, config::Environment values
ComprehensiveValidator Orchestrates the above validators for full market creation and state checks

Key Constants

Constant Value Used by
MIN_VOTE_STAKE 1,000,000 stroops VoteValidator
MIN_DISPUTE_STAKE 10,000,000 stroops DisputeValidator
MIN_FEE_AMOUNT 1,000,000 FeeValidator
MAX_FEE_AMOUNT 1,000,000,000 FeeValidator
FEE_COLLECTION_THRESHOLD 100,000,000 MarketValidator
MIN_MARKET_DURATION_DAYS 1 MarketValidator, MarketParameterValidator
MAX_MARKET_DURATION_DAYS 365 MarketValidator, MarketParameterValidator
MIN_MARKET_OUTCOMES 2 InputValidator, MarketValidator
MAX_MARKET_OUTCOMES 10 InputValidator, MarketValidator
MIN_QUESTION_LENGTH 10 chars InputValidator
MAX_QUESTION_LENGTH 500 chars InputValidator
MIN_OUTCOME_LENGTH 2 chars InputValidator
MAX_OUTCOME_LENGTH 100 chars InputValidator

Known Limitations

OracleConfigValidator::validate_config_consistency / validate_oracle_config_all_together with Reflector or Pyth providers โ€” the private get_supported_operators_for_provider helper creates multiple independent soroban_sdk::Env::default() instances inside a single vec![] call. Strings built against different Env instances cannot be compared safely in the test harness and cause SIGSEGV. Affected public paths (MarketValidator::validate_market_creation, ComprehensiveValidator::validate_complete_market_creation) must not be exercised with Reflector/Pyth configs in unit tests until this upstream SDK usage is corrected. Individual field validators (question, duration, outcomes, resolution timeout) remain fully testable.

Test Coverage Summary

All 118 unit tests in contracts/predictify-hybrid/src/validation_tests.rs pass (cargo test -p predictify-hybrid --lib "validation_tests"). Coverage includes:

  • Every InputValidator branch (string length, numeric range, array bounds, address format, timestamp, outcomes, tags, description, category, outcome format)
  • MarketValidator lifecycle guards (voting, resolution, fee collection โ€” active, ended, and empty-question paths)
  • OracleValidator (provider, comparison operator, result presence, result-against-outcomes)
  • FeeValidator (valid config, invalid percentage, min > max, zero threshold)
  • VoteValidator (valid vote, too-low stake, invalid outcome, duplicate vote)
  • DisputeValidator (valid dispute, no winning outcome, too-low stake, duplicate dispute)
  • EventValidator (valid creation, short description, past end time, too-few/too-many outcomes)
  • OracleConfigValidator (provider support, threshold range, feed ID format, comparison operator, resolution timeout, BandProtocol/DIA always-fail paths)
  • MarketParameterValidator (duration limits, stake amounts, threshold values)
  • ConfigValidator (contract config, all Environment variants)
  • ComprehensiveValidator (input validation, market state โ€” active and empty-question)
  • ValidationResult and ValidationError helpers

Last Updated: 2026-03-25 API Version: v1.0.0 Documentation Version: 1.1