LogoLogo
  • Overview
    • Introduction
    • Table of Contents
  • Token Information
    • Symmio Foundation
  • Protocol Architecture
    • Protocol Introduction
    • Technical Documentation
      • Building an Application with SYMM
        • Introduction and Diamond Explainer
        • Querying Info from the SYMM Diamond
        • MultiAccount
        • Creating an Account and Depositing Funds
        • Sending a Quote
        • Closing a Quote
        • Instant Trading
          • Instant Login (EOA)
          • Instant Login (Account Abstraction)
          • Sending a Quote (Instant Open)
          • Sending a Quote (Instant Close)
        • Frequently Used Queries
      • Solver Docs
        • Solver Docs (github)
        • Solver Implementation Guide (High Level Overview)
        • Building a Solver on SYMMIO
          • 1. Intent Creation
          • 2. Seeing the Intent
          • 3. Hedging Off-Chain
          • 4. Opening/Closing a Position On-Chain
          • Creating the APIs
            • GET Contract Symbols
            • GET Open Interest
            • GET Notional Cap
            • GET Price Range
            • GET Error Codes
            • GET Get Locked Params
            • GET Get Funding Info
            • POST Position State
          • Solver Flow Summary Example
          • Recommended Architecture for Solvers
          • Glossary
        • Conditional Orders Handler
        • Rasa Solver TP/SL Implementation
        • Instant Trading
          • Instant Trading (Solvers)
          • Rasa Instant Trading Implementation
          • Instant Trading Condition Checks
        • Fetching Gas Prices Script
        • How to Add a Market as a Solver
        • Verifying Account Abstracted Instant Actions (ERC-4337)
      • Frontend Docs
        • Setting up a Frontend with SYMMIO
        • Frontend SDK Setup Guide
        • MultiAccount Deployment Guide
        • Instant Trading (Frontends)
          • Account Abstracted Instant Actions (Frontends)
        • Implement a Trading Bot on Symmio (OLD)
          • Setup
          • Creating a Sub-Account
          • Minting Collateral Tokens (Optional)
          • Depositing and Allocating Tokens
          • Obtaining Muon Signatures
          • Sending a Quote
          • Monitoring Price for Execution
      • Contract Docs
        • SYMMIO CORE v0.82
        • Contracts Documentation 0.8.2
          • Main Flow
          • The SYMM Diamond
          • Facets
            • Account Facet
            • Control Facet
            • Funding Rate Facet
            • PartyA Facet
            • PartyB Facet
            • Liquidation Facet
            • View Facet
          • MultiAccount
            • PartyA
            • PartyB
          • SYMM App (Muon)
            • LibMuon
            • MuonStorage
        • Contracts Documentation 0.8.3
          • Facets
            • Control Facet
            • Account Facet
            • PartyA Facet
            • PartyB Facet
            • View Facet
            • Bridge Facet
            • Liquidation Facet (Implementation)
          • Modified Events
          • New Events
          • MuonStorage
        • Contracts Documentation 0.8.4
          • Main Flow (0.8.4)
          • The SYMM Diamond (0.8.4)
          • Facets
            • Account Facet (0.8.4)
            • Bridge Facet (0.8.4)
            • Control Facet (0.8.4)
            • Force Actions Facet (0.8.4)
            • Funding Rate Facet (0.8.4)
            • Liquidations Facet (0.8.4)
            • PartyA Facet (0.8.4)
            • PartyB Group Actions Facet (0.8.4)
            • PartyB Quote Actions Facet (0.8.4)
            • PartyB Position Actions Facet (0.8.4)
            • Settlement Facet (0.8.4)
            • View Facet (0.8.4)
          • MultiAccount (0.8.4)
            • SymmioPartyA
            • SymmioPartyB
          • SYMM App (Muon)
            • LibMuon (0.8.4)
            • MuonStorage (0.8.4)
      • Contract Addresses / Solver Endpoints
        • Mantle
        • Mode
        • IOTA
        • Base
        • BSC
        • Arbitrum
        • Polygon
        • Berachain
        • Solver Endpoints and Addresses
          • Perps Hub
          • Rasa Capital
          • Rasa Capital (Zero Spread)
          • Zenith
      • How to Query our Contracts
      • Muon API Queries
      • Solver Error Codes
      • Interacting with SYMMIO Contracts
    • Protocol higher level architecture
      • 12-Hour Fraud Proof Window
      • PartyB
      • Solver Settings
      • Max Leverage
      • Maintenance Margin (CVA) Calculations
    • Symmio Whitepaper
  • Building on Symmio
    • Builders introduction
    • Solving for Symmio
      • Solver documentation
      • Solver - Example Flow
    • Trading Fees
      • Perps - Settlement Costs
      • Pair Trading - Settlement costs
    • Exchanges (Frontends)
      • Frontend Introduction
      • SDK - SYMM client
      • Trade on Symmio
  • Legal & Brand & Security
    • Security (Audits / Bugbounty)
      • Bug bounty / Coverage
        • How to contact ?
      • Audits
        • SYMM - V0.8 - 0.81
          • Sherlock Audit - Jun 15, 2023
          • Smart State - Jul 2, 2023
        • SYMM - 0.82
          • Sherlock Audit -Aug 30, 2023
        • SYMM - 0.83
          • Sherlock Audit - Jun 17, 2024
        • SYMM - 0.84
          • Sherlock Audit - Oct 3, 2024
        • Vaults
          • Sherlock Audit - Jan 2, 2024
    • Terms of Service & Licensing
      • TRADEMARK & COPYRIGHT NOTICE
      • CONTACT US
      • TERMS OF SERVICE
      • FRONTEND LICENSE
        • Frontend Modifications
        • Frontend Use Grants
      • CONTRACT LICENSE
        • Contract Use Grants
        • Contract Modifications
    • Brand - Assets Logos
