Files
smom-dbis-138/services/firefly-bridge/firefly-client.ts
2026-03-02 12:14:09 -08:00

140 lines
3.8 KiB
TypeScript

/**
* Firefly Bridge Client
* Interfaces with Hyperledger Firefly API for multi-chain orchestration
*/
import axios, { AxiosInstance } from 'axios';
import WebSocket from 'ws';
export interface FireflyTokenTransfer {
namespace: string;
pool: string; // Token pool (contract address)
from: string; // Sender identity
to: string; // Recipient identity
amount: string;
message?: {
data: any; // Off-chain data via DataExchange
};
}
export interface FireflyEvent {
id: string;
type: string;
namespace: string;
reference: string;
created: string;
info: any;
}
export class FireflyBridgeClient {
private api: AxiosInstance;
private ws: WebSocket | null = null;
private namespace: string;
constructor(apiUrl: string, namespace: string = 'default') {
this.api = axios.create({
baseURL: apiUrl,
headers: {
'Content-Type': 'application/json'
}
});
this.namespace = namespace;
}
/**
* Transfer token via Firefly
*/
async transferToken(transfer: FireflyTokenTransfer): Promise<any> {
const response = await this.api.post('/tokens/transfers', {
...transfer,
namespace: this.namespace
});
return response.data;
}
/**
* Get token pools in namespace
*/
async getTokenPools(): Promise<any[]> {
const response = await this.api.get(`/namespaces/${this.namespace}/tokens/pools`);
return response.data;
}
/**
* Create token pool
*/
async createTokenPool(pool: {
name: string;
type: 'fungible' | 'nonfungible';
config?: any;
}): Promise<any> {
const response = await this.api.post(`/namespaces/${this.namespace}/tokens/pools`, {
...pool,
namespace: this.namespace
});
return response.data;
}
/**
* Listen to Firefly events via WebSocket
*/
async listenToEvents(
callback: (event: FireflyEvent) => void,
eventTypes?: string[]
): Promise<void> {
const wsUrl = this.api.defaults.baseURL?.replace('http', 'ws') + '/ws';
this.ws = new WebSocket(wsUrl);
this.ws.on('message', (data: Buffer) => {
try {
const event: FireflyEvent = JSON.parse(data.toString());
// Filter by namespace and event types
if (event.namespace === this.namespace) {
if (!eventTypes || eventTypes.includes(event.type)) {
callback(event);
}
}
} catch (error) {
console.error('Error parsing Firefly event:', error);
}
});
this.ws.on('error', (error) => {
console.error('Firefly WebSocket error:', error);
});
this.ws.on('close', () => {
console.log('Firefly WebSocket closed, reconnecting...');
// Reconnect logic
setTimeout(() => this.listenToEvents(callback, eventTypes), 5000);
});
}
/**
* Get transaction status
*/
async getTransactionStatus(txId: string): Promise<any> {
const response = await this.api.get(`/namespaces/${this.namespace}/transactions/${txId}`);
return response.data;
}
/**
* Get blockchain connector status
*/
async getConnectorStatus(connector: string): Promise<any> {
const response = await this.api.get(`/namespaces/${this.namespace}/blockchain/${connector}`);
return response.data;
}
/**
* Close WebSocket connection
*/
close(): void {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
}