@arkhamintelligence/sdk
Version:
Arkham Intelligence TypeScript SDK
100 lines (88 loc) • 2.68 kB
text/typescript
import { ArkhamError } from "./exceptions";
import { KeyPair } from "./key-pair";
export class HttpError extends Error {
statusCode: number;
constructor(message: string, statusCode?: number) {
super(message);
this.name = this.constructor.name; // Set the name to the class name
this.statusCode = statusCode || 500; // Default to 500 Internal Server Error
}
}
export const $request = Symbol("request");
export interface ArkhamClientOptions {
apiKey?: string;
apiSecret?: string;
baseUrl?: string;
}
export class BaseClient {
#keyPair: KeyPair;
#baseUrl: string;
constructor({
apiKey = process.env.ARKHAM_API_KEY,
apiSecret = process.env.ARKHAM_API_SECRET,
baseUrl = process.env.ARKHAM_API_URL ?? "https://arkm.com/api",
}: ArkhamClientOptions = {}) {
this.#keyPair = new KeyPair(apiKey, apiSecret);
this.#baseUrl = baseUrl.replace(/\/$/, "");
}
async [$request]<T = any>(
method: string,
path: string,
params?: Record<string, any> | null,
jsonData?: unknown
): Promise<T> {
// Build URL and query params
if (params) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== null && value !== undefined) {
searchParams.append(key, String(value));
}
}
path += "?" + searchParams.toString();
}
// Prepare body + signing
const data = jsonData ? JSON.stringify(jsonData) : "";
const headers: HeadersInit = {
"Content-Type": "application/json",
Accept: "application/json",
...this.#keyPair.signRequest(method, path, data),
};
console.log(`HTTP ${method} ${this.#baseUrl + path}`);
console.log("Headers:", headers);
if (data) {
console.log("Body:", data);
}
// Make request using fetch
const response = await fetch(this.#baseUrl + path, {
method,
headers,
body: data || undefined,
});
// Handle errors
if (!response.ok) {
let error: Error = new HttpError(response.statusText, response.status);
try {
const errorData = await response.json();
if (
typeof errorData?.id === "number" &&
typeof errorData?.message === "string" &&
typeof errorData?.name === "string"
) {
error = new ArkhamError(
errorData.id,
errorData.name,
errorData.message
);
}
} catch {
const text = await response.text();
if (text !== "") {
error.message += `: ${text}`;
}
}
throw error;
}
return (await response.json()) as T;
}
}