Powered by GitBook
LogoLogo

All rights to the people (c) 2023 Symmetry Labs A.G.

On this page
  • Making a HTTP Request
  • Base Client
  • Overview
  • Sending a Request
  • Creating the Quotes Client
  • Constructor
  • Creating an Instance
  • Obtaining the Muon Signature
  • Getting Request Params
  • Implementing for Sending a Quote
  1. Protocol Architecture
  2. Technical Documentation
  3. Frontend Docs
  4. Implement a Trading Bot on Symmio (OLD)

Obtaining Muon Signatures

For sensitive functions like opening and closing a trade, Muon signatures are required to be passed and verified on the contracts to verify the user's upnl and the price of an asset. This is done through a series of processes. For a trading bot, we'll structure Muon queries into three main parts: HTTP utility functions, a base client for handling requests to the Muon network, and a specialized client for fetching quotes and signatures.

Making a HTTP Request

The HTTP utility module provides a basic functionality to make HTTP GET requests using axios, a promise-based HTTP client.

const axios = require('axios');

const makeHttpRequest = async function(url, options = {}) {
  try {
    const response = await axios.get(url, {
      headers: {
        'Cache-Control': 'no-cache',
      }
    });
    return response.data; 
  } catch (err) {
    console.error(`Error fetching ${url}: `, err.message); 
    return null; 
  }
};

module.exports = { makeHttpRequest };

This code snippet sends an HTTP GET request to a specified URL and returns the response data. We'll export this module and use it in the base client.

Base Client

Overview

MuonClient serves as the base class for making requests to the Muon network. It constructs URLs with appropriate parameters for the network requests. Here's how you can set up a base client, which will be used by extended classes to carry out specific queries to Muon.

Parameters:

  • options (Object): Configuration options for the Muon client. Includes APP_METHOD to specify the method for the Muon application.

const { makeHttpRequest } = require("../utils/http");

class MuonClient {
  constructor(options) {
    this.APP_METHOD = options.APP_METHOD;
  }
  //Code
}

Here's a full list of the App Methods you can use to query Muon:

  • 'uPnl_A': Returns the uPnl of partyA.

  • **'partyA_overview':**Returns an the prices of partyA's assets upon liquidation.

  • 'verify': Returns liquidation signatures.

  • **'uPnl_A_withSymbolPrice':**Returns partyA's uPnl with the price of a symbol.

  • **'uPnl_B':**Returns partyB's uPnl.

  • **'uPnl':**Returns the uPnl of both parties at a timestamp.

  • 'uPnlWithSymbolPrice': Returns both parties' uPnl with a symbol price.

  • 'price': Returns an array of prices from an array of quotes.

Sending a Request

The _sendRequest() function constructs a request URL with the given parameters and sends an HTTP GET request to the Muon network.

Parameters:

  • baseUrl (String): The base URL for the Muon network endpoint.

  • appName (String): The name of the application making the request ("symmio")

  • requestParams (Array): A list of parameters required for the request, structured as key-value pairs.

  async _sendRequest(baseUrl, appName, requestParams) {
    const MuonURL = new URL(baseUrl);
    MuonURL.searchParams.set("app", appName);
    MuonURL.searchParams.append("method", this.APP_METHOD);
    requestParams.forEach((param) => {
      MuonURL.searchParams.append(`params[${param[0]}]`, param[1]);
    });
    console.log('Request URL:', MuonURL.href);

    try {
      const response = await makeHttpRequest(MuonURL.href);
      return { result: response, success: true }; 
    } catch (error) {
      console.error(`Error during request to ${baseUrl}:`, error);
      return { success: false, error }; 
    }
  }
}

Returns: An object indicating the success of the request and containing the result or error information.

Finally we'll export this class:

module.exports = { MuonClient };

Creating the Quotes Client

The QuotesClient class extends MuonClient to interact with the Muon network for the purpose of fetching the price of a symbol with the upnl of partyA. In order to send a quote, the signature received must be verified on SYMM's contracts.

Constructor

Initializes the QuotesClient with a predefined application method.

