Thales Protocol Documentation
  • ℹ️Introduction to Thales Protocol
  • 🏗️Foundational Architecture of Thales
  • ❔Frequently Asked Questions (FAQ)
  • 📜The Story of Thales from Miletus
  • 🛠️For Developers
  • ⚽Thales Sports Markets
    • Revolutionizing Sports Markets
    • Thales Sports Markets Architecture
      • Game Market Smart Contract
      • SportsAMM Smart Contract
      • ParlayAMM Smart Contract
      • Liquidity Providing Smart Contracts
    • Singles Market Making
    • Parlays Market Making
    • Onchain Sports Odds
    • Sports Markets Liquidity Providing
    • Sports Markets Integration
  • 📈Thales Digital Options
    • Introduction to Thales Digital Options
    • Mechanics of Tokenized Digital Options
    • How Thales AMM works
    • Digital Options Liquidity Providing
    • Digital Options Integration
  • ⚡Thales Speed Markets
    • Introduction to Speed Markets
    • Chained Speed Markets
    • Speed Markets Integration
    • Speed Markets Trading Guide
    • Speed Market Deposit Guides
      • Deposit USDC from Coinbase
      • Deposit from Binance Mobile App
      • Deposit from Binance Website
  • 🔵THALES Token
    • THALES Token Info
    • THALES Token Distribution
    • Staking Guide
    • Automate staking with Chainlink Automation
    • Automate staking with Gelato Functions
    • Real Yield
  • ⚖️Governance
    • Thales Governance Structure
    • Thales Improvement Proposals (TIPs)
  • Links
    • Thales Protocol Blog
    • Thales Protocol Discord
    • Thales Protocol Twitter
  • 🗃️Resources
    • Thales Protocol Smart Contract List
    • Thales Media Kit
    • Thales Whitepaper (2021)
    • Smart Contract Audits
Powered by GitBook
On this page
  • Overtime API
  • Contract integration
  • Buy a single
  • Buy a parlay
  1. Thales Sports Markets

Sports Markets Integration

Last updated 10 months ago

Overtime API

In order to ensure easy integration with third party applications, Overtime API is created. API returns all main data available on Overtime. Using Overtime API endpoints someone can get data about:

  • Overtime sports

  • Overtime collaterals

  • Overtime markets

  • Overtime market

  • User Overtime positions

  • User Overtime transactions

  • Single quote

  • Parlay quote

More details about each API endpoint with request/response examples can be found under .

Contract integration

Once all data are fetched from API, the next step is integration with Overtime contracts. Depending on whether someone wants to buy a single or a parlay, integration should be done with or .

The next sections describe integration with Overtime API and Overtime contracts together with JS code examples.

Buy a single

Let's say someone wants to buy positional tokens on Chelsea for the game Chelsea - Liverpool with a buy-in amount of 100 sUSD.

Integration with Overtime API and Sports AMM contract should include the following steps:

  1. Get a quote for a single market from Overtime API

  2. Create Sports AMM contract instance

  3. Call buyFromAmm method on Sports AMM contract with input parameters fetched from Overtime API in step #1

The JS code snippet below implements these steps:

import { ethers } from "ethers";
import w3utils from "web3-utils";
import axios from "axios";
import dotenv from "dotenv";
import sportsAMMContractAbi from "./SportsAMMContractAbi.js"; // SportsAMM contract ABI

dotenv.config();

const API_URL = "https://overtimemarketsv2.xyz"; // base API URL
const NETWORK_ID = 10; // optimism network ID
const NETWORK = "optimism"; // optimism network
const SPORTS_AMM_CONTRACT_ADDRESS =
  "0x170a5714112daEfF20E798B6e92e25B86Ea603C1"; // SportsAMM contract address on optimism
const MARKET_ADDRESS = "0xb157e64720d3ff251023119a5f6557067763b08a"; // address od market Chelsea - Liverpool
const POSITION = 0; // select Chelsea position
const BUY_IN = 100; // 100 sUSD
const SLIPPAGE = 0.02; // slippage 2%

// create instance of Infura provider for optimism network
const provider = new ethers.providers.InfuraProvider(
  { chainId: Number(NETWORK_ID), name: NETWORK },
  process.env.INFURA
);

// create wallet instance for provided private key and provider
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

// create instance of Sports AMM contract
const sportsAMM = new ethers.Contract(
  SPORTS_AMM_CONTRACT_ADDRESS,
  sportsAMMContractAbi,
  wallet
);

