feat: resume query

This commit is contained in:
AP 2019-12-13 18:21:04 +01:00
parent 3ef05b338e
commit ce454ae669
9 changed files with 186 additions and 239 deletions

View file

@ -1,47 +0,0 @@
import {
GraphQLObjectType,
GraphQLBoolean,
GraphQLString,
GraphQLList
} from "graphql";
import { GraphQLInt } from "graphql";
const PaymentType = new GraphQLObjectType({
name: "paymentType",
fields: () => ({
confirmedAt: { type: GraphQLString },
createdAt: { type: GraphQLString },
createdHeight: { type: GraphQLInt },
inChannel: { type: GraphQLString },
isCanceled: { type: GraphQLBoolean },
isConfirmed: { type: GraphQLBoolean },
isHeld: { type: GraphQLBoolean },
mtokens: { type: GraphQLString },
pendingIndex: { type: GraphQLInt },
tokens: { type: GraphQLInt }
})
});
export const GetInvoiceType = new GraphQLObjectType({
name: "getInvoiceType",
fields: () => ({
chainAddress: { type: GraphQLString },
confirmedAt: { type: GraphQLString },
createdAt: { type: GraphQLString },
description: { type: GraphQLString },
descriptionHash: { type: GraphQLString },
expiresAt: { type: GraphQLString },
id: { type: GraphQLString },
isCanceled: { type: GraphQLBoolean },
isConfirmed: { type: GraphQLBoolean },
isHeld: { type: GraphQLBoolean },
isOutgoing: { type: GraphQLBoolean },
isPrivate: { type: GraphQLBoolean },
payments: { type: new GraphQLList(PaymentType) },
received: { type: GraphQLInt },
receivedMtokens: { type: GraphQLInt },
request: { type: GraphQLString },
secret: { type: GraphQLString },
tokens: { type: GraphQLInt }
})
});

View file

@ -1,25 +0,0 @@
import {
GraphQLObjectType,
GraphQLBoolean,
GraphQLString,
GraphQLList
} from "graphql";
import { GraphQLInt } from "graphql";
export const GetPaymentType = new GraphQLObjectType({
name: "getPaymentType",
fields: () => ({
createdAt: { type: GraphQLString },
destination: { type: GraphQLString },
fee: { type: GraphQLInt },
feeMtokens: { type: GraphQLString },
hops: { type: new GraphQLList(GraphQLString) },
id: { type: GraphQLString },
isConfirmed: { type: GraphQLBoolean },
isOutgoing: { type: GraphQLBoolean },
mtokens: { type: GraphQLString },
request: { type: GraphQLString },
secret: { type: GraphQLString },
tokens: { type: GraphQLInt }
})
});

View file

@ -0,0 +1,9 @@
import { GraphQLObjectType, GraphQLString } from 'graphql';
export const GetResumeType = new GraphQLObjectType({
name: 'getResumeType',
fields: () => ({
token: { type: GraphQLString },
resume: { type: GraphQLString },
}),
});

View file

