mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-23 06:35:05 +01:00
feat: ✨ add leaderboard (#119)
* feat: ✨ add leaderboard * chore: 🔧 add leaderboard * chore: 🔧 leaderboard card * style: 🎨 node card * chore: 🔧 cleanup * chore: 🔧 remove ssr query
This commit is contained in:
parent
f9ba0b64fe
commit
f985e51b98
39 changed files with 783 additions and 420 deletions
20
package-lock.json
generated
20
package-lock.json
generated
|
@ -3420,6 +3420,12 @@
|
||||||
"universalify": "^1.0.0"
|
"universalify": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"graphql-request": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ww3Ax+G3l2d+mPT8w7HC9LfrKjutnCKtnDq7ZZp2ghVk5IQDjwAk3/arRF1ix17Ky15rm0hrSKVKxRhIVlSuoQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
@ -10104,7 +10110,6 @@
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz",
|
||||||
"integrity": "sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==",
|
"integrity": "sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-fetch": "2.6.0",
|
"node-fetch": "2.6.0",
|
||||||
"whatwg-fetch": "3.0.0"
|
"whatwg-fetch": "3.0.0"
|
||||||
|
@ -13678,10 +13683,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"graphql-request": {
|
"graphql-request": {
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.0.0.tgz",
|
||||||
"integrity": "sha512-Ww3Ax+G3l2d+mPT8w7HC9LfrKjutnCKtnDq7ZZp2ghVk5IQDjwAk3/arRF1ix17Ky15rm0hrSKVKxRhIVlSuoQ==",
|
"integrity": "sha512-zW8AuLnKMYOnpVKdANU9FzLDoj4u4AoU6KZ79e+BcJaNiuw/vgCJ0p7ppDMSDrW77a12Moa7J7Mg4w0f9Kd/Kg==",
|
||||||
"dev": true
|
"requires": {
|
||||||
|
"cross-fetch": "^3.0.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"graphql-shield": {
|
"graphql-shield": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
|
@ -26475,8 +26482,7 @@
|
||||||
"whatwg-fetch": {
|
"whatwg-fetch": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
||||||
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
|
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"whatwg-mimetype": {
|
"whatwg-mimetype": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
"graphql": "^15.3.0",
|
"graphql": "^15.3.0",
|
||||||
"graphql-iso-date": "^3.6.1",
|
"graphql-iso-date": "^3.6.1",
|
||||||
"graphql-rate-limit": "^2.0.1",
|
"graphql-rate-limit": "^2.0.1",
|
||||||
|
"graphql-request": "^3.0.0",
|
||||||
"intersection-observer": "^0.11.0",
|
"intersection-observer": "^0.11.0",
|
||||||
"js-cookie": "^2.2.1",
|
"js-cookie": "^2.2.1",
|
||||||
"js-yaml": "^3.14.0",
|
"js-yaml": "^3.14.0",
|
||||||
|
|
|
@ -38,11 +38,6 @@ export default class MyDocument extends Document {
|
||||||
return (
|
return (
|
||||||
<Html>
|
<Html>
|
||||||
<Head>
|
<Head>
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="initial-scale=1.0, width=device-width"
|
|
||||||
key="viewport"
|
|
||||||
/>
|
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Manage and monitor your lightning network node right inside your browser"
|
content="Manage and monitor your lightning network node right inside your browser"
|
||||||
|
|
58
pages/leaderboard.tsx
Normal file
58
pages/leaderboard.tsx
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
|
||||||
|
import { NextPageContext } from 'next';
|
||||||
|
import { getProps } from 'src/utils/ssr';
|
||||||
|
import { GET_BASE_POINTS } from 'src/graphql/queries/getBasePoints';
|
||||||
|
import { useGetBasePointsQuery } from 'src/graphql/queries/__generated__/getBasePoints.generated';
|
||||||
|
import { NodeCard } from 'src/views/leaderboard/NodeCard';
|
||||||
|
import { SupportBar } from 'src/views/home/quickActions/donate/DonateContent';
|
||||||
|
import {
|
||||||
|
CardWithTitle,
|
||||||
|
SubTitle,
|
||||||
|
Card,
|
||||||
|
} from '../src/components/generic/Styled';
|
||||||
|
import { LoadingCard } from '../src/components/loading/LoadingCard';
|
||||||
|
|
||||||
|
const LeaderboardView = () => {
|
||||||
|
const { loading, data } = useGetBasePointsQuery();
|
||||||
|
|
||||||
|
const renderBoard = () => {
|
||||||
|
if (loading || !data?.getBasePoints) {
|
||||||
|
return <LoadingCard title={'Supporters'} />;
|
||||||
|
}
|
||||||
|
if (!data.getBasePoints.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<CardWithTitle>
|
||||||
|
<SubTitle>Supporters</SubTitle>
|
||||||
|
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||||
|
{data.getBasePoints.map((node, index: number) => (
|
||||||
|
<React.Fragment key={index}>
|
||||||
|
<NodeCard node={node} index={index + 1} />
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
</CardWithTitle>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SupportBar />
|
||||||
|
{renderBoard()}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Wrapped = () => (
|
||||||
|
<GridWrapper>
|
||||||
|
<LeaderboardView />
|
||||||
|
</GridWrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Wrapped;
|
||||||
|
|
||||||
|
export async function getServerSideProps(context: NextPageContext) {
|
||||||
|
return await getProps(context, [GET_BASE_POINTS]);
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import { Bakery } from 'src/views/tools/bakery/Bakery';
|
||||||
import { Accounting } from 'src/views/tools/accounting/Accounting';
|
import { Accounting } from 'src/views/tools/accounting/Accounting';
|
||||||
import { NextPageContext } from 'next';
|
import { NextPageContext } from 'next';
|
||||||
import { getProps } from 'src/utils/ssr';
|
import { getProps } from 'src/utils/ssr';
|
||||||
import { GET_WALLET_INFO } from 'src/graphql/queries/getWalletInfo';
|
|
||||||
import { BackupsView } from '../src/views/tools/backups/Backups';
|
import { BackupsView } from '../src/views/tools/backups/Backups';
|
||||||
import { MessagesView } from '../src/views/tools/messages/Messages';
|
import { MessagesView } from '../src/views/tools/messages/Messages';
|
||||||
import { WalletVersion } from '../src/views/tools/WalletVersion';
|
import { WalletVersion } from '../src/views/tools/WalletVersion';
|
||||||
|
@ -28,5 +27,5 @@ const Wrapped = () => (
|
||||||
export default Wrapped;
|
export default Wrapped;
|
||||||
|
|
||||||
export async function getServerSideProps(context: NextPageContext) {
|
export async function getServerSideProps(context: NextPageContext) {
|
||||||
return await getProps(context, [GET_WALLET_INFO]);
|
return await getProps(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ import { authResolvers } from './auth/resolvers';
|
||||||
import { generalTypes, queryTypes, mutationTypes } from './types';
|
import { generalTypes, queryTypes, mutationTypes } from './types';
|
||||||
import { accountResolvers } from './account/resolvers';
|
import { accountResolvers } from './account/resolvers';
|
||||||
import { accountTypes } from './account/types';
|
import { accountTypes } from './account/types';
|
||||||
import { lnpayResolvers } from './lnpay/resolvers';
|
|
||||||
import { lnpayTypes } from './lnpay/types';
|
|
||||||
import { bitcoinResolvers } from './bitcoin/resolvers';
|
import { bitcoinResolvers } from './bitcoin/resolvers';
|
||||||
import { bitcoinTypes } from './bitcoin/types';
|
import { bitcoinTypes } from './bitcoin/types';
|
||||||
import { peerTypes } from './peer/types';
|
import { peerTypes } from './peer/types';
|
||||||
|
@ -47,7 +45,6 @@ const typeDefs = [
|
||||||
mutationTypes,
|
mutationTypes,
|
||||||
nodeTypes,
|
nodeTypes,
|
||||||
accountTypes,
|
accountTypes,
|
||||||
lnpayTypes,
|
|
||||||
bitcoinTypes,
|
bitcoinTypes,
|
||||||
peerTypes,
|
peerTypes,
|
||||||
chainTypes,
|
chainTypes,
|
||||||
|
@ -69,7 +66,6 @@ const resolvers = merge(
|
||||||
nodeResolvers,
|
nodeResolvers,
|
||||||
authResolvers,
|
authResolvers,
|
||||||
accountResolvers,
|
accountResolvers,
|
||||||
lnpayResolvers,
|
|
||||||
bitcoinResolvers,
|
bitcoinResolvers,
|
||||||
peerResolvers,
|
peerResolvers,
|
||||||
routeResolvers,
|
routeResolvers,
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`LnPay Resolvers getLnPay failure 1`] = `
|
|
||||||
Object {
|
|
||||||
"data": Object {
|
|
||||||
"getLnPay": null,
|
|
||||||
},
|
|
||||||
"errors": Array [
|
|
||||||
[GraphQLError: NoLnPayInvoice],
|
|
||||||
],
|
|
||||||
"extensions": undefined,
|
|
||||||
"http": Object {
|
|
||||||
"headers": Headers {
|
|
||||||
Symbol(map): Object {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`LnPay Resolvers getLnPay success 1`] = `
|
|
||||||
Object {
|
|
||||||
"data": Object {
|
|
||||||
"getLnPay": "paymentRequest",
|
|
||||||
},
|
|
||||||
"errors": undefined,
|
|
||||||
"extensions": undefined,
|
|
||||||
"http": Object {
|
|
||||||
"headers": Headers {
|
|
||||||
Symbol(map): Object {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`LnPay Resolvers getLnPayInfo failure 1`] = `
|
|
||||||
Object {
|
|
||||||
"data": Object {
|
|
||||||
"getLnPayInfo": null,
|
|
||||||
},
|
|
||||||
"errors": Array [
|
|
||||||
[GraphQLError: NoLnPay],
|
|
||||||
],
|
|
||||||
"extensions": undefined,
|
|
||||||
"http": Object {
|
|
||||||
"headers": Headers {
|
|
||||||
Symbol(map): Object {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`LnPay Resolvers getLnPayInfo success 1`] = `
|
|
||||||
Object {
|
|
||||||
"data": Object {
|
|
||||||
"getLnPayInfo": Object {
|
|
||||||
"max": 1000,
|
|
||||||
"min": 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"errors": undefined,
|
|
||||||
"extensions": undefined,
|
|
||||||
"http": Object {
|
|
||||||
"headers": Headers {
|
|
||||||
Symbol(map): Object {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -1,68 +0,0 @@
|
||||||
import testServer from 'server/tests/testServer';
|
|
||||||
import { GET_LN_PAY } from 'src/graphql/queries/getLnPay';
|
|
||||||
import fetchMock from 'jest-fetch-mock';
|
|
||||||
import { GraphQLError } from 'graphql';
|
|
||||||
import { GET_LN_PAY_INFO } from 'src/graphql/queries/getLnPayInfo';
|
|
||||||
|
|
||||||
describe('LnPay Resolvers', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
fetchMock.resetMocks();
|
|
||||||
});
|
|
||||||
describe('getLnPay', () => {
|
|
||||||
test('success', async () => {
|
|
||||||
fetchMock.mockResponseOnce(JSON.stringify({ pr: 'paymentRequest' }));
|
|
||||||
const { query } = testServer();
|
|
||||||
|
|
||||||
const res = await query({
|
|
||||||
query: GET_LN_PAY,
|
|
||||||
variables: { amount: 100 },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(res.errors).toBe(undefined);
|
|
||||||
|
|
||||||
expect(fetchMock).toBeCalledWith(
|
|
||||||
'https://thunderhub.io/api/lnpay?amount=100'
|
|
||||||
);
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
test('failure', async () => {
|
|
||||||
fetchMock.mockRejectOnce(new Error('Error'));
|
|
||||||
const { query } = testServer();
|
|
||||||
|
|
||||||
const res = await query({
|
|
||||||
query: GET_LN_PAY,
|
|
||||||
variables: { amount: 100 },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(res.errors).toStrictEqual([new GraphQLError('NoLnPayInvoice')]);
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe('getLnPayInfo', () => {
|
|
||||||
test('success', async () => {
|
|
||||||
fetchMock.mockResponseOnce(
|
|
||||||
JSON.stringify({ maxSendable: 1000, minSendable: 1 })
|
|
||||||
);
|
|
||||||
const { query } = testServer();
|
|
||||||
|
|
||||||
const res = await query({
|
|
||||||
query: GET_LN_PAY_INFO,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(res.errors).toBe(undefined);
|
|
||||||
expect(fetchMock).toBeCalledWith('https://thunderhub.io/api/lnpay');
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
test('failure', async () => {
|
|
||||||
fetchMock.mockRejectOnce(new Error('Error'));
|
|
||||||
const { query } = testServer();
|
|
||||||
|
|
||||||
const res = await query({
|
|
||||||
query: GET_LN_PAY_INFO,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(res.errors).toStrictEqual([new GraphQLError('NoLnPay')]);
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,43 +0,0 @@
|
||||||
import { ContextType } from 'server/types/apiTypes';
|
|
||||||
import { toWithError } from 'server/helpers/async';
|
|
||||||
import { logger } from 'server/helpers/logger';
|
|
||||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
|
||||||
import { appUrls } from 'server/utils/appUrls';
|
|
||||||
|
|
||||||
export const lnpayResolvers = {
|
|
||||||
Query: {
|
|
||||||
getLnPay: async (
|
|
||||||
_: undefined,
|
|
||||||
params: { amount: number },
|
|
||||||
context: ContextType
|
|
||||||
) => {
|
|
||||||
await requestLimiter(context.ip, 'getLnPay');
|
|
||||||
|
|
||||||
const [response, error] = await toWithError(
|
|
||||||
fetch(`${appUrls.lnpay}?amount=${params.amount}`)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (error || !response) {
|
|
||||||
logger.debug('Unable to get lnpay invoice: %o', error);
|
|
||||||
throw new Error('NoLnPayInvoice');
|
|
||||||
}
|
|
||||||
|
|
||||||
const json = await response.json();
|
|
||||||
return json.pr || null;
|
|
||||||
},
|
|
||||||
getLnPayInfo: async (_: undefined, params: any, context: ContextType) => {
|
|
||||||
await requestLimiter(context.ip, 'getLnPayInfo');
|
|
||||||
|
|
||||||
const [response, error] = await toWithError(fetch(appUrls.lnpay));
|
|
||||||
|
|
||||||
if (error || !response) {
|
|
||||||
logger.debug('Unable to connect to ThunderHub LNPAY');
|
|
||||||
throw new Error('NoLnPay');
|
|
||||||
}
|
|
||||||
|
|
||||||
const json = await response.json();
|
|
||||||
|
|
||||||
return { max: json.maxSendable, min: json.minSendable };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { gql } from 'apollo-server-micro';
|
|
||||||
|
|
||||||
export const lnpayTypes = gql`
|
|
||||||
type lnPayInfoType {
|
|
||||||
max: Int
|
|
||||||
min: Int
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -2,34 +2,129 @@ import { ContextType } from 'server/types/apiTypes';
|
||||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||||
import { toWithError } from 'server/helpers/async';
|
import { toWithError } from 'server/helpers/async';
|
||||||
import { appUrls } from 'server/utils/appUrls';
|
import { appUrls } from 'server/utils/appUrls';
|
||||||
|
import { request, gql } from 'graphql-request';
|
||||||
|
|
||||||
|
const getBaseCanConnectQuery = gql`
|
||||||
|
{
|
||||||
|
hello
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const getBaseNodesQuery = gql`
|
||||||
|
{
|
||||||
|
getNodes {
|
||||||
|
_id
|
||||||
|
name
|
||||||
|
public_key
|
||||||
|
socket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const getBasePointsQuery = gql`
|
||||||
|
{
|
||||||
|
getPoints {
|
||||||
|
alias
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const createBaseInvoiceQuery = gql`
|
||||||
|
mutation CreateInvoice($amount: Int!) {
|
||||||
|
createInvoice(amount: $amount) {
|
||||||
|
request
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const createThunderPointsQuery = gql`
|
||||||
|
mutation CreatePoints(
|
||||||
|
$id: String!
|
||||||
|
$alias: String!
|
||||||
|
$uris: [String!]!
|
||||||
|
$public_key: String!
|
||||||
|
) {
|
||||||
|
createPoints(id: $id, alias: $alias, uris: $uris, public_key: $public_key)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const tbaseResolvers = {
|
export const tbaseResolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
getBaseNodes: async (_: undefined, params: any, context: ContextType) => {
|
getBaseCanConnect: async (
|
||||||
|
_: undefined,
|
||||||
|
__: undefined,
|
||||||
|
context: ContextType
|
||||||
|
): Promise<boolean> => {
|
||||||
|
await requestLimiter(context.ip, 'getBaseCanConnect');
|
||||||
|
|
||||||
|
const [data, error] = await toWithError(
|
||||||
|
request(appUrls.tbase, getBaseCanConnectQuery)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error || !data?.hello) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
getBaseNodes: async (_: undefined, __: any, context: ContextType) => {
|
||||||
await requestLimiter(context.ip, 'getBaseNodes');
|
await requestLimiter(context.ip, 'getBaseNodes');
|
||||||
|
|
||||||
const query = '{getNodes {_id, name, public_key, socket}}';
|
const [data, error] = await toWithError(
|
||||||
|
request(appUrls.tbase, getBaseNodesQuery)
|
||||||
|
);
|
||||||
|
|
||||||
const [response, fetchError] = await toWithError(
|
if (error || !data?.getNodes) return [];
|
||||||
fetch(appUrls.tbase, {
|
|
||||||
method: 'post',
|
return data.getNodes.filter(
|
||||||
headers: {
|
(n: { public_key: string; socket: string }) => n.public_key && n.socket
|
||||||
'Content-Type': 'application/json',
|
);
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ query }),
|
getBasePoints: async (_: undefined, __: any, context: ContextType) => {
|
||||||
})
|
await requestLimiter(context.ip, 'getBasePoints');
|
||||||
);
|
|
||||||
if (fetchError || !response) return [];
|
|
||||||
const result = await response.json();
|
|
||||||
const { errors, data } = result || {};
|
|
||||||
if (errors) return [];
|
|
||||||
|
|
||||||
return (
|
const [data, error] = await toWithError(
|
||||||
data?.getNodes?.filter(
|
request(appUrls.tbase, getBasePointsQuery)
|
||||||
(n: { public_key: string; socket: string }) =>
|
|
||||||
n.public_key && n.socket
|
|
||||||
) || []
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (error || !data?.getPoints) return [];
|
||||||
|
|
||||||
|
return data.getPoints;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Mutation: {
|
||||||
|
createBaseInvoice: async (
|
||||||
|
_: undefined,
|
||||||
|
params: { amount: number },
|
||||||
|
context: ContextType
|
||||||
|
) => {
|
||||||
|
await requestLimiter(context.ip, 'getBaseInvoice');
|
||||||
|
|
||||||
|
if (!params?.amount) return '';
|
||||||
|
|
||||||
|
const [data, error] = await toWithError(
|
||||||
|
request(appUrls.tbase, createBaseInvoiceQuery, params)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) return null;
|
||||||
|
if (data?.createInvoice) return data.createInvoice;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
createThunderPoints: async (
|
||||||
|
_: undefined,
|
||||||
|
params: { id: string; alias: string; uris: string[]; public_key: string },
|
||||||
|
context: ContextType
|
||||||
|
): Promise<boolean> => {
|
||||||
|
await requestLimiter(context.ip, 'getThunderPoints');
|
||||||
|
|
||||||
|
const [info, error] = await toWithError(
|
||||||
|
request(appUrls.tbase, createThunderPointsQuery, params)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error || !info?.createPoints) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,4 +7,14 @@ export const tbaseTypes = gql`
|
||||||
public_key: String!
|
public_key: String!
|
||||||
socket: String!
|
socket: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type basePointsType {
|
||||||
|
alias: String!
|
||||||
|
amount: Int!
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseInvoiceType {
|
||||||
|
id: String!
|
||||||
|
request: String!
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -28,7 +28,9 @@ export const generalTypes = gql`
|
||||||
|
|
||||||
export const queryTypes = gql`
|
export const queryTypes = gql`
|
||||||
type Query {
|
type Query {
|
||||||
|
getBaseCanConnect: Boolean!
|
||||||
getBaseNodes: [baseNodesType]!
|
getBaseNodes: [baseNodesType]!
|
||||||
|
getBasePoints: [basePointsType]!
|
||||||
getAccountingReport(
|
getAccountingReport(
|
||||||
category: String
|
category: String
|
||||||
currency: String
|
currency: String
|
||||||
|
@ -83,14 +85,19 @@ export const queryTypes = gql`
|
||||||
getSessionToken(id: String, password: String): Boolean
|
getSessionToken(id: String, password: String): Boolean
|
||||||
getServerAccounts: [serverAccountType]
|
getServerAccounts: [serverAccountType]
|
||||||
getAccount: serverAccountType
|
getAccount: serverAccountType
|
||||||
getLnPayInfo: lnPayInfoType
|
|
||||||
getLnPay(amount: Int): String
|
|
||||||
getLatestVersion: String
|
getLatestVersion: String
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const mutationTypes = gql`
|
export const mutationTypes = gql`
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
createBaseInvoice(amount: Int!): baseInvoiceType
|
||||||
|
createThunderPoints(
|
||||||
|
id: String!
|
||||||
|
alias: String!
|
||||||
|
uris: [String!]!
|
||||||
|
public_key: String!
|
||||||
|
): Boolean!
|
||||||
closeChannel(
|
closeChannel(
|
||||||
id: String!
|
id: String!
|
||||||
forceClose: Boolean
|
forceClose: Boolean
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
const lnpay =
|
|
||||||
process.env.NODE_ENV === 'development'
|
|
||||||
? 'http://localhost:3001/api/lnpay'
|
|
||||||
: 'https://thunderhub.io/api/lnpay';
|
|
||||||
|
|
||||||
const tbase =
|
const tbase =
|
||||||
process.env.NODE_ENV === 'development'
|
process.env.NODE_ENV === 'development'
|
||||||
? 'http://localhost:3010/dev/v1'
|
? 'http://localhost:3010/dev/v1'
|
||||||
: 'https://api.thunderbase.io/v1';
|
: 'https://api.thunderbase.io/v1';
|
||||||
|
|
||||||
export const appUrls = {
|
export const appUrls = {
|
||||||
lnpay,
|
|
||||||
tbase,
|
tbase,
|
||||||
oneml: 'https://1ml.com/node/',
|
oneml: 'https://1ml.com/node/',
|
||||||
blockchain: 'https://www.blockchain.com/btc/tx/',
|
blockchain: 'https://www.blockchain.com/btc/tx/',
|
||||||
|
|
69
src/graphql/mutations/__generated__/createBaseInvoice.generated.tsx
generated
Normal file
69
src/graphql/mutations/__generated__/createBaseInvoice.generated.tsx
generated
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
import * as Types from '../../types';
|
||||||
|
|
||||||
|
const gql = Apollo.gql;
|
||||||
|
|
||||||
|
export type CreateBaseInvoiceMutationVariables = Types.Exact<{
|
||||||
|
amount: Types.Scalars['Int'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type CreateBaseInvoiceMutation = { __typename?: 'Mutation' } & {
|
||||||
|
createBaseInvoice?: Types.Maybe<
|
||||||
|
{ __typename?: 'baseInvoiceType' } & Pick<
|
||||||
|
Types.BaseInvoiceType,
|
||||||
|
'request' | 'id'
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CreateBaseInvoiceDocument = gql`
|
||||||
|
mutation CreateBaseInvoice($amount: Int!) {
|
||||||
|
createBaseInvoice(amount: $amount) {
|
||||||
|
request
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type CreateBaseInvoiceMutationFn = Apollo.MutationFunction<
|
||||||
|
CreateBaseInvoiceMutation,
|
||||||
|
CreateBaseInvoiceMutationVariables
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useCreateBaseInvoiceMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useCreateBaseInvoiceMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useCreateBaseInvoiceMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [createBaseInvoiceMutation, { data, loading, error }] = useCreateBaseInvoiceMutation({
|
||||||
|
* variables: {
|
||||||
|
* amount: // value for 'amount'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useCreateBaseInvoiceMutation(
|
||||||
|
baseOptions?: Apollo.MutationHookOptions<
|
||||||
|
CreateBaseInvoiceMutation,
|
||||||
|
CreateBaseInvoiceMutationVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useMutation<
|
||||||
|
CreateBaseInvoiceMutation,
|
||||||
|
CreateBaseInvoiceMutationVariables
|
||||||
|
>(CreateBaseInvoiceDocument, baseOptions);
|
||||||
|
}
|
||||||
|
export type CreateBaseInvoiceMutationHookResult = ReturnType<
|
||||||
|
typeof useCreateBaseInvoiceMutation
|
||||||
|
>;
|
||||||
|
export type CreateBaseInvoiceMutationResult = Apollo.MutationResult<
|
||||||
|
CreateBaseInvoiceMutation
|
||||||
|
>;
|
||||||
|
export type CreateBaseInvoiceMutationOptions = Apollo.BaseMutationOptions<
|
||||||
|
CreateBaseInvoiceMutation,
|
||||||
|
CreateBaseInvoiceMutationVariables
|
||||||
|
>;
|
78
src/graphql/mutations/__generated__/createThunderPoints.generated.tsx
generated
Normal file
78
src/graphql/mutations/__generated__/createThunderPoints.generated.tsx
generated
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
import * as Types from '../../types';
|
||||||
|
|
||||||
|
const gql = Apollo.gql;
|
||||||
|
|
||||||
|
export type CreateThunderPointsMutationVariables = Types.Exact<{
|
||||||
|
id: Types.Scalars['String'];
|
||||||
|
alias: Types.Scalars['String'];
|
||||||
|
uris: Array<Types.Scalars['String']>;
|
||||||
|
public_key: Types.Scalars['String'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type CreateThunderPointsMutation = { __typename?: 'Mutation' } & Pick<
|
||||||
|
Types.Mutation,
|
||||||
|
'createThunderPoints'
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const CreateThunderPointsDocument = gql`
|
||||||
|
mutation CreateThunderPoints(
|
||||||
|
$id: String!
|
||||||
|
$alias: String!
|
||||||
|
$uris: [String!]!
|
||||||
|
$public_key: String!
|
||||||
|
) {
|
||||||
|
createThunderPoints(
|
||||||
|
id: $id
|
||||||
|
alias: $alias
|
||||||
|
uris: $uris
|
||||||
|
public_key: $public_key
|
||||||
|
)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type CreateThunderPointsMutationFn = Apollo.MutationFunction<
|
||||||
|
CreateThunderPointsMutation,
|
||||||
|
CreateThunderPointsMutationVariables
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useCreateThunderPointsMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useCreateThunderPointsMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useCreateThunderPointsMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [createThunderPointsMutation, { data, loading, error }] = useCreateThunderPointsMutation({
|
||||||
|
* variables: {
|
||||||
|
* id: // value for 'id'
|
||||||
|
* alias: // value for 'alias'
|
||||||
|
* uris: // value for 'uris'
|
||||||
|
* public_key: // value for 'public_key'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useCreateThunderPointsMutation(
|
||||||
|
baseOptions?: Apollo.MutationHookOptions<
|
||||||
|
CreateThunderPointsMutation,
|
||||||
|
CreateThunderPointsMutationVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useMutation<
|
||||||
|
CreateThunderPointsMutation,
|
||||||
|
CreateThunderPointsMutationVariables
|
||||||
|
>(CreateThunderPointsDocument, baseOptions);
|
||||||
|
}
|
||||||
|
export type CreateThunderPointsMutationHookResult = ReturnType<
|
||||||
|
typeof useCreateThunderPointsMutation
|
||||||
|
>;
|
||||||
|
export type CreateThunderPointsMutationResult = Apollo.MutationResult<
|
||||||
|
CreateThunderPointsMutation
|
||||||
|
>;
|
||||||
|
export type CreateThunderPointsMutationOptions = Apollo.BaseMutationOptions<
|
||||||
|
CreateThunderPointsMutation,
|
||||||
|
CreateThunderPointsMutationVariables
|
||||||
|
>;
|
10
src/graphql/mutations/createBaseInvoice.ts
Normal file
10
src/graphql/mutations/createBaseInvoice.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const CREATE_BASE_INVOICE = gql`
|
||||||
|
mutation CreateBaseInvoice($amount: Int!) {
|
||||||
|
createBaseInvoice(amount: $amount) {
|
||||||
|
request
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
17
src/graphql/mutations/createThunderPoints.ts
Normal file
17
src/graphql/mutations/createThunderPoints.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const CREATE_THUNDER_POINTS = gql`
|
||||||
|
mutation CreateThunderPoints(
|
||||||
|
$id: String!
|
||||||
|
$alias: String!
|
||||||
|
$uris: [String!]!
|
||||||
|
$public_key: String!
|
||||||
|
) {
|
||||||
|
createThunderPoints(
|
||||||
|
id: $id
|
||||||
|
alias: $alias
|
||||||
|
uris: $uris
|
||||||
|
public_key: $public_key
|
||||||
|
)
|
||||||
|
}
|
||||||
|
`;
|
67
src/graphql/queries/__generated__/getBaseCanConnect.generated.tsx
generated
Normal file
67
src/graphql/queries/__generated__/getBaseCanConnect.generated.tsx
generated
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
import * as Types from '../../types';
|
||||||
|
|
||||||
|
const gql = Apollo.gql;
|
||||||
|
|
||||||
|
export type GetBaseCanConnectQueryVariables = Types.Exact<{
|
||||||
|
[key: string]: never;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type GetBaseCanConnectQuery = { __typename?: 'Query' } & Pick<
|
||||||
|
Types.Query,
|
||||||
|
'getBaseCanConnect'
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const GetBaseCanConnectDocument = gql`
|
||||||
|
query GetBaseCanConnect {
|
||||||
|
getBaseCanConnect
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetBaseCanConnectQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetBaseCanConnectQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetBaseCanConnectQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetBaseCanConnectQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetBaseCanConnectQuery(
|
||||||
|
baseOptions?: Apollo.QueryHookOptions<
|
||||||
|
GetBaseCanConnectQuery,
|
||||||
|
GetBaseCanConnectQueryVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useQuery<
|
||||||
|
GetBaseCanConnectQuery,
|
||||||
|
GetBaseCanConnectQueryVariables
|
||||||
|
>(GetBaseCanConnectDocument, baseOptions);
|
||||||
|
}
|
||||||
|
export function useGetBaseCanConnectLazyQuery(
|
||||||
|
baseOptions?: Apollo.LazyQueryHookOptions<
|
||||||
|
GetBaseCanConnectQuery,
|
||||||
|
GetBaseCanConnectQueryVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useLazyQuery<
|
||||||
|
GetBaseCanConnectQuery,
|
||||||
|
GetBaseCanConnectQueryVariables
|
||||||
|
>(GetBaseCanConnectDocument, baseOptions);
|
||||||
|
}
|
||||||
|
export type GetBaseCanConnectQueryHookResult = ReturnType<
|
||||||
|
typeof useGetBaseCanConnectQuery
|
||||||
|
>;
|
||||||
|
export type GetBaseCanConnectLazyQueryHookResult = ReturnType<
|
||||||
|
typeof useGetBaseCanConnectLazyQuery
|
||||||
|
>;
|
||||||
|
export type GetBaseCanConnectQueryResult = Apollo.QueryResult<
|
||||||
|
GetBaseCanConnectQuery,
|
||||||
|
GetBaseCanConnectQueryVariables
|
||||||
|
>;
|
74
src/graphql/queries/__generated__/getBasePoints.generated.tsx
generated
Normal file
74
src/graphql/queries/__generated__/getBasePoints.generated.tsx
generated
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
import * as Types from '../../types';
|
||||||
|
|
||||||
|
const gql = Apollo.gql;
|
||||||
|
|
||||||
|
export type GetBasePointsQueryVariables = Types.Exact<{ [key: string]: never }>;
|
||||||
|
|
||||||
|
export type GetBasePointsQuery = { __typename?: 'Query' } & {
|
||||||
|
getBasePoints: Array<
|
||||||
|
Types.Maybe<
|
||||||
|
{ __typename?: 'basePointsType' } & Pick<
|
||||||
|
Types.BasePointsType,
|
||||||
|
'alias' | 'amount'
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GetBasePointsDocument = gql`
|
||||||
|
query GetBasePoints {
|
||||||
|
getBasePoints {
|
||||||
|
alias
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetBasePointsQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetBasePointsQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetBasePointsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetBasePointsQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetBasePointsQuery(
|
||||||
|
baseOptions?: Apollo.QueryHookOptions<
|
||||||
|
GetBasePointsQuery,
|
||||||
|
GetBasePointsQueryVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useQuery<GetBasePointsQuery, GetBasePointsQueryVariables>(
|
||||||
|
GetBasePointsDocument,
|
||||||
|
baseOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function useGetBasePointsLazyQuery(
|
||||||
|
baseOptions?: Apollo.LazyQueryHookOptions<
|
||||||
|
GetBasePointsQuery,
|
||||||
|
GetBasePointsQueryVariables
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return Apollo.useLazyQuery<GetBasePointsQuery, GetBasePointsQueryVariables>(
|
||||||
|
GetBasePointsDocument,
|
||||||
|
baseOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export type GetBasePointsQueryHookResult = ReturnType<
|
||||||
|
typeof useGetBasePointsQuery
|
||||||
|
>;
|
||||||
|
export type GetBasePointsLazyQueryHookResult = ReturnType<
|
||||||
|
typeof useGetBasePointsLazyQuery
|
||||||
|
>;
|
||||||
|
export type GetBasePointsQueryResult = Apollo.QueryResult<
|
||||||
|
GetBasePointsQuery,
|
||||||
|
GetBasePointsQueryVariables
|
||||||
|
>;
|
|
@ -1,63 +0,0 @@
|
||||||
import * as Apollo from '@apollo/client';
|
|
||||||
import * as Types from '../../types';
|
|
||||||
|
|
||||||
const gql = Apollo.gql;
|
|
||||||
|
|
||||||
export type GetLnPayQueryVariables = Types.Exact<{
|
|
||||||
amount: Types.Scalars['Int'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export type GetLnPayQuery = { __typename?: 'Query' } & Pick<
|
|
||||||
Types.Query,
|
|
||||||
'getLnPay'
|
|
||||||
>;
|
|
||||||
|
|
||||||
export const GetLnPayDocument = gql`
|
|
||||||
query GetLnPay($amount: Int!) {
|
|
||||||
getLnPay(amount: $amount)
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useGetLnPayQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useGetLnPayQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useGetLnPayQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
||||||
* you can use to render your UI.
|
|
||||||
*
|
|
||||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const { data, loading, error } = useGetLnPayQuery({
|
|
||||||
* variables: {
|
|
||||||
* amount: // value for 'amount'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useGetLnPayQuery(
|
|
||||||
baseOptions?: Apollo.QueryHookOptions<GetLnPayQuery, GetLnPayQueryVariables>
|
|
||||||
) {
|
|
||||||
return Apollo.useQuery<GetLnPayQuery, GetLnPayQueryVariables>(
|
|
||||||
GetLnPayDocument,
|
|
||||||
baseOptions
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export function useGetLnPayLazyQuery(
|
|
||||||
baseOptions?: Apollo.LazyQueryHookOptions<
|
|
||||||
GetLnPayQuery,
|
|
||||||
GetLnPayQueryVariables
|
|
||||||
>
|
|
||||||
) {
|
|
||||||
return Apollo.useLazyQuery<GetLnPayQuery, GetLnPayQueryVariables>(
|
|
||||||
GetLnPayDocument,
|
|
||||||
baseOptions
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export type GetLnPayQueryHookResult = ReturnType<typeof useGetLnPayQuery>;
|
|
||||||
export type GetLnPayLazyQueryHookResult = ReturnType<
|
|
||||||
typeof useGetLnPayLazyQuery
|
|
||||||
>;
|
|
||||||
export type GetLnPayQueryResult = Apollo.QueryResult<
|
|
||||||
GetLnPayQuery,
|
|
||||||
GetLnPayQueryVariables
|
|
||||||
>;
|
|
|
@ -1,69 +0,0 @@
|
||||||
import * as Apollo from '@apollo/client';
|
|
||||||
import * as Types from '../../types';
|
|
||||||
|
|
||||||
const gql = Apollo.gql;
|
|
||||||
|
|
||||||
export type GetLnPayInfoQueryVariables = Types.Exact<{ [key: string]: never }>;
|
|
||||||
|
|
||||||
export type GetLnPayInfoQuery = { __typename?: 'Query' } & {
|
|
||||||
getLnPayInfo?: Types.Maybe<
|
|
||||||
{ __typename?: 'lnPayInfoType' } & Pick<Types.LnPayInfoType, 'max' | 'min'>
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GetLnPayInfoDocument = gql`
|
|
||||||
query GetLnPayInfo {
|
|
||||||
getLnPayInfo {
|
|
||||||
max
|
|
||||||
min
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useGetLnPayInfoQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useGetLnPayInfoQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useGetLnPayInfoQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
||||||
* you can use to render your UI.
|
|
||||||
*
|
|
||||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const { data, loading, error } = useGetLnPayInfoQuery({
|
|
||||||
* variables: {
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useGetLnPayInfoQuery(
|
|
||||||
baseOptions?: Apollo.QueryHookOptions<
|
|
||||||
GetLnPayInfoQuery,
|
|
||||||
GetLnPayInfoQueryVariables
|
|
||||||
>
|
|
||||||
) {
|
|
||||||
return Apollo.useQuery<GetLnPayInfoQuery, GetLnPayInfoQueryVariables>(
|
|
||||||
GetLnPayInfoDocument,
|
|
||||||
baseOptions
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export function useGetLnPayInfoLazyQuery(
|
|
||||||
baseOptions?: Apollo.LazyQueryHookOptions<
|
|
||||||
GetLnPayInfoQuery,
|
|
||||||
GetLnPayInfoQueryVariables
|
|
||||||
>
|
|
||||||
) {
|
|
||||||
return Apollo.useLazyQuery<GetLnPayInfoQuery, GetLnPayInfoQueryVariables>(
|
|
||||||
GetLnPayInfoDocument,
|
|
||||||
baseOptions
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export type GetLnPayInfoQueryHookResult = ReturnType<
|
|
||||||
typeof useGetLnPayInfoQuery
|
|
||||||
>;
|
|
||||||
export type GetLnPayInfoLazyQueryHookResult = ReturnType<
|
|
||||||
typeof useGetLnPayInfoLazyQuery
|
|
||||||
>;
|
|
||||||
export type GetLnPayInfoQueryResult = Apollo.QueryResult<
|
|
||||||
GetLnPayInfoQuery,
|
|
||||||
GetLnPayInfoQueryVariables
|
|
||||||
>;
|
|
|
@ -73,7 +73,7 @@ export type GetCanConnectInfoQuery = { __typename?: 'Query' } & {
|
||||||
getNodeInfo?: Types.Maybe<
|
getNodeInfo?: Types.Maybe<
|
||||||
{ __typename?: 'nodeInfoType' } & Pick<
|
{ __typename?: 'nodeInfoType' } & Pick<
|
||||||
Types.NodeInfoType,
|
Types.NodeInfoType,
|
||||||
'public_key' | 'uris'
|
'alias' | 'public_key' | 'uris'
|
||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
@ -268,6 +268,7 @@ export type GetChannelAmountInfoQueryResult = Apollo.QueryResult<
|
||||||
export const GetCanConnectInfoDocument = gql`
|
export const GetCanConnectInfoDocument = gql`
|
||||||
query GetCanConnectInfo {
|
query GetCanConnectInfo {
|
||||||
getNodeInfo {
|
getNodeInfo {
|
||||||
|
alias
|
||||||
public_key
|
public_key
|
||||||
uris
|
uris
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,6 +501,7 @@ exports[`Query tests "GET_CONNECT_INFO" matches snapshot 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"data": Object {
|
"data": Object {
|
||||||
"getNodeInfo": Object {
|
"getNodeInfo": Object {
|
||||||
|
"alias": "TestNode",
|
||||||
"public_key": "key",
|
"public_key": "key",
|
||||||
"uris": Array [
|
"uris": Array [
|
||||||
"uri",
|
"uri",
|
||||||
|
|
7
src/graphql/queries/getBaseCanConnect.ts
Normal file
7
src/graphql/queries/getBaseCanConnect.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const GET_BASE_CAN_CONNECT = gql`
|
||||||
|
query GetBaseCanConnect {
|
||||||
|
getBaseCanConnect
|
||||||
|
}
|
||||||
|
`;
|
10
src/graphql/queries/getBasePoints.ts
Normal file
10
src/graphql/queries/getBasePoints.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const GET_BASE_POINTS = gql`
|
||||||
|
query GetBasePoints {
|
||||||
|
getBasePoints {
|
||||||
|
alias
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
|
@ -1,7 +0,0 @@
|
||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_LN_PAY = gql`
|
|
||||||
query GetLnPay($amount: Int!) {
|
|
||||||
getLnPay(amount: $amount)
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_LN_PAY_INFO = gql`
|
|
||||||
query GetLnPayInfo {
|
|
||||||
getLnPayInfo {
|
|
||||||
max
|
|
||||||
min
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -51,6 +51,7 @@ export const GET_CHANNEL_AMOUNT_INFO = gql`
|
||||||
export const GET_CONNECT_INFO = gql`
|
export const GET_CONNECT_INFO = gql`
|
||||||
query GetCanConnectInfo {
|
query GetCanConnectInfo {
|
||||||
getNodeInfo {
|
getNodeInfo {
|
||||||
|
alias
|
||||||
public_key
|
public_key
|
||||||
uris
|
uris
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,9 @@ export type PermissionsType = {
|
||||||
|
|
||||||
export type Query = {
|
export type Query = {
|
||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
|
getBaseCanConnect: Scalars['Boolean'];
|
||||||
getBaseNodes: Array<Maybe<BaseNodesType>>;
|
getBaseNodes: Array<Maybe<BaseNodesType>>;
|
||||||
|
getBasePoints: Array<Maybe<BasePointsType>>;
|
||||||
getAccountingReport: Scalars['String'];
|
getAccountingReport: Scalars['String'];
|
||||||
getVolumeHealth?: Maybe<ChannelsHealth>;
|
getVolumeHealth?: Maybe<ChannelsHealth>;
|
||||||
getTimeHealth?: Maybe<ChannelsTimeHealth>;
|
getTimeHealth?: Maybe<ChannelsTimeHealth>;
|
||||||
|
@ -79,8 +81,6 @@ export type Query = {
|
||||||
getSessionToken?: Maybe<Scalars['Boolean']>;
|
getSessionToken?: Maybe<Scalars['Boolean']>;
|
||||||
getServerAccounts?: Maybe<Array<Maybe<ServerAccountType>>>;
|
getServerAccounts?: Maybe<Array<Maybe<ServerAccountType>>>;
|
||||||
getAccount?: Maybe<ServerAccountType>;
|
getAccount?: Maybe<ServerAccountType>;
|
||||||
getLnPayInfo?: Maybe<LnPayInfoType>;
|
|
||||||
getLnPay?: Maybe<Scalars['String']>;
|
|
||||||
getLatestVersion?: Maybe<Scalars['String']>;
|
getLatestVersion?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,12 +179,10 @@ export type QueryGetSessionTokenArgs = {
|
||||||
password?: Maybe<Scalars['String']>;
|
password?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QueryGetLnPayArgs = {
|
|
||||||
amount?: Maybe<Scalars['Int']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Mutation = {
|
export type Mutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
|
createBaseInvoice?: Maybe<BaseInvoiceType>;
|
||||||
|
createThunderPoints: Scalars['Boolean'];
|
||||||
closeChannel?: Maybe<CloseChannelType>;
|
closeChannel?: Maybe<CloseChannelType>;
|
||||||
openChannel?: Maybe<OpenChannelType>;
|
openChannel?: Maybe<OpenChannelType>;
|
||||||
updateFees?: Maybe<Scalars['Boolean']>;
|
updateFees?: Maybe<Scalars['Boolean']>;
|
||||||
|
@ -202,6 +200,17 @@ export type Mutation = {
|
||||||
createMacaroon?: Maybe<Scalars['String']>;
|
createMacaroon?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MutationCreateBaseInvoiceArgs = {
|
||||||
|
amount: Scalars['Int'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MutationCreateThunderPointsArgs = {
|
||||||
|
id: Scalars['String'];
|
||||||
|
alias: Scalars['String'];
|
||||||
|
uris: Array<Scalars['String']>;
|
||||||
|
public_key: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
export type MutationCloseChannelArgs = {
|
export type MutationCloseChannelArgs = {
|
||||||
id: Scalars['String'];
|
id: Scalars['String'];
|
||||||
forceClose?: Maybe<Scalars['Boolean']>;
|
forceClose?: Maybe<Scalars['Boolean']>;
|
||||||
|
@ -339,12 +348,6 @@ export type ServerAccountType = {
|
||||||
loggedIn: Scalars['Boolean'];
|
loggedIn: Scalars['Boolean'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LnPayInfoType = {
|
|
||||||
__typename?: 'lnPayInfoType';
|
|
||||||
max?: Maybe<Scalars['Int']>;
|
|
||||||
min?: Maybe<Scalars['Int']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BitcoinFeeType = {
|
export type BitcoinFeeType = {
|
||||||
__typename?: 'bitcoinFeeType';
|
__typename?: 'bitcoinFeeType';
|
||||||
fast?: Maybe<Scalars['Int']>;
|
fast?: Maybe<Scalars['Int']>;
|
||||||
|
@ -889,3 +892,15 @@ export type BaseNodesType = {
|
||||||
public_key: Scalars['String'];
|
public_key: Scalars['String'];
|
||||||
socket: Scalars['String'];
|
socket: Scalars['String'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type BasePointsType = {
|
||||||
|
__typename?: 'basePointsType';
|
||||||
|
alias: Scalars['String'];
|
||||||
|
amount: Scalars['Int'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BaseInvoiceType = {
|
||||||
|
__typename?: 'baseInvoiceType';
|
||||||
|
id: Scalars['String'];
|
||||||
|
request: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
15
src/hooks/UseBaseConnect.tsx
Normal file
15
src/hooks/UseBaseConnect.tsx
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useGetBaseCanConnectQuery } from 'src/graphql/queries/__generated__/getBaseCanConnect.generated';
|
||||||
|
|
||||||
|
export const useBaseConnect = () => {
|
||||||
|
const [canConnect, setCanConnect] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { loading, error, data } = useGetBaseCanConnectQuery();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (loading || !data?.getBaseCanConnect || error) return;
|
||||||
|
setCanConnect(true);
|
||||||
|
}, [loading, data, error]);
|
||||||
|
|
||||||
|
return canConnect;
|
||||||
|
};
|
|
@ -19,7 +19,7 @@ export const useBitcoinFees = (): State => {
|
||||||
const [bitcoinFees, setBitcoinFees] = useState<State>(initialState);
|
const [bitcoinFees, setBitcoinFees] = useState<State>(initialState);
|
||||||
|
|
||||||
const { loading, data, error } = useGetBitcoinFeesQuery({
|
const { loading, data, error } = useGetBitcoinFeesQuery({
|
||||||
fetchPolicy: 'cache-only',
|
fetchPolicy: 'cache-first',
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -41,7 +41,7 @@ const initialState = {
|
||||||
export const useNodeInfo = (): StatusState => {
|
export const useNodeInfo = (): StatusState => {
|
||||||
const [nodeInfo, setNodeInfo] = useState<StatusState>(initialState);
|
const [nodeInfo, setNodeInfo] = useState<StatusState>(initialState);
|
||||||
const { data, loading, error } = useGetNodeInfoQuery({
|
const { data, loading, error } = useGetNodeInfoQuery({
|
||||||
fetchPolicy: 'cache-only',
|
fetchPolicy: 'cache-first',
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -7,9 +7,11 @@ import {
|
||||||
Settings,
|
Settings,
|
||||||
Home,
|
Home,
|
||||||
Icon,
|
Icon,
|
||||||
|
Heart,
|
||||||
} from 'react-feather';
|
} from 'react-feather';
|
||||||
import { useTransition, animated } from 'react-spring';
|
import { useTransition, animated } from 'react-spring';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { useBaseConnect } from 'src/hooks/UseBaseConnect';
|
||||||
import { headerColor, headerTextColor } from '../../styles/Themes';
|
import { headerColor, headerTextColor } from '../../styles/Themes';
|
||||||
import { SingleLine } from '../../components/generic/Styled';
|
import { SingleLine } from '../../components/generic/Styled';
|
||||||
import { BurgerMenu } from '../../components/burgerMenu/BurgerMenu';
|
import { BurgerMenu } from '../../components/burgerMenu/BurgerMenu';
|
||||||
|
@ -29,16 +31,19 @@ import {
|
||||||
const MAIN = '/';
|
const MAIN = '/';
|
||||||
const HOME = '/home';
|
const HOME = '/home';
|
||||||
const CHAT = '/chat';
|
const CHAT = '/chat';
|
||||||
|
const DONATIONS = '/leaderboard';
|
||||||
const SETTINGS = '/settings';
|
const SETTINGS = '/settings';
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
const { pathname } = useRouter();
|
const { pathname } = useRouter();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const connected = useBaseConnect();
|
||||||
|
|
||||||
const isRoot = pathname === '/';
|
const isRoot = pathname === '/';
|
||||||
|
|
||||||
const showHomeButton = (): boolean =>
|
const showHomeButton = (): boolean =>
|
||||||
pathname === CHAT || pathname === SETTINGS;
|
pathname === DONATIONS || pathname === CHAT || pathname === SETTINGS;
|
||||||
|
|
||||||
const transitions = useTransition(open, null, {
|
const transitions = useTransition(open, null, {
|
||||||
from: { position: 'absolute', opacity: 0 },
|
from: { position: 'absolute', opacity: 0 },
|
||||||
|
@ -74,6 +79,7 @@ export const Header = () => {
|
||||||
<ViewSwitch hideMobile={true}>
|
<ViewSwitch hideMobile={true}>
|
||||||
<HeaderButtons>
|
<HeaderButtons>
|
||||||
{showHomeButton() && renderNavButton(HOME, Home)}
|
{showHomeButton() && renderNavButton(HOME, Home)}
|
||||||
|
{connected && renderNavButton(DONATIONS, Heart)}
|
||||||
{renderNavButton(CHAT, MessageCircle)}
|
{renderNavButton(CHAT, MessageCircle)}
|
||||||
{renderNavButton(SETTINGS, Settings)}
|
{renderNavButton(SETTINGS, Settings)}
|
||||||
</HeaderButtons>
|
</HeaderButtons>
|
||||||
|
|
|
@ -14,8 +14,10 @@ import {
|
||||||
MessageCircle,
|
MessageCircle,
|
||||||
BarChart2,
|
BarChart2,
|
||||||
Icon,
|
Icon,
|
||||||
|
Heart,
|
||||||
} from 'react-feather';
|
} from 'react-feather';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { useBaseConnect } from 'src/hooks/UseBaseConnect';
|
||||||
import {
|
import {
|
||||||
unSelectedNavButton,
|
unSelectedNavButton,
|
||||||
navBackgroundColor,
|
navBackgroundColor,
|
||||||
|
@ -121,6 +123,7 @@ const CHAIN_TRANS = '/chain';
|
||||||
const TOOLS = '/tools';
|
const TOOLS = '/tools';
|
||||||
const DETAILS = '/details';
|
const DETAILS = '/details';
|
||||||
const STATS = '/stats';
|
const STATS = '/stats';
|
||||||
|
const DONATIONS = '/leaderboard';
|
||||||
const CHAT = '/chat';
|
const CHAT = '/chat';
|
||||||
const SETTINGS = '/settings';
|
const SETTINGS = '/settings';
|
||||||
|
|
||||||
|
@ -133,6 +136,8 @@ export const Navigation = ({ isBurger, setOpen }: NavigationProps) => {
|
||||||
const { pathname } = useRouter();
|
const { pathname } = useRouter();
|
||||||
const { sidebar } = useConfigState();
|
const { sidebar } = useConfigState();
|
||||||
|
|
||||||
|
const connected = useBaseConnect();
|
||||||
|
|
||||||
const isRoot = pathname === '/';
|
const isRoot = pathname === '/';
|
||||||
|
|
||||||
const renderNavButton = (
|
const renderNavButton = (
|
||||||
|
@ -188,6 +193,7 @@ export const Navigation = ({ isBurger, setOpen }: NavigationProps) => {
|
||||||
{renderBurgerNav('Chain', CHAIN_TRANS, LinkIcon)}
|
{renderBurgerNav('Chain', CHAIN_TRANS, LinkIcon)}
|
||||||
{renderBurgerNav('Tools', TOOLS, Shield)}
|
{renderBurgerNav('Tools', TOOLS, Shield)}
|
||||||
{renderBurgerNav('Stats', STATS, BarChart2)}
|
{renderBurgerNav('Stats', STATS, BarChart2)}
|
||||||
|
{connected && renderBurgerNav('Donations', DONATIONS, Heart)}
|
||||||
{renderBurgerNav('Chat', CHAT, MessageCircle)}
|
{renderBurgerNav('Chat', CHAT, MessageCircle)}
|
||||||
{renderBurgerNav('Settings', SETTINGS, Settings)}
|
{renderBurgerNav('Settings', SETTINGS, Settings)}
|
||||||
</BurgerRow>
|
</BurgerRow>
|
||||||
|
|
|
@ -86,6 +86,7 @@ export const RequestModal: React.FC<DecodeProps> = ({
|
||||||
handleReset,
|
handleReset,
|
||||||
}) => {
|
}) => {
|
||||||
const { data, loading, error } = useDecodeRequestQuery({
|
const { data, loading, error } = useDecodeRequestQuery({
|
||||||
|
skip: !request,
|
||||||
fetchPolicy: 'network-only',
|
fetchPolicy: 'network-only',
|
||||||
variables: { request },
|
variables: { request },
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useGetLnPayInfoQuery } from 'src/graphql/queries/__generated__/getLnPayInfo.generated';
|
|
||||||
import { Heart } from 'react-feather';
|
import { Heart } from 'react-feather';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import {
|
import {
|
||||||
|
@ -8,6 +7,7 @@ import {
|
||||||
cardBorderColor,
|
cardBorderColor,
|
||||||
unSelectedNavButton,
|
unSelectedNavButton,
|
||||||
} from 'src/styles/Themes';
|
} from 'src/styles/Themes';
|
||||||
|
import { useBaseConnect } from 'src/hooks/UseBaseConnect';
|
||||||
|
|
||||||
const QuickTitle = styled.div`
|
const QuickTitle = styled.div`
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -47,11 +47,9 @@ type SupportCardProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SupportCard = ({ callback }: SupportCardProps) => {
|
export const SupportCard = ({ callback }: SupportCardProps) => {
|
||||||
const { loading, error } = useGetLnPayInfoQuery();
|
const connected = useBaseConnect();
|
||||||
|
|
||||||
if (loading || error) {
|
if (!connected) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QuickCard onClick={callback}>
|
<QuickCard onClick={callback}>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useGetLnPayLazyQuery } from 'src/graphql/queries/__generated__/getLnPay.generated';
|
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
SubTitle,
|
SubTitle,
|
||||||
|
@ -10,31 +9,93 @@ import { InputWithDeco } from 'src/components/input/InputWithDeco';
|
||||||
import { ColorButton } from 'src/components/buttons/colorButton/ColorButton';
|
import { ColorButton } from 'src/components/buttons/colorButton/ColorButton';
|
||||||
import Modal from 'src/components/modal/ReactModal';
|
import Modal from 'src/components/modal/ReactModal';
|
||||||
import { Emoji } from 'src/components/emoji/Emoji';
|
import { Emoji } from 'src/components/emoji/Emoji';
|
||||||
|
import { useCreateBaseInvoiceMutation } from 'src/graphql/mutations/__generated__/createBaseInvoice.generated';
|
||||||
|
import {
|
||||||
|
SingleButton,
|
||||||
|
MultiButton,
|
||||||
|
} from 'src/components/buttons/multiButton/MultiButton';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { mediaWidths } from 'src/styles/Themes';
|
||||||
|
import { useGetCanConnectInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||||
|
import { useCreateThunderPointsMutation } from 'src/graphql/mutations/__generated__/createThunderPoints.generated';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import { useBaseConnect } from 'src/hooks/UseBaseConnect';
|
||||||
import { RequestModal } from '../../account/pay/RequestModal';
|
import { RequestModal } from '../../account/pay/RequestModal';
|
||||||
|
|
||||||
|
const StyledText = styled.div`
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 16px 40px 0;
|
||||||
|
|
||||||
|
@media (${mediaWidths.mobile}) {
|
||||||
|
margin: 16px 0 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const SupportBar = () => {
|
export const SupportBar = () => {
|
||||||
const [modalOpen, modalOpenSet] = React.useState<boolean>(false);
|
const [modalOpen, modalOpenSet] = React.useState<boolean>(false);
|
||||||
const [amount, amountSet] = React.useState<number>(0);
|
const [amount, amountSet] = React.useState<number>(0);
|
||||||
const [invoice, invoiceSet] = React.useState<string>('');
|
const [invoice, invoiceSet] = React.useState<string>('');
|
||||||
|
const [id, idSet] = React.useState<string>('');
|
||||||
|
|
||||||
|
const connected = useBaseConnect();
|
||||||
|
|
||||||
|
const [withPoints, setWithPoints] = React.useState<boolean>(false);
|
||||||
|
|
||||||
|
const [getInvoice, { data, loading }] = useCreateBaseInvoiceMutation();
|
||||||
|
|
||||||
const [
|
const [
|
||||||
getInvoice,
|
createPoints,
|
||||||
{ data, loading: invoiceLoading },
|
{ data: pointsData, called, loading: pointsLoading },
|
||||||
] = useGetLnPayLazyQuery();
|
] = useCreateThunderPointsMutation({ refetchQueries: ['GetBasePoints'] });
|
||||||
|
const { data: info } = useGetCanConnectInfoQuery();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (data && data.getLnPay) {
|
if (data?.createBaseInvoice) {
|
||||||
invoiceSet(data.getLnPay);
|
const { request, id } = data.createBaseInvoice;
|
||||||
|
invoiceSet(request);
|
||||||
|
idSet(id);
|
||||||
modalOpenSet(true);
|
modalOpenSet(true);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!pointsLoading && called) {
|
||||||
|
if (pointsData?.createThunderPoints) {
|
||||||
|
toast.success('Points Created');
|
||||||
|
} else {
|
||||||
|
toast.error('Error creating points. Write to us on telegram!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [pointsData, pointsLoading, called]);
|
||||||
|
|
||||||
|
if (!connected) return null;
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
modalOpenSet(false);
|
modalOpenSet(false);
|
||||||
amountSet(0);
|
amountSet(0);
|
||||||
invoiceSet('');
|
invoiceSet('');
|
||||||
|
idSet('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePaidReset = () => {
|
||||||
|
if (withPoints && info?.getNodeInfo) {
|
||||||
|
const { alias, public_key, uris } = info.getNodeInfo;
|
||||||
|
createPoints({ variables: { id, alias, public_key, uris } });
|
||||||
|
}
|
||||||
|
handleReset();
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderButton = (
|
||||||
|
onClick: () => void,
|
||||||
|
text: string,
|
||||||
|
selected: boolean
|
||||||
|
) => (
|
||||||
|
<SingleButton selected={selected} onClick={onClick}>
|
||||||
|
{text}
|
||||||
|
</SingleButton>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card>
|
<Card>
|
||||||
|
@ -53,24 +114,34 @@ export const SupportBar = () => {
|
||||||
inputType={'number'}
|
inputType={'number'}
|
||||||
inputCallback={value => amountSet(Number(value))}
|
inputCallback={value => amountSet(Number(value))}
|
||||||
/>
|
/>
|
||||||
|
<Separation />
|
||||||
|
<InputWithDeco title={'With Points'} noInput={true}>
|
||||||
|
<MultiButton>
|
||||||
|
{renderButton(() => setWithPoints(true), 'Yes', withPoints)}
|
||||||
|
{renderButton(() => setWithPoints(false), 'No', !withPoints)}
|
||||||
|
</MultiButton>
|
||||||
|
</InputWithDeco>
|
||||||
|
{withPoints && (
|
||||||
|
<StyledText>
|
||||||
|
This means your node will appear in the ThunderHub donation
|
||||||
|
leaderboard. If you want to remain anonymous, do not enable this
|
||||||
|
option. Your node alias and public key will be stored if you enable
|
||||||
|
it.
|
||||||
|
</StyledText>
|
||||||
|
)}
|
||||||
|
<Separation />
|
||||||
<ColorButton
|
<ColorButton
|
||||||
onClick={() => getInvoice({ variables: { amount: amount * 1000 } })}
|
onClick={() => getInvoice({ variables: { amount } })}
|
||||||
loading={invoiceLoading}
|
loading={loading}
|
||||||
disabled={amount <= 0 || invoiceLoading}
|
disabled={amount <= 0 || loading}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
withMargin={'8px 0 0 0'}
|
withMargin={'8px 0 0 0'}
|
||||||
>
|
>
|
||||||
Send
|
Send
|
||||||
</ColorButton>
|
</ColorButton>
|
||||||
</Card>
|
</Card>
|
||||||
<Modal
|
<Modal isOpen={modalOpen} closeCallback={handleReset}>
|
||||||
isOpen={modalOpen}
|
<RequestModal request={invoice} handleReset={handlePaidReset} />
|
||||||
closeCallback={() => {
|
|
||||||
modalOpenSet(false);
|
|
||||||
amountSet(0);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RequestModal request={invoice} handleReset={handleReset} />
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
91
src/views/leaderboard/NodeCard.tsx
Normal file
91
src/views/leaderboard/NodeCard.tsx
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { BasePointsType } from 'src/graphql/types';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { DarkSubTitle } from 'src/components/generic/Styled';
|
||||||
|
import { themeColors } from 'src/styles/Themes';
|
||||||
|
|
||||||
|
type LeaderCardProps = {
|
||||||
|
color?: string;
|
||||||
|
borderColor?: string;
|
||||||
|
borderWidth?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LeaderCard = styled.div<LeaderCardProps>`
|
||||||
|
padding: 8px;
|
||||||
|
border: ${({ borderWidth }) => borderWidth || '2px'} solid
|
||||||
|
${({ borderColor }) => borderColor || 'gold'};
|
||||||
|
background-color: ${({ color }) => color || 'gold'};
|
||||||
|
margin: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Line = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const NumberPadding = styled.div`
|
||||||
|
margin-right: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const getBorderColor = (index: number) => {
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
return 'gold';
|
||||||
|
case 2:
|
||||||
|
return 'orange';
|
||||||
|
case 3:
|
||||||
|
return 'white';
|
||||||
|
default:
|
||||||
|
return themeColors.blue2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getColor = (index: number) => {
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
return 'transparent';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWidth = (index: number): string => {
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
return '2px';
|
||||||
|
default:
|
||||||
|
return '1px';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type NodeCardType = {
|
||||||
|
node: BasePointsType | null;
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NodeCard = ({ node, index }: NodeCardType) => {
|
||||||
|
if (!node) return null;
|
||||||
|
return (
|
||||||
|
<LeaderCard
|
||||||
|
color={getColor(index)}
|
||||||
|
borderColor={getBorderColor(index)}
|
||||||
|
borderWidth={getWidth(index)}
|
||||||
|
>
|
||||||
|
<Line>
|
||||||
|
<NumberPadding>{`${index}.`}</NumberPadding>
|
||||||
|
{node.alias}
|
||||||
|
</Line>
|
||||||
|
<Line>
|
||||||
|
<DarkSubTitle withMargin={'0 8px 0 0'}>Points:</DarkSubTitle>
|
||||||
|
{node.amount}
|
||||||
|
</Line>
|
||||||
|
</LeaderCard>
|
||||||
|
);
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue