mempool/backend/src/api/lightning/clightning/clightning-convert.ts

96 lines
3.3 KiB
TypeScript
Raw Normal View History

import logger from "../../../logger";
import { ILightningApi } from "../lightning-api.interface";
export function convertNode(clNode: any): ILightningApi.Node {
return {
alias: clNode.alias ?? '',
color: `#${clNode.color ?? ''}`,
features: [], // TODO parse and return clNode.feature
public_key: clNode.nodeid,
sockets: clNode.addresses?.map(addr => `${addr.address}:${addr.port}`) ?? [],
updated_at: new Date((clNode?.last_timestamp ?? 0) * 1000).toUTCString(),
};
}
export function convertAndmergeBidirectionalChannels(clChannels: any[]): ILightningApi.Channel[] {
const consolidatedChannelList: ILightningApi.Channel[] = [];
const clChannelsDict = {};
const clChannelsDictCount = {};
for (const clChannel of clChannels) {
if (!clChannelsDict[clChannel.short_channel_id]) {
clChannelsDict[clChannel.short_channel_id] = clChannel;
clChannelsDictCount[clChannel.short_channel_id] = 1;
} else {
consolidatedChannelList.push(
buildBidirectionalChannel(clChannel, clChannelsDict[clChannel.short_channel_id])
);
delete clChannelsDict[clChannel.short_channel_id];
clChannelsDictCount[clChannel.short_channel_id]++;
}
}
const bidirectionalChannelsCount = consolidatedChannelList.length;
for (const short_channel_id of Object.keys(clChannelsDict)) {
consolidatedChannelList.push(buildUnidirectionalChannel(clChannelsDict[short_channel_id]));
}
const unidirectionalChannelsCount = consolidatedChannelList.length - bidirectionalChannelsCount;
logger.debug(`clightning knows ${clChannels.length} channels. ` +
`We found ${bidirectionalChannelsCount} bidirectional channels ` +
`and ${unidirectionalChannelsCount} unidirectional channels.`);
return consolidatedChannelList;
}
function buildBidirectionalChannel(clChannelA: any, clChannelB: any): ILightningApi.Channel {
const lastUpdate = Math.max(clChannelA.last_update ?? 0, clChannelB.last_update ?? 0);
return {
id: clChannelA.short_channel_id,
capacity: clChannelA.satoshis,
transaction_id: '', // TODO
transaction_vout: 0, // TODO
updated_at: new Date(lastUpdate * 1000).toUTCString(),
policies: [
convertPolicy(clChannelA),
convertPolicy(clChannelB)
]
};
}
function buildUnidirectionalChannel(clChannel: any): ILightningApi.Channel {
return {
id: clChannel.short_channel_id,
capacity: clChannel.satoshis,
policies: [convertPolicy(clChannel), getEmptyPolicy()],
transaction_id: '', // TODO
transaction_vout: 0, // TODO
updated_at: new Date((clChannel.last_update ?? 0) * 1000).toUTCString(),
};
}
function convertPolicy(clChannel: any): ILightningApi.Policy {
return {
public_key: clChannel.source,
base_fee_mtokens: clChannel.base_fee_millisatoshi,
fee_rate: clChannel.fee_per_millionth,
is_disabled: !clChannel.active,
max_htlc_mtokens: clChannel.htlc_maximum_msat.slice(0, -4),
min_htlc_mtokens: clChannel.htlc_minimum_msat.slice(0, -4),
updated_at: new Date((clChannel.last_update ?? 0) * 1000).toUTCString(),
};
}
function getEmptyPolicy(): ILightningApi.Policy {
return {
public_key: 'null',
base_fee_mtokens: '0',
fee_rate: 0,
is_disabled: true,
max_htlc_mtokens: '0',
min_htlc_mtokens: '0',
updated_at: new Date(0).toUTCString(),
};
}