Browse Source

refactor(lnd): add getChannels funtion to LightningService interface

master
jamaljsr 5 years ago
parent
commit
336596c462
  1. 5
      src/lib/clightning/clightningService.ts
  2. 7
      src/lib/lightning/notImplementedService.ts
  3. 1
      src/lib/lightning/types.ts
  4. 39
      src/lib/lnd/lndService.ts
  5. 26
      src/lib/lnd/mappers.ts

5
src/lib/clightning/clightningService.ts

@ -2,6 +2,7 @@ import { CLightningNode, LightningNode } from 'shared/types';
import { import {
LightningNodeAddress, LightningNodeAddress,
LightningNodeBalances, LightningNodeBalances,
LightningNodeChannel,
LightningNodeInfo, LightningNodeInfo,
LightningService, LightningService,
} from 'lib/lightning/types'; } from 'lib/lightning/types';
@ -38,6 +39,10 @@ class CLightningService implements LightningService {
return { address }; return { address };
} }
async getChannels(node: LightningNode): Promise<LightningNodeChannel[]> {
throw new Error(`getChannels is not implemented for ${node.implementation} nodes`);
}
/** /**
* Helper function to continually query the node until a successful * Helper function to continually query the node until a successful
* response is received or it times out * response is received or it times out

7
src/lib/lightning/notImplementedService.ts

@ -2,10 +2,14 @@ import { LightningNode } from 'shared/types';
import { import {
LightningNodeAddress, LightningNodeAddress,
LightningNodeBalances, LightningNodeBalances,
LightningNodeChannel,
LightningNodeInfo, LightningNodeInfo,
LightningService, LightningService,
} from './types'; } from './types';
/**
* A Lightning Service class whose functionas are not yet implemented
*/
class NotImplementedService implements LightningService { class NotImplementedService implements LightningService {
getInfo(node: LightningNode): Promise<LightningNodeInfo> { getInfo(node: LightningNode): Promise<LightningNodeInfo> {
throw new Error(`getInfo is not implemented for ${node.implementation} nodes`); throw new Error(`getInfo is not implemented for ${node.implementation} nodes`);
@ -21,6 +25,9 @@ class NotImplementedService implements LightningService {
getNewAddress(node: LightningNode): Promise<LightningNodeAddress> { getNewAddress(node: LightningNode): Promise<LightningNodeAddress> {
throw new Error(`getNewAddress is not implemented for ${node.implementation} nodes`); throw new Error(`getNewAddress is not implemented for ${node.implementation} nodes`);
} }
getChannels(node: LightningNode): Promise<LightningNodeChannel[]> {
throw new Error(`getChannels is not implemented for ${node.implementation} nodes`);
}
} }
export default new NotImplementedService(); export default new NotImplementedService();

1
src/lib/lightning/types.ts

@ -36,6 +36,7 @@ export interface LightningService {
getInfo: (node: LightningNode) => Promise<LightningNodeInfo>; getInfo: (node: LightningNode) => Promise<LightningNodeInfo>;
getBalances: (node: LightningNode) => Promise<LightningNodeBalances>; getBalances: (node: LightningNode) => Promise<LightningNodeBalances>;
getNewAddress: (node: LightningNode) => Promise<LightningNodeAddress>; getNewAddress: (node: LightningNode) => Promise<LightningNodeAddress>;
getChannels: (node: LightningNode) => Promise<LightningNodeChannel[]>;
// openChannel: (from: LightningNode, to: LightningNode, amount: string) => Promise<LND.ChannelPoint>; // openChannel: (from: LightningNode, to: LightningNode, amount: string) => Promise<LND.ChannelPoint>;
// closeChannel: (node: LightningNode, channelPoint: string) => Promise<any>; // closeChannel: (node: LightningNode, channelPoint: string) => Promise<any>;
// listChannels: (node: LightningNode) => Promise<LND.ListChannelsResponse>; // listChannels: (node: LightningNode) => Promise<LND.ListChannelsResponse>;

39
src/lib/lnd/lndService.ts

@ -1,18 +1,20 @@
import * as LND from '@radar/lnrpc'; import * as LND from '@radar/lnrpc';
import { LndNode } from 'shared/types'; import { LightningNode, LndNode } from 'shared/types';
import { import {
LightningNodeAddress, LightningNodeAddress,
LightningNodeBalances, LightningNodeBalances,
LightningNodeChannel,
LightningNodeInfo, LightningNodeInfo,
} from 'lib/lightning/types'; } from 'lib/lightning/types';
import { LndLibrary } from 'types'; import { LndLibrary } from 'types';
import { waitFor } from 'utils/async'; import { waitFor } from 'utils/async';
import { getContainerName } from 'utils/network'; import { getContainerName } from 'utils/network';
import { lndProxyClient as proxy } from './'; import { lndProxyClient as proxy } from './';
import { mapOpenChannel, mapPendingChannel } from './mappers';
class LndService implements LndLibrary { class LndService implements LndLibrary {
async getInfo(node: LndNode): Promise<LightningNodeInfo> { async getInfo(node: LndNode): Promise<LightningNodeInfo> {
const info = await proxy.getInfo(node); const info = await proxy.getInfo(this.cast(node));
return { return {
pubkey: info.identityPubkey, pubkey: info.identityPubkey,
alias: info.alias, alias: info.alias,
@ -25,7 +27,7 @@ class LndService implements LndLibrary {
} }
async getBalances(node: LndNode): Promise<LightningNodeBalances> { async getBalances(node: LndNode): Promise<LightningNodeBalances> {
const balances = await proxy.getWalletBalance(node); const balances = await proxy.getWalletBalance(this.cast(node));
return { return {
total: balances.totalBalance, total: balances.totalBalance,
confirmed: balances.confirmedBalance, confirmed: balances.confirmedBalance,
@ -33,8 +35,28 @@ class LndService implements LndLibrary {
}; };
} }
async getNewAddress(node: LndNode): Promise<LightningNodeAddress> { async getNewAddress(node: LightningNode): Promise<LightningNodeAddress> {
return await proxy.getNewAddress(node); return await proxy.getNewAddress(this.cast(node));
}
async getChannels(node: LightningNode): Promise<LightningNodeChannel[]> {
const { channels: open } = await proxy.listChannels(this.cast(node), {});
const {
pendingOpenChannels: opening,
pendingClosingChannels: closing,
pendingForceClosingChannels: forceClosing,
waitingCloseChannels: waitingClose,
} = await proxy.pendingChannels(this.cast(node));
const pluckChan = (c: any) => c.channel as LND.PendingChannel;
// merge all of the channel types into one array
return [
...open.filter(c => c.initiator).map(mapOpenChannel),
...opening.map(pluckChan).map(mapPendingChannel('Opening')),
...closing.map(pluckChan).map(mapPendingChannel('Closing')),
...forceClosing.map(pluckChan).map(mapPendingChannel('Force Closing')),
...waitingClose.map(pluckChan).map(mapPendingChannel('Waiting to Close')),
];
} }
async openChannel( async openChannel(
@ -108,6 +130,13 @@ class LndService implements LndLibrary {
timeout, timeout,
); );
} }
private cast(node: LightningNode): LndNode {
if (node.implementation !== 'LND')
throw new Error(`LndService cannot be used for '${node.implementation}' nodes`);
return node as LndNode;
}
} }
export default new LndService(); export default new LndService();

26
src/lib/lnd/mappers.ts

@ -0,0 +1,26 @@
import { Channel, PendingChannel } from '@radar/lnrpc';
import { LightningNodeChannel } from 'lib/lightning/types';
export const mapOpenChannel = (chan: Channel): LightningNodeChannel => ({
pending: false,
uniqueId: chan.channelPoint.slice(-12),
channelPoint: chan.channelPoint,
pubkey: chan.remotePubkey,
capacity: chan.capacity,
localBalance: chan.localBalance,
remoteBalance: chan.remoteBalance,
status: 'Open',
});
export const mapPendingChannel = (status: string) => (
chan: PendingChannel,
): LightningNodeChannel => ({
pending: true,
uniqueId: chan.channelPoint.slice(-12),
channelPoint: chan.channelPoint,
pubkey: chan.remoteNodePub,
capacity: chan.capacity,
localBalance: chan.localBalance,
remoteBalance: chan.remoteBalance,
status,
});
Loading…
Cancel
Save