@ -4,6 +4,7 @@ import { invoiceQueries } from './invoices';
import { dataQueries } from './data';
import { reportQueries } from './report';
import { flowQueries } from './flow';
import { routeQueries } from './route';
export const query = {
...channelQueries,
@ -12,4 +13,5 @@ export const query = {
...dataQueries,
...reportQueries,
...flowQueries,
...routeQueries,
};

View file

@ -1,9 +1,7 @@
import { getInvoices } from './invoices';
import { getPayments } from './payments';
import { getForwards } from './forwards';
import { getResume } from './resume';
export const invoiceQueries = {
getInvoices,
getPayments,
getResume,
getForwards,
};

View file

@ -1,102 +0,0 @@
import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql';
import { getInvoices as getLnInvoices } from 'ln-service';
import { logger } from '../../../helpers/logger';
import { requestLimiter } from '../../../helpers/rateLimiter';
import { GetInvoiceType } from '../../../schemaTypes/query/info/invoices';
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
interface PaymentProps {
confirmed_at: string;
created_at: string;
created_height: number;
in_channel: string;
is_canceled: boolean;
is_confirmed: boolean;
is_held: boolean;
mtokens: string;
pending_index: number;
tokens: number;
}
interface InvoiceProps {
chain_address: string;
confirmed_at: string;
created_at: string;
description: string;
description_hash: string;
expires_at: string;
id: string;
is_canceled: boolean;
is_confirmed: boolean;
is_held: boolean;
is_outgoing: boolean;
is_private: boolean;
payments: PaymentProps[];
received: number;
received_mtokens: string;
request: string;
secret: string;
tokens: number;
}
interface InvoicesProps {
invoices: InvoiceProps[];
next: string;
}
export const getInvoices = {
type: new GraphQLList(GetInvoiceType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, 'invoices');
const lnd = getAuthLnd(params.auth);
try {
const invoiceList: InvoicesProps = await getLnInvoices({
lnd: lnd,
});
const invoices = invoiceList.invoices.map(invoice => {
const payments = invoice.payments.map(payment => ({
confirmedAt: payment.confirmed_at,
createdAt: payment.created_at,
createdHeight: payment.created_height,
inChannel: payment.in_channel,
isCanceled: payment.is_canceled,
isConfirmed: payment.is_confirmed,
isHeld: payment.is_held,
mtokens: payment.mtokens,
pendingIndex: payment.pending_index,
tokens: payment.tokens,
}));
return {
chainAddress: invoice.chain_address,
confirmedAt: invoice.confirmed_at,
createdAt: invoice.created_at,
description: invoice.description,
descriptionHash: invoice.description_hash,
expiresAt: invoice.expires_at,
id: invoice.id,
isCanceled: invoice.is_canceled,
isConfirmed: invoice.is_confirmed,
isHeld: invoice.is_held,
isOutgoing: invoice.is_outgoing,
isPrivate: invoice.is_private,
payments: payments,
received: invoice.received,
receivedMtokens: invoice.received_mtokens,
request: invoice.request,
secret: invoice.secret,
tokens: invoice.tokens,
};
});
return invoices;
} catch (error) {
logger.error('Error getting invoices: %o', error);
throw new Error(getErrorMsg(error));
}
},
};

View file

@ -1,61 +0,0 @@
import { GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql';
import { getPayments as getLnPayments } from 'ln-service';
import { logger } from '../../../helpers/logger';
import { requestLimiter } from '../../../helpers/rateLimiter';
import { GetPaymentType } from '../../../schemaTypes/query/info/payments';
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
interface PaymentProps {
created_at: string;
destination: string;
fee: number;
fee_mtokens: string;
hops: string[];
id: string;
is_confirmed: boolean;
is_outgoing: boolean;
mtokens: string;
request: string;
secret: string;
tokens: number;
}
interface PaymentsProps {
payments: PaymentProps[];
}
export const getPayments = {
type: new GraphQLList(GetPaymentType),
args: { auth: { type: new GraphQLNonNull(GraphQLString) } },
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, 'payments');
const lnd = getAuthLnd(params.auth);
try {
const paymentList: PaymentsProps = await getLnPayments({
lnd: lnd,
});
const payments = paymentList.payments.map(payment => ({
createdAt: payment.created_at,
destination: payment.destination,
fee: payment.fee,
feeMtokens: payment.fee_mtokens,
hops: payment.hops,
id: payment.id,
isConfirmed: payment.is_confirmed,
isOutgoing: payment.is_outgoing,
mtokens: payment.mtokens,
request: payment.request,
secret: payment.secret,
tokens: payment.tokens,
}));
return payments;
} catch (error) {
logger.error('Error getting payments: %o', error);
throw new Error(getErrorMsg(error));
}
},
};

View file

