Created
January 18, 2025 23:13
-
-
Save zhe-t/9b9cf1b18e9204dc2c4ecead9a4ad037 to your computer and use it in GitHub Desktop.
HeliusAPIClient.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* External dependencies | |
*/ | |
import fetch from 'node-fetch'; | |
/** | |
* Helius API request/response types | |
*/ | |
type Webhook = { | |
webhookID: string; | |
wallet: string; | |
webhookURL: string; | |
transactionTypes: string[]; | |
accountAddresses: string[]; | |
webhookType: string; | |
authHeader: string; | |
} | |
type CreateWebhookData = { | |
webhookURL: string; | |
transactionTypes: string[]; | |
accountAddresses: string[]; | |
webhookType: string; | |
authHeader?: string; | |
} | |
type CreateWebhookResponse = Webhook; | |
type UpdateWebhookData = CreateWebhookData; | |
type UpdateWebhookResponse = Webhook; | |
type GetWebhookResponse = Webhook; | |
type GetAllWebhooksResponse = Webhook[]; | |
enum HttpMethod { | |
GET = 'GET', | |
POST = 'POST', | |
PUT = 'PUT', | |
DELETE = 'DELETE', | |
} | |
/** | |
* Helius API client | |
*/ | |
class HeliusAPIClient { | |
/** | |
* API key | |
*/ | |
private readonly apiKey: string; | |
/** | |
* Base URL | |
*/ | |
private readonly baseUrl: string; | |
constructor(apiKey: string, baseUrl: string = 'https://api.helius.xyz') { | |
this.apiKey = apiKey; | |
this.baseUrl = baseUrl; | |
} | |
static builder() { | |
return new HeliusAPIClientBuilder(); | |
} | |
private async request<T, D = any>(method: HttpMethod, path: string, data?: D): Promise<T> { | |
if (!path) { | |
throw new Error('Path is required'); | |
} | |
const url = `${this.baseUrl}/v0${path}?api-key=${this.apiKey}`; | |
const options: fetch.RequestInit = { | |
method, | |
headers: { | |
'Content-Type': 'application/json', | |
'Accept': 'application/json' | |
} | |
}; | |
if (method === HttpMethod.POST || method === HttpMethod.PUT) { | |
if (!data) { | |
throw new Error('Data is required for POST/PUT requests'); | |
} | |
options.body = JSON.stringify(data); | |
} | |
try { | |
const response = await fetch(url, options); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`); | |
} | |
const json = await response.json() as T; | |
return json; | |
} catch (error) { | |
throw new Error(`API request failed: ${error instanceof Error ? error.message : 'Unknown error'}`); | |
} | |
} | |
/** | |
* Creates a new webhook | |
* | |
* @param {CreateWebhookData} data - The webhook data | |
* @returns {Promise<CreateWebhookResponse>} The created webhook | |
* | |
* @example | |
* const webhook = await heliusClient.createWebhook({ | |
* webhookURL: 'https://example.com/webhook', | |
* transactionTypes: ['transaction'], | |
* accountAddresses: ['0x123'], | |
* webhookType: 'transaction', | |
* authHeader: 'Bearer 123' | |
* }); | |
*/ | |
async createWebhook(data: CreateWebhookData): Promise<CreateWebhookResponse> { | |
return await this.request<CreateWebhookResponse, CreateWebhookData>(HttpMethod.POST, '/webhooks', data); | |
} | |
/** | |
* Updates an existing webhook | |
* | |
* @param {string} webhookId - The ID of the webhook to update | |
* @param {UpdateWebhookData} data - The webhook data | |
* @returns {Promise<UpdateWebhookResponse>} The updated webhook | |
* | |
* @example | |
* const webhook = await heliusClient.updateWebhook('123', { | |
* webhookURL: 'https://example.com/webhook', | |
* transactionTypes: ['transaction'], | |
* accountAddresses: ['0x123'], | |
* webhookType: 'transaction', | |
* authHeader: 'Bearer 123' | |
* }); | |
*/ | |
async updateWebhook(webhookId: string, data: UpdateWebhookData): Promise<UpdateWebhookResponse> { | |
return await this.request<UpdateWebhookResponse, UpdateWebhookData>(HttpMethod.PUT, `/webhooks/${webhookId}`, data); | |
} | |
/** | |
* Retrieves a webhook by its ID | |
* | |
* @param {string} webhookId - The ID of the webhook to retrieve | |
* @returns {Promise<GetWebhookResponse>} The retrieved webhook | |
* | |
* @example | |
* const webhook = await heliusClient.getWebhook('123'); | |
*/ | |
async getWebhook(webhookId: string): Promise<GetWebhookResponse> { | |
return await this.request<GetWebhookResponse>(HttpMethod.GET, `/webhooks/${webhookId}`); | |
} | |
/** | |
* Retrieves all webhooks | |
* | |
* @returns {Promise<GetAllWebhooksResponse>} The list of webhooks | |
*/ | |
async getAllWebhooks(): Promise<GetAllWebhooksResponse> { | |
return await this.request<GetAllWebhooksResponse>(HttpMethod.GET, '/webhooks'); | |
} | |
/** | |
* Deletes a webhook by its ID | |
* | |
* @param {string} webhookId - The ID of the webhook to delete | |
* @returns {Promise<boolean>} Whether the webhook was deleted successfully | |
*/ | |
async deleteWebhook(webhookId: string): Promise<boolean> { | |
return await this.request<boolean>(HttpMethod.DELETE, `/webhooks/${webhookId}`); | |
} | |
} | |
/** | |
* Helius API client builder | |
* | |
* @example | |
* const heliusClient = HeliusAPIClient.builder() | |
* .withApiKey('sk-123') | |
* .build(); | |
*/ | |
class HeliusAPIClientBuilder { | |
private apiKey: string; | |
private baseUrl?: string; | |
withApiKey(apiKey: string) { | |
if (!apiKey) throw new Error('API key cannot be empty'); | |
this.apiKey = apiKey; | |
return this; | |
} | |
withBaseUrl(baseUrl: string) { | |
if (!baseUrl) throw new Error('Base URL cannot be empty'); | |
this.baseUrl = baseUrl; | |
return this; | |
} | |
build(): HeliusAPIClient { | |
if (!this.apiKey) { | |
throw new Error('API key is required'); | |
} | |
return new HeliusAPIClient(this.apiKey, this.baseUrl); | |
} | |
} | |
export { | |
HeliusAPIClient, | |
HeliusAPIClientBuilder | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment