Connecting to the MEXC WebSocket API

/
65

I was not able to find very much documentation for MEXC's WebSocket endpoint(s), but was able to wade through a few resources and build a simple deal (trade) subscription monitor.

Hope this helps someone out there :)

Usage:

const mexc = new MEXCStreamer()

// handle unknown messages
mexc.on('message', (msg) => {
    console.log('[???]', msg.data)
})

// handle deal/trade notifications
mexc.on('trade', (data) => {
    let {S: type, p: price, t: time, v: amount} = data
    const fiatValue = parseFloat(( ( price ) * ( amount ) ).toFixed(2))
    if (fiatValue > mexc.minFiatValue) {
        const formattedFiatValue = mexc.amountFormat.format(fiatValue)
        const formattedPrice = mexc.amountFormat.format(price)
        const orderType = mexc.orderTypes[type];
        let formattedAmount
        switch (true) {
            case ( amount > 1000000 ):
                formattedAmount = `${mexc.amountFormat.format(amount / 1000000)}M`
                break
            case ( amount > 10000 ):
                formattedAmount = `${mexc.amountFormat.format(amount / 1000)}K`
                break
            default:
                formattedAmount = `${mexc.amountFormat.format(amount)}`
        }
        const msg = `[TRADE] ${( new Date(time) ).toLocaleTimeString()} ${orderType} • $${formattedFiatValue} (${formattedAmount} BTC @ $${formattedPrice})`
        console.log(msg)
    }
})

mexc.start()

And here's the MEXCStreamer TypeScript class:

import * as WebSocket from "ws"
import { clearInterval, setInterval } from "timers"
import { EventEmitter } from "events"
import { parseFixed } from "@ethersproject/bignumber";

interface DealData {
  t: number,
  S: string,
  v: number,
  p: number
}

class MEXCStreamer extends EventEmitter {
  protected ws: WebSocket | undefined

  public minFiatValue = 5
  public pair = 'BTCUSDT'

  readonly amountFormat = Intl.NumberFormat('en-US')
  readonly orderTypes: { [key: string]: string } = {
    '1': '🙌 BUY',
    '2': '🫠 SELL'
  }
  private interval: NodeJS.Timer | undefined

  start() {
    this.ws = new WebSocket('wss://wbs.mexc.com/ws')
    this.ws.onopen = this.handleOpen.bind(this)
    this.ws.onerror = this.handleError.bind(this)
    this.ws.onmessage = this.handleMessage.bind(this)
  }

  destroy() {
    if (this.ws)
      this.ws.close()

    if (this.interval)
      clearInterval(this.interval)
  }

  private ping() {
    if (this.ws)
      this.ws.send('{"method": "PING"}')
  }

  private handleError(err: WebSocket.ErrorEvent) {
    throw err
  }

  private handleOpen() {
    console.log('⚡️ Connected to MEXC stream!')
    if (this.ws) {

      this.ws.send(
        JSON.stringify({"method": "SUBSCRIPTION", "params": [`spot@public.deals.v3.api@${this.pair}`]})
      )

      this.interval = setInterval(() => {
        this.ping()
      }, 30 * 1000)
    }
  }

  private async handleMessage(msg: any) {
    const data = JSON.parse(msg.data)
    if (data.c?.startsWith('spot@public.deals.v3.api@')) {
      this.emit('trade', data.d.deals[0])
    } else {
      // unhandled incoming message
      this.emit('message', msg)
    }
  }
}

Git the gist here.


TOY MODE
π