bitso-bert-api
Version:
<h1 align="center">bitso-bert-api</h1>
87 lines (75 loc) • 2.67 kB
text/typescript
import crypto from 'crypto'
import camelcaseKeys from 'camelcase-keys'
import fetch, { RequestInit } from 'node-fetch'
type BitsoQueryParams = Record<string, any>
type BitsoBodyParams = Record<string, any>
const client = (method: 'GET' | 'POST' | 'DELETE', isPrivate: boolean = false) => {
return async function request<T>(
path: string,
queryParams?: BitsoQueryParams,
bodyParams?: BitsoBodyParams,
): Promise<T> {
if (isPrivate && (!process.env.BITSO_API_KEY || !process.env.BITSO_API_SECRET))
throw new Error('[BITSO_API_KEY, BITSO_API_SECRET] enviroment variables are required for private endpoints')
const queryString =
queryParams &&
Object.keys(queryParams)
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
.join('&')
const requestPath = `/v3${path}?${queryString}`
const config: RequestInit = {
method,
headers: { 'Content-Type': 'application/json' },
}
if (isPrivate) {
const nonce = new Date().getTime()
let message = nonce + method + requestPath
if (method === 'POST') {
config.body = JSON.stringify(bodyParams || {})
message += config.body
}
const signature = crypto
.createHmac('sha256', process.env.BITSO_API_SECRET)
.update(message)
.digest('hex')
config.headers = { ...config.headers, Authorization: `Bitso ${process.env.BITSO_API_KEY}:${nonce}:${signature}` }
}
try {
const url = `${process.env.BITSO_API_URL}${requestPath}`
const response = await fetch(url, config)
const data = await response.json()
if (response.ok) {
return camelcaseKeys(data.payload, { deep: true })
} else {
return Promise.reject(data.error)
}
} catch (err) {
return Promise.reject(new Error(err))
}
}
}
const basicClient = (method: 'GET') => {
return async function request<T>(path: string): Promise<T> {
const config: RequestInit = {
method,
headers: { 'Content-Type': 'application/json' },
}
try {
const response = await fetch(path, config)
const data = await response.json()
if (response.ok) {
return camelcaseKeys(data, { deep: true })
} else {
return Promise.reject(data)
}
} catch (err) {
return Promise.reject(new Error(err))
}
}
}
export const publicGet = client('GET')
export const publicPost = client('POST')
export const privateGet = client('GET', true)
export const privateDelete = client('DELETE', true)
export const privatePost = client('POST', true)
export const basicGet = basicClient('GET')