class QuotesClient extends MuonClient {
  constructor() {
    super({ APP_METHOD: "uPnl_A_withSymbolPrice" });
  }
  • APP_METHOD: Set to "uPnl_A_withSymbolPrice", specifying the Muon network method to be used for fetching quotes and signatures related to unrealized profit and loss (uPnl) and symbol price.

Creating an Instance

  static createInstance(isEnabled) {
    if (isEnabled) {
      return new QuotesClient();
    }
    return null;
  }

A static factory method to conditionally create an instance of QuotesClient.

Parameters:

  • isEnabled (Boolean): A flag to determine whether an instance should be created.

Returns:

  • An instance of QuotesClient if isEnabled is true.

  • null if isEnabled is false.

Obtaining the Muon Signature

The getMuonSig() function fetches a cryptographic signature from the Muon network based on provided parameters. It formats the generated signature so it can be passed to the contract without causing errors.

  async getMuonSig(
    account, 
    appName, 
    urls, 
    chainId, 
    contractAddress, 
    marketId) {
    try {
      //creating the request
      const requestParams = this._getRequestParams(account, chainId, contractAddress, marketId);
      if (requestParams instanceof Error) throw requestParams;
      let result, success;
      for (const url of urls) {
        try {
          const res = await this._sendRequest(url, appName, requestParams);
          if (res && res.success) {
            result = res.result;
            success = true;
            break; 
          }
        } catch (error) {
          console.log("Retrying with the next URL...");
        }
      }

      if (success) {
        const reqId = result.result.reqId;
        const timestamp = result.result.data.timestamp ? BigInt(result.result.data.timestamp) : BigInt(0);
        console.log("timestamp: ", timestamp);
        const upnl = result.result.data.result.uPnl ? BigInt(result.result.data.result.uPnl) : BigInt(0);
        const price = result.result.data.result.price ? BigInt(result.result.data.result.price) : BigInt(0);
        const gatewaySignature = result.result.nodeSignature;
        const signature = result.result.signatures[0].signature ? BigInt(result.result.signatures[0].signature) : BigInt(0);
        const owner = result.result.signatures[0].owner;
        const nonce = result.result.data.init.nonceAddress;

        //formatting the generatedSignature
        const generatedSignature = {
          reqId,
          timestamp,
          upnl,
          price: price ? price : toWei(0),
          gatewaySignature,
          sigs: { signature, owner, nonce },
        };
        //returning the signature
        return { success: true, signature: generatedSignature };
        
      } else {
        throw new Error("Muon request unsuccessful");
      }
    } catch (error) {
      console.error(error);
      return { success: false, error };
    }
  }

Parameters:

  • account (String): The subAccount address.

  • appName (String): The name of the Muon app ("symmio")

  • urls (Array): An array of URLs for the Muon network endpoints to try in sequence.

  • chainId (Number): The blockchain chain ID.

  • contractAddress (String): The address of the Diamond contract.

  • marketId (Number): A unique identifier for the market.

Returns: A promise that resolves to an object with two properties:

  • success (Boolean): Indicates whether the request was successful.

  • signature (Object): The signature data, available only if success is true.

  • error (String): An error message, available only if success is false.

Getting Request Params

This is a helper function to make sure all fields for the Muon request are filled. It constructs the request parameters required by the Muon network.

_getRequestParams(account, chainId, contractAddress, marketId) {
    if (!account) return new Error("Param `account` is missing.");
    if (!chainId) return new Error("Param `chainId` is missing.");
    if (!contractAddress) return new Error("Param `contractAddress` is missing.");
    if (!marketId) return new Error("Param `marketId` is missing.");

    return [
      ["partyA", account],
      ["chainId", chainId.toString()],
      ["symmio", contractAddress],
      ["symbolId", marketId.toString()],
    ];
  }

Parameters:

  • The same as for getMuonSig.

Returns:

  • An array of key-value pairs representing the request parameters.

  • An Error object if any parameter is missing.

Finally we'll export the QuotesClient so it can be used in our main code:

module.exports = QuotesClient;

Implementing for Sending a Quote

Here's how you can implement the getMuonSig() function in the main bot (using pre-defined values).

async function getMuonSigImplementation(botAddress) {
  const quotesClient = QuotesClient.createInstance(true);

  if (!quotesClient) {
      console.log('QuotesClient is not enabled or failed to instantiate.');
      return { success: false, error: 'QuotesClient initialization failed' };
  }

  const account = botAddress;
  const appName = 'symmio';
  const urls = [process.env.MUON_URL];
  const chainId = 137;
  const contractAddress = config.DIAMOND_ADDRESS;
  const marketId = 4;

  try {
    const result = await quotesClient.getMuonSig(account, appName, urls, chainId, contractAddress, marketId);

    if (result.success) {
      console.log('Successfully retrieved Muon signature:', result.signature);
      return { success: true, signature: result.signature };
    } else {
      throw new Error(result.error || 'Unknown error');
    }
  } catch (error) {
    console.error('Error getting Muon signature:', error);
    return { success: false, error: error.toString() };
  }
}
PreviousDepositing and Allocating TokensNextSending a Quote

Last updated 11 months ago