mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-22 14:22:33 +01:00
feat: channel queries
This commit is contained in:
parent
a84131d5f2
commit
22a909b4d9
10 changed files with 233 additions and 53 deletions
27
src/schemaTypes/query/channels/channelFees.ts
Normal file
27
src/schemaTypes/query/channels/channelFees.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { GraphQLObjectType, GraphQLInt, GraphQLString } from 'graphql';
|
||||||
|
|
||||||
|
export const ChannelFeeType = new GraphQLObjectType({
|
||||||
|
name: 'channelFeeType',
|
||||||
|
fields: () => {
|
||||||
|
return {
|
||||||
|
alias: {
|
||||||
|
type: GraphQLString,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: GraphQLString,
|
||||||
|
},
|
||||||
|
baseFee: {
|
||||||
|
type: GraphQLInt,
|
||||||
|
},
|
||||||
|
feeRate: {
|
||||||
|
type: GraphQLInt,
|
||||||
|
},
|
||||||
|
transactionId: {
|
||||||
|
type: GraphQLString,
|
||||||
|
},
|
||||||
|
transactionVout: {
|
||||||
|
type: GraphQLInt,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
15
src/schemaTypes/query/channels/channelReport.ts
Normal file
15
src/schemaTypes/query/channels/channelReport.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { GraphQLObjectType, GraphQLInt } from 'graphql';
|
||||||
|
|
||||||
|
export const ChannelReportType = new GraphQLObjectType({
|
||||||
|
name: 'channelReportType',
|
||||||
|
fields: () => {
|
||||||
|
return {
|
||||||
|
local: {
|
||||||
|
type: GraphQLInt,
|
||||||
|
},
|
||||||
|
remote: {
|
||||||
|
type: GraphQLInt,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
87
src/schemas/query/channels/channelFees.ts
Normal file
87
src/schemas/query/channels/channelFees.ts
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
import { getFeeRates, getChannels, getNode } from 'ln-service';
|
||||||
|
import { logger } from '../../../helpers/logger';
|
||||||
|
import { requestLimiter } from '../../../helpers/rateLimiter';
|
||||||
|
import { GraphQLNonNull, GraphQLString, GraphQLList } from 'graphql';
|
||||||
|
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
|
||||||
|
import { ChannelFeeType } from '../../../schemaTypes/query/channels/channelFees';
|
||||||
|
|
||||||
|
interface GetChannelsProps {
|
||||||
|
channels: ChannelsProps[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GetFeeRatesProps {
|
||||||
|
channels: ChannelFeesProps[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChannelsProps {
|
||||||
|
partner_public_key: number;
|
||||||
|
transaction_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChannelFeesProps {
|
||||||
|
base_fee: number;
|
||||||
|
fee_rate: number;
|
||||||
|
transaction_id: string;
|
||||||
|
transaction_vout: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NodeProps {
|
||||||
|
alias: string;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getChannelFees = {
|
||||||
|
type: new GraphQLList(ChannelFeeType),
|
||||||
|
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
|
||||||
|
resolve: async (root: any, params: any, context: any) => {
|
||||||
|
await requestLimiter(context.ip, 'channelFees');
|
||||||
|
|
||||||
|
const lnd = getAuthLnd(params.auth);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const channels: GetChannelsProps = await getChannels({ lnd });
|
||||||
|
|
||||||
|
const channelFees: GetFeeRatesProps = await getFeeRates({ lnd });
|
||||||
|
|
||||||
|
const getConsolidated = () =>
|
||||||
|
Promise.all(
|
||||||
|
channels.channels.map(async channel => {
|
||||||
|
const nodeInfo: NodeProps = await getNode({
|
||||||
|
lnd,
|
||||||
|
is_omitting_channels: true,
|
||||||
|
public_key: channel.partner_public_key,
|
||||||
|
});
|
||||||
|
|
||||||
|
const fees = channelFees.channels.find(
|
||||||
|
channelFee =>
|
||||||
|
channelFee.transaction_id ===
|
||||||
|
channel.transaction_id,
|
||||||
|
);
|
||||||
|
if (!fees) return;
|
||||||
|
const {
|
||||||
|
base_fee,
|
||||||
|
fee_rate,
|
||||||
|
transaction_id,
|
||||||
|
transaction_vout,
|
||||||
|
} = fees;
|
||||||
|
|
||||||
|
return {
|
||||||
|
alias: nodeInfo.alias,
|
||||||
|
color: nodeInfo.color,
|
||||||
|
baseFee: base_fee,
|
||||||
|
feeRate: fee_rate,
|
||||||
|
transactionId: transaction_id,
|
||||||
|
transactionVout: transaction_vout,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const consolidated = await getConsolidated();
|
||||||
|
|
||||||
|
return consolidated;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error getting channel fees: %o', error);
|
||||||
|
throw new Error(getErrorMsg(error));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
44
src/schemas/query/channels/channelReport.ts
Normal file
44
src/schemas/query/channels/channelReport.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { getChannels } from 'ln-service';
|
||||||
|
import { logger } from '../../../helpers/logger';
|
||||||
|
import { requestLimiter } from '../../../helpers/rateLimiter';
|
||||||
|
import { GraphQLNonNull, GraphQLString } from 'graphql';
|
||||||
|
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
|
||||||
|
import { ChannelReportType } from '../../../schemaTypes/query/channels/channelReport';
|
||||||
|
|
||||||
|
interface GetChannelsProps {
|
||||||
|
channels: ChannelsProps[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChannelsProps {
|
||||||
|
remote_balance: number;
|
||||||
|
local_balance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getChannelReport = {
|
||||||
|
type: ChannelReportType,
|
||||||
|
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
|
||||||
|
resolve: async (root: any, params: any, context: any) => {
|
||||||
|
await requestLimiter(context.ip, 'channelReport');
|
||||||
|
|
||||||
|
const lnd = getAuthLnd(params.auth);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const channels: GetChannelsProps = await getChannels({ lnd });
|
||||||
|
|
||||||
|
const consolidated = channels.channels.reduce((p, c) => {
|
||||||
|
return {
|
||||||
|
remote_balance: p.remote_balance + c.remote_balance,
|
||||||
|
local_balance: p.local_balance + c.local_balance,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
local: consolidated.local_balance,
|
||||||
|
remote: consolidated.remote_balance,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error getting channel fees: %o', error);
|
||||||
|
throw new Error(getErrorMsg(error));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -48,46 +48,52 @@ export const getChannels = {
|
||||||
lnd,
|
lnd,
|
||||||
});
|
});
|
||||||
|
|
||||||
const channels = channelList.channels.map(async channel => {
|
const getChannelList = () =>
|
||||||
const nodeInfo = await getNode({
|
Promise.all(
|
||||||
lnd,
|
channelList.channels.map(async channel => {
|
||||||
is_omitting_channels: true,
|
const nodeInfo = await getNode({
|
||||||
public_key: channel.partner_public_key,
|
lnd,
|
||||||
});
|
is_omitting_channels: true,
|
||||||
|
public_key: channel.partner_public_key,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
capacity: channel.capacity,
|
capacity: channel.capacity,
|
||||||
commitTransactionFee: channel.commit_transaction_fee,
|
commitTransactionFee:
|
||||||
commitTransactionWeight: channel.commit_transaction_weight,
|
channel.commit_transaction_fee,
|
||||||
id: channel.id,
|
commitTransactionWeight:
|
||||||
isActive: channel.is_active,
|
channel.commit_transaction_weight,
|
||||||
isClosing: channel.is_closing,
|
id: channel.id,
|
||||||
isOpening: channel.is_opening,
|
isActive: channel.is_active,
|
||||||
isPartnerInitiated: !channel.is_partner_initiated,
|
isClosing: channel.is_closing,
|
||||||
isPrivate: channel.is_private,
|
isOpening: channel.is_opening,
|
||||||
isStaticRemoteKey: channel.is_static_remote_key,
|
isPartnerInitiated: !channel.is_partner_initiated,
|
||||||
localBalance: channel.local_balance,
|
isPrivate: channel.is_private,
|
||||||
localReserve: channel.local_reserve,
|
isStaticRemoteKey: channel.is_static_remote_key,
|
||||||
partnerPublicKey: channel.partner_public_key,
|
localBalance: channel.local_balance,
|
||||||
received: channel.received,
|
localReserve: channel.local_reserve,
|
||||||
remoteBalance: channel.remote_balance,
|
partnerPublicKey: channel.partner_public_key,
|
||||||
remoteReserve: channel.remote_reserve,
|
received: channel.received,
|
||||||
sent: channel.sent,
|
remoteBalance: channel.remote_balance,
|
||||||
timeOffline: channel.time_offline,
|
remoteReserve: channel.remote_reserve,
|
||||||
timeOnline: channel.time_online,
|
sent: channel.sent,
|
||||||
transactionId: channel.transaction_id,
|
timeOffline: channel.time_offline,
|
||||||
transactionVout: channel.transaction_vout,
|
timeOnline: channel.time_online,
|
||||||
unsettledBalance: channel.unsettled_balance,
|
transactionId: channel.transaction_id,
|
||||||
partnerNodeInfo: {
|
transactionVout: channel.transaction_vout,
|
||||||
alias: nodeInfo.alias,
|
unsettledBalance: channel.unsettled_balance,
|
||||||
capacity: nodeInfo.capacity,
|
partnerNodeInfo: {
|
||||||
channelCount: nodeInfo.channel_count,
|
alias: nodeInfo.alias,
|
||||||
color: nodeInfo.color,
|
capacity: nodeInfo.capacity,
|
||||||
lastUpdate: nodeInfo.updated_at,
|
channelCount: nodeInfo.channel_count,
|
||||||
},
|
color: nodeInfo.color,
|
||||||
};
|
lastUpdate: nodeInfo.updated_at,
|
||||||
});
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const channels = await getChannelList();
|
||||||
return channels;
|
return channels;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error getting channels: %o', error);
|
logger.error('Error getting channels: %o', error);
|
||||||
|
|
|
@ -66,7 +66,7 @@ export const getClosedChannels = {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const closedChannels: ChannelListProps = await getLnClosedChannels({
|
const closedChannels: ChannelListProps = await getLnClosedChannels({
|
||||||
lnd: lnd,
|
lnd,
|
||||||
});
|
});
|
||||||
|
|
||||||
const channels = closedChannels.channels.map(channel => {
|
const channels = closedChannels.channels.map(channel => {
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import { getChannelBalance } from "./channelBalance";
|
import { getChannelBalance } from './channelBalance';
|
||||||
import { getChannels } from "./channels";
|
import { getChannels } from './channels';
|
||||||
import { getClosedChannels } from "./closedChannels";
|
import { getClosedChannels } from './closedChannels';
|
||||||
import { getPendingChannels } from "./pendingChannels";
|
import { getPendingChannels } from './pendingChannels';
|
||||||
|
import { getChannelFees } from './channelFees';
|
||||||
|
import { getChannelReport } from './channelReport';
|
||||||
|
|
||||||
export const channelQueries = {
|
export const channelQueries = {
|
||||||
getChannelBalance,
|
getChannelBalance,
|
||||||
getChannels,
|
getChannels,
|
||||||
getClosedChannels,
|
getClosedChannels,
|
||||||
getPendingChannels
|
getPendingChannels,
|
||||||
|
getChannelFees,
|
||||||
|
getChannelReport,
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,9 +25,7 @@ export const getNetworkInfo = {
|
||||||
const lnd = getAuthLnd(params.auth);
|
const lnd = getAuthLnd(params.auth);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const info: NetworkInfoProps = await getLnNetworkInfo({
|
const info: NetworkInfoProps = await getLnNetworkInfo({ lnd });
|
||||||
lnd: lnd,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
averageChannelSize: info.average_channel_size,
|
averageChannelSize: info.average_channel_size,
|
||||||
|
|
|
@ -29,9 +29,7 @@ export const getForwards = {
|
||||||
const lnd = getAuthLnd(params.auth);
|
const lnd = getAuthLnd(params.auth);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const forwardsList: ForwardsProps = await getLnForwards({
|
const forwardsList: ForwardsProps = await getLnForwards({ lnd });
|
||||||
lnd: lnd,
|
|
||||||
});
|
|
||||||
|
|
||||||
const forwards = forwardsList.forwards.map(forward => ({
|
const forwards = forwardsList.forwards.map(forward => ({
|
||||||
createdAt: forward.created_at,
|
createdAt: forward.created_at,
|
||||||
|
|
|
@ -9,6 +9,7 @@ export const RateConfig: RateConfigProps = {
|
||||||
channelBalance: { max: 3, window: '1s' },
|
channelBalance: { max: 3, window: '1s' },
|
||||||
channelFees: { max: 3, window: '1s' },
|
channelFees: { max: 3, window: '1s' },
|
||||||
channels: { max: 3, window: '1s' },
|
channels: { max: 3, window: '1s' },
|
||||||
|
channelReport: { max: 3, window: '1s' },
|
||||||
closedChannels: { max: 3, window: '1s' },
|
closedChannels: { max: 3, window: '1s' },
|
||||||
pendingChannels: { max: 3, window: '1s' },
|
pendingChannels: { max: 3, window: '1s' },
|
||||||
bitcoinFee: { max: 3, window: '1s' },
|
bitcoinFee: { max: 3, window: '1s' },
|
||||||
|
|
Loading…
Add table
Reference in a new issue