UNPKG

@ln-markets/api

Version:

A set of wrappers to easily communicate with LN Markets API !

365 lines (312 loc) 7.96 kB
import { getHostname } from './utils.js' import { createHmac } from 'node:crypto' import { URL, URLSearchParams } from 'node:url' import { fetch } from 'undici' interface RequestOptions { method: string path: string data?: Record<string, string> requireAuth?: boolean } interface RestOptions { key?: string secret?: string passphrase?: string network?: 'mainnet' | 'testnet' headers?: Record<string, any> } class HttpError extends Error { status: number statusText: string constructor(status: number, statusText: string, message: string) { super(message) this.name = 'HttpError' this.status = status this.statusText = statusText } } export const createRestClient = (options: RestOptions = {}) => { const { key = process.env.LNM_API_KEY, secret = process.env.LNM_API_SECRET, network = process.env.LNM_API_NETWORK ?? 'mainnet', passphrase = process.env.LNM_API_PASSPHRASE, headers = {}, } = options const hostname = process.env.LNM_API_HOSTNAME ?? getHostname(network) const request = async (options: RequestOptions) => { const { method, path, data, requireAuth } = options if (requireAuth) { if (!key) { throw new Error('You need an API key to use an authenticated route') } else if (!secret) { throw new Error('You need an API secret to use an authenticated route') } else if (!passphrase) { throw new Error( 'You need an API passphrase to use an authenticated route' ) } const timestamp = Date.now() const payload = /^(GET|DELETE)$/.test(method) ? new URLSearchParams(data).toString() : JSON.stringify(data) const signature = createHmac('sha256', secret) .update(`${timestamp}${method}/v2${path}${payload}`) .digest('base64') Object.assign(headers, { 'LNM-ACCESS-KEY': key, 'LNM-ACCESS-PASSPHRASE': passphrase, 'LNM-ACCESS-TIMESTAMP': timestamp, 'LNM-ACCESS-SIGNATURE': signature, }) } const url = new URL(`https://${hostname}/v2${path}`) if (data && /^(GET|DELETE)$/.test(method)) { for (const [key, value] of Object.entries(data)) { url.searchParams.append(key, value.toString()) } } if (data && /^(POST|PUT)$/.test(method)) { Object.assign(headers, { 'Content-Type': 'application/json', }) } const body = /^(POST|PUT)$/.test(method) ? JSON.stringify(data) : undefined const response = await fetch(url, { method, body, mode: 'cors', headers }) if (response.ok) { if (response.headers.get('content-type')?.includes('application/json')) { return response.json() } return response.text() } const text = await response.text() throw new HttpError(response.status, response.statusText, text) } const futuresGetTicker = () => { return request({ method: 'GET', path: '/futures/ticker' }) } const futuresNewTrade = (data: any) => { return request({ method: 'POST', path: '/futures', requireAuth: true, data, }) } const futuresUpdateTrade = (data: any) => { return request({ method: 'PUT', path: '/futures', requireAuth: true, data, }) } const futuresCloseTrade = (id: string) => { return request({ method: 'DELETE', path: '/futures', data: { id }, requireAuth: true, }) } const futuresCloseAllTrades = () => { return request({ method: 'DELETE', path: '/futures/all/close', requireAuth: true, }) } const futuresCancelTrade = (id: string) => { return request({ method: 'POST', path: '/futures/cancel', data: { id }, requireAuth: true, }) } const futuresCancelAllTrades = () => { return request({ method: 'DELETE', path: '/futures/all/cancel', requireAuth: true, }) } const futuresCashinTrade = (data: any) => { return request({ method: 'POST', path: '/futures/cash-in', requireAuth: true, data, }) } const futuresAddMarginTrade = (data: any) => { return request({ method: 'POST', path: '/futures/add-margin', requireAuth: true, data, }) } const futuresGetTrades = (data: any) => { return request({ method: 'GET', path: '/futures', requireAuth: true, data, }) } const futuresPriceHistory = (data: any) => { return request({ method: 'GET', path: '/futures/history/price', data, }) } const futuresIndexHistory = (data: any) => { return request({ method: 'GET', path: '/futures/history/index', data, }) } const futuresFixingHistory = (data: any) => { return request({ method: 'GET', path: '/futures/history/fixing', data, }) } const futuresCarryFeesHistory = (data: any) => { return request({ method: 'GET', path: '/futures/carry-fees', data, }) } const userGet = () => { return request({ method: 'GET', path: '/user', requireAuth: true }) } const userUpdate = (data: any) => { return request({ method: 'PUT', path: '/user', requireAuth: true, data }) } const userDeposit = (data: any) => { return request({ method: 'POST', path: '/user/deposit', requireAuth: true, data, }) } const userDepositHistory = (data: any) => { return request({ method: 'GET', path: '/user/deposit', requireAuth: true, data, }) } const userWithdraw = (data: any) => { return request({ method: 'POST', path: '/user/withdraw', requireAuth: true, data, }) } const userWithdrawUsd = (data: any) => { return request({ method: 'POST', path: '/user/withdraw/usd', requireAuth: true, data, }) } const userWithdrawHistory = (data: any) => { return request({ method: 'GET', path: '/user/withdraw', requireAuth: true, data, }) } const optionsInstruments = () => { return request({ method: 'GET', path: '/options/instruments' }) } const optionsInstrument = (data: any) => { return request({ method: 'GET', path: '/options/instrument', data }) } const optionsMarket = () => { return request({ method: 'GET', path: '/options/market' }) } const optionsNewTrade = (data: any) => { return request({ method: 'POST', path: '/options', requireAuth: true, data, }) } const optionsGetTrades = (data: any) => { return request({ method: 'GET', path: '/options', requireAuth: true, data, }) } const optionsCloseTrade = (id: string) => { return request({ method: 'DELETE', path: '/options', data: { id }, requireAuth: true, }) } const optionsCloseAllTrades = () => { return request({ method: 'DELETE', path: '/options/all/close', requireAuth: true, }) } const optionsUpdateSettlement = (data: any) => { return request({ method: 'PUT', path: '/options', requireAuth: true, data, }) } return { request, futuresGetTicker, futuresNewTrade, futuresUpdateTrade, futuresCloseTrade, futuresCloseAllTrades, futuresCancelTrade, futuresCancelAllTrades, futuresCashinTrade, futuresAddMarginTrade, futuresGetTrades, futuresPriceHistory, futuresIndexHistory, futuresFixingHistory, futuresCarryFeesHistory, userGet, userUpdate, userDeposit, userDepositHistory, userWithdraw, userWithdrawUsd, userWithdrawHistory, optionsInstrument, optionsInstruments, optionsMarket, optionsNewTrade, optionsGetTrades, optionsCloseTrade, optionsCloseAllTrades, optionsUpdateSettlement, } }