const buyFromAmm = async () => {
  try {
    // get a quote from Overtime API for provided market, position and buy-in amount on optimism network
    const quoteResponse = await axios.get(
      `${API_URL}/overtime/networks/${NETWORK_ID}/markets/${MARKET_ADDRESS}/quote?position=${POSITION}&buyIn=${BUY_IN}`
    );
    const quoteData = quoteResponse.data;
    console.log("Quote data", quoteData);

    // convert payout got from API to BigNumber
    const parsedPayout = ethers.utils.parseEther(quoteData.payout.toString());
    // convert actual buy-in amount got from API to BigNumber
    // actualBuyInCollateralAmount is different from BUY_IN due to the contract architecture having positions amount as input and not buy-in amount
    const parsedActualBuyInCollateralAmount = ethers.utils.parseEther(
      quoteData.actualBuyInCollateralAmount.toString()
    );
    // convert slippage tolerance to BigNumber
    const parsedSlippage = ethers.utils.parseEther(SLIPPAGE.toString());

    // call buyFromAMM method on Sports AMM contract
    const tx = await sportsAMM.buyFromAMM(
      MARKET_ADDRESS,
      POSITION,
      parsedPayout,
      parsedActualBuyInCollateralAmount,
      parsedSlippage,
      {
        type: 2,
        maxPriorityFeePerGas: w3utils.toWei("0.00000000000000001"),
      }
    );
    // wait for the result
    const txResult = await tx.wait();
    console.log(
      `Successfully bought from AMM. Transaction hash: ${txResult.transactionHash}`
    );
  } catch (e) {
    console.log("Failed to buy from AMM", e);
  }
};

buyFromAmm();

Buy a parlay

Let's say someone wants to buy a 4-game parlay with a buy-in amount of 100 sUSD.

  1. Get a quote for a parlay from Overtime API

  2. Create Parlay AMM contract instance

  3. Call buyFromParlay method on Parlay AMM contract with input parameters fetched from Overtime API in step #1

The JS code snippet below implements these steps:

import { ethers } from "ethers";
import w3utils from "web3-utils";
import axios from "axios";
import dotenv from "dotenv";
import parlayAMMContractAbi from "./parlayAMMContractAbi.js"; // ParlayAMM contract ABI

dotenv.config();

const API_URL = "https://overtimemarketsv2.xyz"; // base API URL
const NETWORK_ID = 10; // optimism network ID
const NETWORK = "optimism"; // optimism network
const PARLAY_AMM_CONTRACT_ADDRESS =
  "0x82B3634C0518507D5d817bE6dAb6233ebE4D68D9"; // ParlayAMM contract address on optimism
const MARKETS = [
  "0xb157e64720d3ff251023119a5f6557067763b08a",
  "0xbf1e460b82308cb76d5918377eb03ac7a3c33a43",
  "0xa73553b23799ae0e8743771a79d26cb196eca892",
  "0x91300647b7bc3b698fd2e841d26cdfc61a4145ed",
]; // market addresses
const POSITIONS = [0, 1, 0, 0]; // market positions
const BUY_IN = 100; // 100 sUSD
const SLIPPAGE = 0.02; // slippage 2%
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; // pass as a differentRecipient parameter for the buyFromParlay method

// create instance of Infura provider for optimism network
const provider = new ethers.providers.InfuraProvider(
  { chainId: Number(NETWORK_ID), name: NETWORK },
  process.env.INFURA
);

// create wallet instance for provided private key and provider
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

// create instance of Parlay AMM contract
const parlayAMM = new ethers.Contract(
  PARLAY_AMM_CONTRACT_ADDRESS,
  parlayAMMContractAbi,
  wallet
);

const buyFromParlay = async () => {
  try {
    // get a quote from Overtime API for provided market addresses, market positions and buy-in amount on optimism network
    const quoteResponse = await axios.get(
      `${API_URL}/overtime/networks/${NETWORK_ID}/parlay/quote?markets=${MARKETS.join(
        ","
      )}&positions=${POSITIONS.join(",")}&buyIn=${BUY_IN}`
    );
    const quoteData = quoteResponse.data;
    console.log("Quote data", quoteData);

    // convert payout got from API to BigNumber
    const parsedPayout = ethers.utils.parseEther(quoteData.payout.toString());
    // convert buy-in amount to BigNumber
    const parsedBuyInAmount = ethers.utils.parseEther(BUY_IN.toString());
    // convert slippage tolerance to BigNumber
    const parsedSlippage = ethers.utils.parseEther(SLIPPAGE.toString());

    // call buyFromParlay method on Parlay AMM contract
    const tx = await parlayAMM.buyFromParlay(
      MARKETS,
      POSITIONS,
      parsedBuyInAmount,
      parsedSlippage,
      parsedPayout,
      ZERO_ADDRESS,
      {
        type: 2,
        maxPriorityFeePerGas: w3utils.toWei("0.00000000000000001"),
      }
    );
    // wait for the result
    const txResult = await tx.wait();
    console.log(
      `Successfully bought from Parlay AMM. Transaction hash: ${txResult.transactionHash}`
    );
  } catch (e) {
    console.log("Failed to buy from Parlay AMM", e);
  }
};

buyFromParlay();

Get a Sports AMM contract address for a specific network from

Get a Sports AMM contract ABI from Overtime contract repository

Get a Parlay AMM contract address for a specific network from

Get a Parlay AMM contract ABI from Overtime contract repository

⚽
Postman documentation
Sports AMM Smart Contract
Parlay AMM Smart Contract
Thales contracts
contract repository
Thales contracts
contract repository