@ -0,0 +1,61 @@
export interface PaymentProps {
created_at: string;
destination: string;
fee: number;
fee_mtokens: string;
hops: string[];
id: string;
is_confirmed: boolean;
is_outgoing: boolean;
mtokens: string;
request: string;
secret: string;
tokens: number;
}
export interface PaymentsProps {
payments: PaymentProps[];
}
export interface InvoicePaymentProps {
confirmed_at: string;
created_at: string;
created_height: number;
in_channel: string;
is_canceled: boolean;
is_confirmed: boolean;
is_held: boolean;
mtokens: string;
pending_index: number;
tokens: number;
}
export interface InvoiceProps {
chain_address: string;
confirmed_at: string;
created_at: string;
description: string;
description_hash: string;
expires_at: string;
id: string;
is_canceled: boolean;
is_confirmed: boolean;
is_held: boolean;
is_outgoing: boolean;
is_private: boolean;
payments: InvoicePaymentProps[];
received: number;
received_mtokens: string;
request: string;
secret: string;
tokens: number;
}
export interface InvoicesProps {
invoices: InvoiceProps[];
next: string;
}
export interface NodeProps {
alias: string;
}

View file

@ -0,0 +1,112 @@
import { GraphQLNonNull, GraphQLString } from 'graphql';
import { getPayments, getInvoices, getNode } from 'ln-service';
import { logger } from '../../../helpers/logger';
import { requestLimiter } from '../../../helpers/rateLimiter';
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
import { PaymentsProps, InvoicesProps, NodeProps } from './resume.interface';
import { compareDesc } from 'date-fns';
import { sortBy } from 'underscore';
import { GetResumeType } from '../../../schemaTypes/query/invoices/resume';
export const getResume = {
type: GetResumeType,
args: {
auth: { type: new GraphQLNonNull(GraphQLString) },
token: { type: GraphQLString },
},
resolve: async (root: any, params: any, context: any) => {
await requestLimiter(context.ip, 'payments');
const lnd = getAuthLnd(params.auth);
let payments;
let invoices;
try {
const paymentList: PaymentsProps = await getPayments({
lnd: lnd,
});
const getMappedPayments = () =>
Promise.all(
paymentList.payments.map(async payment => {
let nodeInfo: NodeProps;
try {
nodeInfo = await getNode({
lnd,
is_omitting_channels: true,
public_key: payment.destination,
});
} catch (error) {
nodeInfo = { alias: 'unknown' };
}
return {
type: 'payment',
alias: nodeInfo.alias,
date: payment.created_at,
...payment,
};
}),
);
payments = await getMappedPayments();
} catch (error) {
logger.error('Error getting payments: %o', error);
throw new Error(getErrorMsg(error));
}
const invoiceProps = params.token
? { token: params.token }
: { limit: 10 };
let lastInvoiceDate = '';
let firstInvoiceDate = '';
let token = '';
try {
const invoiceList: InvoicesProps = await getInvoices({
lnd: lnd,
...invoiceProps,
});
invoices = invoiceList.invoices.map(invoice => {
return {
type: 'invoice',
date: invoice.confirmed_at || invoice.created_at,
...invoice,
};
});
const { date } = invoices[invoices.length - 1];
firstInvoiceDate = invoices[0].date;
lastInvoiceDate = date;
token = invoiceList.next;
} catch (error) {
logger.error('Error getting invoices: %o', error);
throw new Error(getErrorMsg(error));
}
const filteredPayments = payments.filter(payment => {
const last =
compareDesc(
new Date(lastInvoiceDate),
new Date(payment.date),
) === 1;
const first =
compareDesc(
new Date(payment.date),
new Date(firstInvoiceDate),
) === 1;
return last && first;
});
const resumeArray = sortBy(
[...invoices, ...filteredPayments],
'date',
).reverse();
return {
token,
resume: JSON.stringify(resumeArray),
};
},
};