2022-07-29 17:41:09 +02:00
|
|
|
import { ILightningApi } from '../lightning-api.interface';
|
2022-07-29 16:33:07 +02:00
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Convert a clightning "listnode" entry to a lnd node entry
|
|
|
|
*/
|
2022-07-29 16:33:07 +02:00
|
|
|
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(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Convert clightning "listchannels" response to lnd "describegraph.channels" format
|
|
|
|
*/
|
|
|
|
export function convertAndmergeBidirectionalChannels(clChannels: any[]): ILightningApi.Channel[] {
|
2022-07-29 16:33:07 +02:00
|
|
|
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(
|
2022-07-29 17:41:09 +02:00
|
|
|
buildFullChannel(clChannel, clChannelsDict[clChannel.short_channel_id])
|
2022-07-29 16:33:07 +02:00
|
|
|
);
|
|
|
|
delete clChannelsDict[clChannel.short_channel_id];
|
|
|
|
clChannelsDictCount[clChannel.short_channel_id]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const short_channel_id of Object.keys(clChannelsDict)) {
|
2022-07-29 17:41:09 +02:00
|
|
|
consolidatedChannelList.push(buildIncompleteChannel(clChannelsDict[short_channel_id]));
|
2022-07-29 16:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return consolidatedChannelList;
|
|
|
|
}
|
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Convert two clightning "getchannels" entries into a full a lnd "describegraph.channels" format
|
|
|
|
* In this case, clightning knows the channel policy for both nodes
|
|
|
|
*/
|
|
|
|
function buildFullChannel(clChannelA: any, clChannelB: any): ILightningApi.Channel {
|
2022-07-29 16:33:07 +02:00
|
|
|
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)
|
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Convert one clightning "getchannels" entry into a full a lnd "describegraph.channels" format
|
|
|
|
* In this case, clightning knows the channel policy of only one node
|
|
|
|
*/
|
|
|
|
function buildIncompleteChannel(clChannel: any): ILightningApi.Channel {
|
2022-07-29 16:33:07 +02:00
|
|
|
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(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Convert a clightning "listnode" response to a lnd channel policy format
|
|
|
|
*/
|
|
|
|
function convertPolicy(clChannel: any): ILightningApi.Policy {
|
2022-07-29 16:33:07 +02:00
|
|
|
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(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-07-29 17:41:09 +02:00
|
|
|
/**
|
|
|
|
* Create an empty channel policy in lnd format
|
|
|
|
*/
|
|
|
|
function getEmptyPolicy(): ILightningApi.Policy {
|
2022-07-29 16:33:07 +02:00
|
|
|
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(),
|
|
|
|
};
|
|
|
|
}
|