140 lines
3.8 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
}
|