UNPKG

@renegade-fi/core

Version:
185 lines 7.86 kB
import axios from "axios"; import invariant from "tiny-invariant"; import { RENEGADE_AUTH_HEADER_NAME, RENEGADE_SDK_VERSION_HEADER, RENEGADE_SIG_EXPIRATION_HEADER_NAME, SIG_EXPIRATION_BUFFER_MS, } from "../constants.js"; import { BaseError } from "../errors/base.js"; import { parseBigJSON } from "./bigJSON.js"; import { getVersionNumber } from "./getVersion.js"; export async function postRelayerRaw(url, body, headers = {}) { try { const response = await axios.post(url, body, { headers, validateStatus: null, // Allow any status code to pass through transformResponse: (data) => { try { return parseBigJSON(data); } catch { // If parsing fails, return raw data return data; } }, }); // For non-2xx responses, throw error with raw data if (response.status < 200 || response.status >= 300) { throw new BaseError(response.data); } return response.data; } catch (error) { if (axios.isAxiosError(error)) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.error("Response error:", error.response.data); throw new BaseError(error.response.data); } if (error.request) { // The request was made but no response was received console.error("Request error: No response received"); } else { // Something happened in setting up the request that triggered an Error console.error("Error:", error.message); } } else { // Non-Axios error console.error("Error:", error); } throw error; // Rethrow the error for further handling or logging } } export async function getRelayerRaw(url, headers = {}) { try { const response = await axios.get(url, { headers, transformResponse: (data) => { try { if (url.includes("/order-history") || url.includes("/open-orders") || url.includes("/metadata")) { // We use ts-ignore here because TypeScript doesn't recognize the // `context` argument in the JSON.parse reviver // @ts-ignore return JSON.parse(data, (key, value, context) => { if (typeof value === "number" && key !== "price") { if (context?.source === undefined) { console.warn(`No JSON source for ${key}, converting parsed value to BigInt`); return BigInt(value); } return BigInt(context.source); } return value; }); } if (url.includes("/price")) { return JSON.parse(data); } return parseBigJSON(data); } catch (_error) { return data; } }, }); // console.log(`GET ${url} response: `, response.data) // Process the response data as needed return response.data; // Assuming the function should return the response data } catch (error) { if (axios.isAxiosError(error)) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.error("Response error:", error.response.data); } else if (error.request) { // The request was made but no response was received console.error("Request error: No response received"); } else { // Something happened in setting up the request that triggered an Error console.error("Error:", error.message); } } else { // Non-Axios error console.error("Error:", error); } throw error; // Rethrow the error for further handling or logging } } export async function postRelayerWithAuth(config, url, body, requestType) { const symmetricKey = config.getSymmetricKey(requestType); invariant(symmetricKey, "Failed to derive symmetric key"); const path = getPathFromUrl(url); const headers = { "Content-Type": "application/json", }; const headersWithAuth = addExpiringAuthToHeaders(config, path, headers, body ?? "", symmetricKey, SIG_EXPIRATION_BUFFER_MS); return await postRelayerRaw(url, body, headersWithAuth); } export async function postRelayerWithAdmin(config, url, body) { const { adminKey } = config; invariant(adminKey, "Admin key is required"); const symmetricKey = config.utils.b64_to_hex_hmac_key(adminKey); const path = getPathFromUrl(url); const headers = { "Content-Type": "application/json", }; const headersWithAuth = addExpiringAuthToHeaders(config, path, headers, body ?? "", symmetricKey, SIG_EXPIRATION_BUFFER_MS); return await postRelayerRaw(url, body, headersWithAuth); } export async function getRelayerWithAuth(config, url) { const symmetricKey = config.getSymmetricKey(); invariant(symmetricKey, "Failed to derive symmetric key"); const path = getPathFromUrl(url); const headers = { "Content-Type": "application/json", }; const headersWithAuth = addExpiringAuthToHeaders(config, path, headers, "", // Body symmetricKey, SIG_EXPIRATION_BUFFER_MS); return await getRelayerRaw(url, headersWithAuth); } export async function getRelayerWithAdmin(config, url) { const { adminKey } = config; invariant(adminKey, "Admin key is required"); const symmetricKey = config.utils.b64_to_hex_hmac_key(adminKey); const path = getPathFromUrl(url); const headers = { "Content-Type": "application/json", }; const headersWithAuth = addExpiringAuthToHeaders(config, path, headers, "", // Body symmetricKey, SIG_EXPIRATION_BUFFER_MS); return await getRelayerRaw(url, headersWithAuth); } export async function postWithSymmetricKey(config, { body, headers = {}, key, url, }) { const path = getPathFromUrl(url); const headersWithAuth = addExpiringAuthToHeaders(config, path, headers, body ?? "", key, SIG_EXPIRATION_BUFFER_MS); return await postRelayerRaw(url, body, headersWithAuth); } /// Get the path from a URL function getPathFromUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.pathname + parsedUrl.search || "/"; } catch { return url.startsWith("/") ? url : `/${url}`; } } /// Add an auth expiration and signature to a set of headers export function addExpiringAuthToHeaders(config, path, headers, body, key, expiration) { // Add a timestamp const expirationTs = Date.now() + expiration; const versionString = `typescript-v${getVersionNumber()}`; const headersWithExpiration = { ...headers, [RENEGADE_SIG_EXPIRATION_HEADER_NAME]: expirationTs.toString(), [RENEGADE_SDK_VERSION_HEADER]: versionString, }; // Add the signature const auth = config.utils.create_request_signature(path, headersWithExpiration, body, key); return { ...headersWithExpiration, [RENEGADE_AUTH_HEADER_NAME]: auth }; } //# sourceMappingURL=http.js.map