Sample MuonApp 1: Simple Oracle

Here is a sample MuonApp for a simple oracle app. This MuonApp, named simple_oracle, fetches real-time token price data from the Coinbase API and and prepares it for signing by Muon nodes. It supports fetching ETH/USD prices directly (eth-price) or the price of any supported token in any fiat or crypto unit (price). The app structures the fetched data into a standardized format and defines signing parameters to ensure consistent and verifiable outputs across the Muon network.

const { axios } = MuonAppUtils

module.exports = {
  APP_NAME: 'simple_oracle',

  onRequest: async function(request){
    let {
      method,
      data: { params }
    } = request;
    switch (method) {
      case 'eth-price':
        var response = await axios
          .get('https://api.coinbase.com/v2/exchange-rates?currency=ETH')
        var price = parseInt(response.data.data.rates.USD)
        return { price }
      case 'price':
        let { token, unit } = params
        var response = await axios.get(`https://api.coinbase.com/v2/exchange-rates?currency=${token}`)
        var price = parseInt(response.data.data.rates[unit])
        return { price }

      default:
        throw `Unknown method ${method}`
    }
  },

  signParams: function(request, result){
    let {
      method,
      data: { params }
    } = request
    let { price } = result;
    let { token, unit } = params

    switch (method) {
      case 'eth-price':
        return [
          { type: 'uint32', value: price }
        ]
      case 'price':
        return [
          { type: 'uint32', value: price },
          { type: 'string', value: token },
          { type: 'string', value: unit },
        ]

      default:
        throw `Unknown method '${method}'`
    }
  }
}

Code Breakdown

There are two main functions in this code: onRequest and signParam.

  1. onRequest(request)

onRequest: async function(request){
    let {
      method,
      data: { params }
    } = request;
    switch (method) {
      case 'eth-price':
        var response = await axios
          .get('https://api.coinbase.com/v2/exchange-rates?currency=ETH')
        var price = parseInt(response.data.data.rates.USD)
        return { price }
      case 'price':
        let { token, unit } = params
        var response = await axios.get(`https://api.coinbase.com/v2/exchange-rates?currency=${token}`)
        var price = parseInt(response.data.data.rates[unit])
        return { price }

      default:
        throw `Unknown method ${method}`
    }
  },

This function handles incoming requests. It extracts the method and any params passed in the request and performs the appropriate action:

  • Method: eth-price

    • Calls Coinbase API for ETH exchange rates.

    • Extracts the USD price and returns it.

  • Method: price

    • Extracts the token (e.g., ETH, BTC) and unit (e.g., USD, EUR).

    • Calls Coinbase API for the token's exchange rates.

    • Extracts the value in the given unit and returns it.

  • Fallback

    • Throws an error if the method is unrecognized.

  1. signParams(request, result)

signParams: function(request, result){
    let {
      method,
      data: { params }
    } = request
    let { price } = result;
    let { token, unit } = params

    switch (method) {
      case 'eth-price':
        return [
          { type: 'uint32', value: price }
        ]
      case 'price':
        return [
          { type: 'uint32', value: price },
          { type: 'string', value: token },
          { type: 'string', value: unit },
        ]

      default:
        throw `Unknown method '${method}'`
    }
  }
}

This function defines the data structure to be signed by the Muon network. The structure depends on the request method:

  • For eth-price

    • Only includes the price as a uint32.

  • For price

    • Includes the price (uint32), token (string), and unit (string).

This makes sure the signed message includes the necessary context for validation.

Last updated