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
  • Instant Close Flow
  • Explanation
  1. Protocol Architecture
  2. Technical Documentation
  3. Building an Application with SYMM
  4. Instant Trading

Sending a Quote (Instant Close)

PreviousSending a Quote (Instant Open)NextFrequently Used Queries

Last updated 2 months ago

Instant closes let you immediately close a position by calling the /instant_close endpoint. You must first obtain a SIWE access token via a login flow if you don't have one already, then use that token to call the instant close function.

Instant Trading is only for MARKET orders


Instant Close Flow

Instant close allows you to quickly exit an open position. The process requires:

  1. (if you don't have an access token already) Fetch a nonce from the solver’s endpoint, build and sign a SIWE (Sign-In with Ethereum) message, and then log in to obtain an access token.

  2. Call the /Endpoint: With the access token, send a POST request that includes:

    • quote_id: The unique number identifying the quote/position.

    • quantity_to_close: The amount (as a string) you wish to close.

    • close_price: The price (as a string) at which you want to close the position.

For market orders, you will need to adjust the close price (i.e. ) similar to the opening process. For CLOSE LONG: Decrease the price by your slippage factor.

For CLOSE SHORT: Increase the price by your slippage factor.

The following script shows a full example in Node.js using Axios and ethers.js, closing a LONG XRP position.


Instant Close Script Example

require("dotenv").config();
const { ethers } = require("ethers");
const axios = require("axios");

// --------------------------------------------------------------------
// SIWE / Login Configuration
// --------------------------------------------------------------------
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const activeAccount = process.env.activeAccount; // Your sub-account address
const wallet = new ethers.Wallet(PRIVATE_KEY);

const SOLVER_BASE_URL = "https://www.perps-streaming.com/v1/42161a/0x141269E29a770644C34e05B127AB621511f20109";
const DOMAIN = "localhost";
const ORIGIN = "http://localhost:3000";
const CHAIN_ID = 42161;
const LOGIN_URI = `${SOLVER_BASE_URL}/login`;
const ISSUED_AT = new Date().toISOString();
// Set expiration to 24 hours from now for login
const EXPIRATION_DATE = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();

// --------------------------------------------------------------------
// Helper Functions
// --------------------------------------------------------------------

// SIWE message builder (EIP-4361 format)
function buildSiweMessage({ domain, address, statement, uri, version, chainId, nonce, issuedAt, expirationTime }) {
  return `${domain} wants you to sign in with your Ethereum account:
${address}

${statement}

URI: ${uri}
Version: ${version}
Chain ID: ${chainId}
Nonce: ${nonce}
Issued At: ${issuedAt}
Expiration Time: ${expirationTime}`;
}

// Fetch nonce for SIWE login
async function getNonce(address) {
  const url = `${SOLVER_BASE_URL}/nonce/${address}`;
  const { data } = await axios.get(url);
  return data.nonce;
}

// Fetch the asset price from Muon, convert the returned wei value to a standard decimal string.
async function fetchMuonPriceConverted() {
  try {
    const MUON_URL = ""; //This is the uPnL_A_WithSymbolPrice Muon API request.
    const response = await axios.get(MUON_URL);
    const fetchedPriceWei = response.data.result.data.result.price;
    if (!fetchedPriceWei) {
      throw new Error("Muon price not found in response.");
    }
    // Convert the wei value to a human-readable decimal (assumes 18 decimals)
    const priceDecimal = ethers.formatUnits(fetchedPriceWei, 18);
    return priceDecimal;
  } catch (error) {
    console.error("Error fetching Muon price:", error.response?.data || error.message);
    throw error;
  }
}

// Call the /instant_close endpoint to close a position.
// The endpoint expects an object with:
//   {
//     "quote_id": number,
//     "quantity_to_close": "string",
//     "close_price": "string"
//   }
async function closeInstantPosition(token, quote_id, quantity_to_close, close_price) {
  const payload = {
    quote_id,            // Example: 23688
    quantity_to_close,   // Example: "6.1"
    close_price,         // Example: "2.3"
  };

  const headers = {
    "Content-Type": "application/json",
    Authorization: `Bearer ${token}`,
  };

  const response = await axios.post(`${SOLVER_BASE_URL}/instant_close`, payload, { headers });
  return response.data;
}

// --------------------------------------------------------------------
// Main Flow: SIWE Login then Instant Close Trade
// --------------------------------------------------------------------
(async function main() {
  try {
    console.log(`\n[1/4] Wallet Address: ${wallet.address}`);
    const nonce = await getNonce(activeAccount);
    console.log(`[2/4] Got nonce: ${nonce}`);

    // Build the SIWE message.
    const siweMessage = buildSiweMessage({
      domain: DOMAIN,
      address: wallet.address,
      statement: `msg: ${activeAccount}`,
      uri: LOGIN_URI,
      version: "1",
      chainId: CHAIN_ID,
      nonce,
      issuedAt: ISSUED_AT,
      expirationTime: EXPIRATION_DATE,
    });
    console.log("\n[3/4] SIWE message to sign:\n", siweMessage);

    // Sign the SIWE message.
    const signature = await wallet.signMessage(siweMessage);
    console.log("\nSignature:", signature);

    // Build the login request body.
    const loginBody = {
      account_address: activeAccount,
      expiration_time: EXPIRATION_DATE,
      issued_at: ISSUED_AT,
      signature,
      nonce,
    };

    const loginHeaders = {
      "Content-Type": "application/json",
      Origin: ORIGIN,
      Referer: ORIGIN,
    };

    console.log("\n[4/4] Sending login request...");
    const loginResponse = await axios.post(`${SOLVER_BASE_URL}/login`, loginBody, { headers: loginHeaders });
    console.log("Login response:", loginResponse.data);

    // Extract the access token.
    const token = loginResponse.data.access_token;
    if (!token) {
      throw new Error("No access token received from login.");
    }

    // Fetch and log the Muon price in standard decimal format.
    const muonPrice = await fetchMuonPriceConverted();
    console.log("Fetched Muon Price (converted):", muonPrice);

    // ----------------------------------------------------------------
    // Instant Close Parameters – Replace these with your actual values:
    const quote_id = 24718;         // The quote ID (number) for the position to close.
    const quantity_to_close = "6.1"; // The quantity to close as a string.
    const close_price = (muonPrice * 0.95).toString(); //Position was LONG, so we're going to decrease a little to account for hedger spread.
    console.log("closePrice: ", close_price);

    console.log("\nSending instant close request...");
    const closeResponse = await closeInstantPosition(token, quote_id, quantity_to_close, close_price);
    console.log("Instant close response:", closeResponse);
  } catch (err) {
    console.error("Error in SIWE login flow or closing position:", err.response?.data || err.message);
  }
})();

Explanation

  1. SIWE Login Flow:

    • Nonce Retrieval: The script calls getNonce(activeAccount) to get a nonce from the solver.

    • SIWE Message: A SIWE message is built using the provided configuration (domain, chain ID, etc.) and then signed with your wallet.

    • Login Request: The signed SIWE message is sent to the /login endpoint. On success, an access token is returned.

  2. Instant Close Request:

    • Parameters:

      • quote_id: The identifier of the quote (or open position) you wish to close.

      • quantity_to_close: The amount to close (as a string).

      • close_price: The price at which you wish to close the position. Note: For market orders, remember to adjust this price for slippage if required.

    • API Call: The access token is included in the authorization header when making a POST request to the /instant_close endpoint with the above parameters.

SIWE Login
apply slippage
instant_close