/** * 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 { const response = await this.api.post('/tokens/transfers', { ...transfer, namespace: this.namespace }); return response.data; } /** * Get token pools in namespace */ async getTokenPools(): Promise { 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 { 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 { 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 { const response = await this.api.get(`/namespaces/${this.namespace}/transactions/${txId}`); return response.data; } /** * Get blockchain connector status */ async getConnectorStatus(connector: string): Promise { 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; } } }