mirror of
https://github.com/apotdevin/thunderhub.git
synced 2024-11-19 09:50:03 +01:00
chore: π§ enable strict tsconfig (#96)
* chore: π§ strict enable wip * Improve typings, add type dependencies (#97) We improve the TypeScript situation by enabling `noImplicitAny`. This leads to a bunch of errors, as expected. We fix some of these by installing the correct types, and some are fixed manually by an educated guess. There are still a lot left, and these seem to be a big mix of lacking types for the `ln-service` dependency and potential bugs. * Strict null (#100) * chore: π§ enable strict-null * chore: π§ more checks * chore: π§ some fixes * chore: π§ more types * chore: π§ more types * chore: π§ more types * chore: π§ more types * chore: π§ more types * chore: π§ more types * chore: π§ more types * chore: π§ enable strict * fix: π input * fix: π forward report * fix: π chat sending * fix: π chat bubble input Co-authored-by: Torkel Rogstad <torkel@rogstad.io>
This commit is contained in:
parent
34d4586a41
commit
bc4415cde7
17
@types/index.d.ts
vendored
17
@types/index.d.ts
vendored
@ -3,3 +3,20 @@ declare module '*.jpg';
|
||||
declare module '*.jpeg';
|
||||
declare module '*.svg';
|
||||
declare module '*.gif';
|
||||
|
||||
/**
|
||||
* ln-service does not have proper types. This is slightly
|
||||
* problematic, as this leads to types being `any` **a ton**
|
||||
* of places.
|
||||
*
|
||||
* Here's an issue tracking this: https://github.com/alexbosworth/ln-service/issues/112
|
||||
*
|
||||
* It seems like the library is generated from Proto files.
|
||||
* Could it be an idea to try and generate TypeScript declarations
|
||||
* from those files?
|
||||
*/
|
||||
declare module 'ln-service';
|
||||
declare module '@alexbosworth/request';
|
||||
declare module 'balanceofsatoshis/request';
|
||||
declare module 'balanceofsatoshis/swaps';
|
||||
declare module 'balanceofsatoshis/balances';
|
||||
|
@ -6,22 +6,26 @@ import { ApolloClient } from 'apollo-client';
|
||||
import {
|
||||
InMemoryCache,
|
||||
IntrospectionFragmentMatcher,
|
||||
NormalizedCacheObject,
|
||||
} from 'apollo-cache-inmemory';
|
||||
import getConfig from 'next/config';
|
||||
import introspectionQueryResultData from 'src/graphql/fragmentTypes.json';
|
||||
import { SchemaLink } from 'apollo-link-schema';
|
||||
import { NextPage } from 'next';
|
||||
|
||||
const fragmentMatcher = new IntrospectionFragmentMatcher({
|
||||
introspectionQueryResultData,
|
||||
});
|
||||
|
||||
let globalApolloClient = null;
|
||||
let globalApolloClient: ReturnType<typeof createApolloClient> | null = null;
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
const { apiUrl: uri } = publicRuntimeConfig;
|
||||
|
||||
function createIsomorphLink(ctx) {
|
||||
type Context = SchemaLink.ResolverContextFunction | Record<string, any>;
|
||||
|
||||
function createIsomorphLink(ctx: Context) {
|
||||
if (typeof window === 'undefined') {
|
||||
const { SchemaLink } = require('apollo-link-schema');
|
||||
const schema = require('server/schema');
|
||||
return new SchemaLink({ schema, context: ctx });
|
||||
} else {
|
||||
@ -36,9 +40,11 @@ function createIsomorphLink(ctx) {
|
||||
|
||||
/**
|
||||
* Creates and configures the ApolloClient
|
||||
* @param {Object} [initialState={}]
|
||||
*/
|
||||
function createApolloClient(ctx = {}, initialState = {}) {
|
||||
function createApolloClient(
|
||||
ctx: Context = {},
|
||||
initialState: NormalizedCacheObject = {}
|
||||
) {
|
||||
const ssrMode = typeof window === 'undefined';
|
||||
const cache = new InMemoryCache({ fragmentMatcher }).restore(initialState);
|
||||
|
||||
@ -53,9 +59,8 @@ function createApolloClient(ctx = {}, initialState = {}) {
|
||||
/**
|
||||
* Always creates a new apollo client on the server
|
||||
* Creates or reuses apollo client in the browser.
|
||||
* @param {Object} initialState
|
||||
*/
|
||||
function initApolloClient(ctx, initialState?) {
|
||||
function initApolloClient(ctx?: Context, initialState?: NormalizedCacheObject) {
|
||||
// Make sure to create a new client for every server-side request so that data
|
||||
// isn't shared between connections (which would be bad)
|
||||
if (typeof window === 'undefined') {
|
||||
@ -70,16 +75,29 @@ function initApolloClient(ctx, initialState?) {
|
||||
return globalApolloClient;
|
||||
}
|
||||
|
||||
interface WithApolloProps {
|
||||
apolloClient?: ApolloClient<NormalizedCacheObject>;
|
||||
apolloState?: NormalizedCacheObject;
|
||||
}
|
||||
|
||||
interface WithApolloOptions {
|
||||
ssr?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and provides the apolloContext
|
||||
* to a next.js PageTree. Use it by wrapping
|
||||
* your PageComponent via HOC pattern.
|
||||
* @param {Function|Class} PageComponent
|
||||
* @param {Object} [config]
|
||||
* @param {Boolean} [config.ssr=true]
|
||||
*/
|
||||
export function withApollo(PageComponent, { ssr = true } = {}) {
|
||||
const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => {
|
||||
export function withApollo(
|
||||
PageComponent: NextPage,
|
||||
{ ssr }: WithApolloOptions = { ssr: true }
|
||||
) {
|
||||
const WithApollo: NextPage<WithApolloProps> = ({
|
||||
apolloClient,
|
||||
apolloState,
|
||||
...pageProps
|
||||
}) => {
|
||||
const client = apolloClient || initApolloClient(undefined, apolloState);
|
||||
return (
|
||||
<ApolloProvider client={client}>
|
||||
@ -101,15 +119,16 @@ export function withApollo(PageComponent, { ssr = true } = {}) {
|
||||
}
|
||||
|
||||
if (ssr || PageComponent.getInitialProps) {
|
||||
WithApollo.getInitialProps = async ctx => {
|
||||
WithApollo.getInitialProps = async (ctx): Promise<WithApolloProps> => {
|
||||
const { AppTree } = ctx;
|
||||
|
||||
// Initialize ApolloClient, add it to the ctx object so
|
||||
// we can use it in `PageComponent.getInitialProp`.
|
||||
const apolloClient = (ctx.apolloClient = initApolloClient({
|
||||
const apolloClient = initApolloClient({
|
||||
res: ctx.res,
|
||||
req: ctx.req,
|
||||
}));
|
||||
});
|
||||
(ctx as any).apolloClient = apolloClient;
|
||||
|
||||
// Run wrapped getInitialProps methods
|
||||
let pageProps = {};
|
||||
@ -122,7 +141,7 @@ export function withApollo(PageComponent, { ssr = true } = {}) {
|
||||
// When redirecting, the response is finished.
|
||||
// No point in continuing to render
|
||||
if (ctx.res && ctx.res.finished) {
|
||||
return pageProps;
|
||||
return pageProps as WithApolloProps;
|
||||
}
|
||||
|
||||
// Only if ssr is enabled
|
||||
|
133
package-lock.json
generated
133
package-lock.json
generated
@ -4766,6 +4766,12 @@
|
||||
"@babel/types": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@types/bcryptjs": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
|
||||
"integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
|
||||
@ -4802,6 +4808,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg=="
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/cookies": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz",
|
||||
@ -4822,6 +4834,12 @@
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/crypto-js": {
|
||||
"version": "3.1.47",
|
||||
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.47.tgz",
|
||||
"integrity": "sha512-eI6gvpcGHLk3dAuHYnRCAjX+41gMv1nz/VP55wAe5HtmAKDOoPSfr3f6vkMc08ov1S0NsjvUBxDtHHxqQY1LGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/eslint-visitor-keys": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
|
||||
@ -4866,6 +4884,15 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/graphql-iso-date": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/graphql-iso-date/-/graphql-iso-date-3.4.0.tgz",
|
||||
"integrity": "sha512-V3jITHTsoI2E8TGt9+/HPDz6LWt3z9/HYnPJYWI6WwiLRexsngg7KzaQlCgQkA4jkEbGPROUD0hJFc9F02W9WA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graphql": "^15.1.0"
|
||||
}
|
||||
},
|
||||
"@types/graphql-upload": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.3.tgz",
|
||||
@ -4937,6 +4964,18 @@
|
||||
"pretty-format": "^25.2.1"
|
||||
}
|
||||
},
|
||||
"@types/js-cookie": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.6.tgz",
|
||||
"integrity": "sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/js-yaml": {
|
||||
"version": "3.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz",
|
||||
"integrity": "sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
||||
@ -4985,6 +5024,48 @@
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.157",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.157.tgz",
|
||||
"integrity": "sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash.groupby": {
|
||||
"version": "4.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash.groupby/-/lodash.groupby-4.6.6.tgz",
|
||||
"integrity": "sha512-kwg3T7Ia63KtDNoQQR8hKrLHCAgrH4I44l5uEMuA6JCbj7DiSccaV4tNV1vbjtAOpX990SolVthJCmBVtRVRgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"@types/lodash.merge": {
|
||||
"version": "4.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.6.tgz",
|
||||
"integrity": "sha512-IB90krzMf7YpfgP3u/EvZEdXVvm4e3gJbUvh5ieuI+o+XqiNEt6fCzqNRaiLlPVScLI59RxIGZMQ3+Ko/DJ8vQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"@types/lodash.omit": {
|
||||
"version": "4.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash.omit/-/lodash.omit-4.5.6.tgz",
|
||||
"integrity": "sha512-KXPpOSNX2h0DAG2w7ajpk7TXvWF28ZHs5nJhOJyP0BQHkehgr948RVsToItMme6oi0XJkp19CbuNXkIX8FiBlQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"@types/lodash.sortby": {
|
||||
"version": "4.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash.sortby/-/lodash.sortby-4.7.6.tgz",
|
||||
"integrity": "sha512-EnvAOmKvEg7gdYpYrS6+fVFPw5dL9rBnJi3vcKI7wqWQcLJVF/KRXK9dH29HjGNVvFUj0s9prRP3J8jEGnGKDw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"@types/long": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
|
||||
@ -5021,6 +5102,12 @@
|
||||
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/numeral": {
|
||||
"version": "0.0.28",
|
||||
"resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-0.0.28.tgz",
|
||||
"integrity": "sha512-Sjsy10w6XFHDktJJdXzBJmoondAKW+LcGpRFH+9+zXEDj0cOH8BxJuZA9vUDSMAzU1YRJlsPKmZEEiTYDlICLw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -5043,6 +5130,15 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
|
||||
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
||||
},
|
||||
"@types/qrcode.react": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/qrcode.react/-/qrcode.react-1.0.1.tgz",
|
||||
"integrity": "sha512-PcVCjpsiT2KFKfJibOgTQtkt0QQT/6GbQUp1Np/hMPhwUzMJ2DRUkR9j7tXN9Q8X06qukw+RbaJ8lJ22SBod+Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.3.tgz",
|
||||
@ -5063,6 +5159,15 @@
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/react-copy-to-clipboard": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.3.0.tgz",
|
||||
"integrity": "sha512-iideNPRyroENqsOFh1i2Dv3zkviYS9r/9qD9Uh3Z9NNoAAqqa2x53i7iGndGNnJFIo20wIu7Hgh77tx1io8bgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-native": {
|
||||
"version": "0.62.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.62.18.tgz",
|
||||
@ -5115,6 +5220,16 @@
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/styled-react-modal": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/styled-react-modal/-/styled-react-modal-1.2.0.tgz",
|
||||
"integrity": "sha512-g+mtpYcekjAgnyKRN+xQ4bo5GQmiNdoXZ+XGb374uIgxSXx3+Wnb643o49MprYYcTTupzHf8scK3SDTzcf42Gw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"@types/styled-components": "*"
|
||||
}
|
||||
},
|
||||
"@types/styled-theming": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/styled-theming/-/styled-theming-2.2.4.tgz",
|
||||
@ -5134,6 +5249,18 @@
|
||||
"@types/jest": "*"
|
||||
}
|
||||
},
|
||||
"@types/underscore": {
|
||||
"version": "1.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.10.9.tgz",
|
||||
"integrity": "sha512-mKzbGzZ02nXKSV2VJdY92KNzwV7x4Zq626/4qR+7nJEceyKGk5gJXCi0mQqp3tEUa3GTc8uiuxqm4QyIaP0I1Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz",
|
||||
"integrity": "sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/websocket": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.0.tgz",
|
||||
@ -5176,6 +5303,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz",
|
||||
"integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg=="
|
||||
},
|
||||
"@types/zxcvbn": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.0.tgz",
|
||||
"integrity": "sha512-GQLOT+SN20a+AI51y3fAimhyTF4Y0RG+YP3gf91OibIZ7CJmPFgoZi+ZR5a+vRbS01LbQosITWum4ATmJ1Z6Pg==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.0.tgz",
|
||||
|
17
package.json
17
package.json
@ -102,11 +102,28 @@
|
||||
"@next/bundle-analyzer": "^9.4.4",
|
||||
"@testing-library/jest-dom": "^5.11.0",
|
||||
"@testing-library/react": "^10.4.5",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/crypto-js": "^3.1.47",
|
||||
"@types/graphql-iso-date": "^3.4.0",
|
||||
"@types/js-cookie": "^2.2.6",
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/lodash.groupby": "^4.6.6",
|
||||
"@types/lodash.merge": "^4.6.6",
|
||||
"@types/lodash.omit": "^4.5.6",
|
||||
"@types/lodash.sortby": "^4.7.6",
|
||||
"@types/node": "^14.0.22",
|
||||
"@types/numeral": "0.0.28",
|
||||
"@types/qrcode.react": "^1.0.1",
|
||||
"@types/react": "^16.9.43",
|
||||
"@types/react-copy-to-clipboard": "^4.3.0",
|
||||
"@types/styled-components": "^5.1.1",
|
||||
"@types/styled-react-modal": "^1.2.0",
|
||||
"@types/styled-theming": "^2.2.4",
|
||||
"@types/underscore": "^1.10.9",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"@types/zxcvbn": "^4.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^3.6.0",
|
||||
"@typescript-eslint/parser": "^3.6.0",
|
||||
"apollo-server": "^2.15.1",
|
||||
|
@ -4,6 +4,8 @@ import { ModalProvider, BaseModalBackground } from 'styled-react-modal';
|
||||
import { useRouter } from 'next/router';
|
||||
import Head from 'next/head';
|
||||
import { StyledToastContainer } from 'src/components/toastContainer/ToastContainer';
|
||||
import { NextPage } from 'next';
|
||||
import { AppProps } from 'next/app';
|
||||
import { ContextProvider } from '../src/context/ContextProvider';
|
||||
import { useConfigState, ConfigProvider } from '../src/context/ConfigContext';
|
||||
import { GlobalStyles } from '../src/styles/GlobalStyle';
|
||||
@ -36,7 +38,14 @@ const Wrapper: React.FC = ({ children }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const App = ({ Component, pageProps, initialConfig }) => (
|
||||
type InitialProps = { initialConfig: string };
|
||||
type MyAppProps = InitialProps & AppProps;
|
||||
|
||||
const App: NextPage<MyAppProps, InitialProps> = ({
|
||||
Component,
|
||||
pageProps,
|
||||
initialConfig,
|
||||
}) => (
|
||||
<>
|
||||
<Head>
|
||||
<title>ThunderHub - Lightning Node Manager</title>
|
||||
@ -52,8 +61,13 @@ const App = ({ Component, pageProps, initialConfig }) => (
|
||||
</>
|
||||
);
|
||||
|
||||
App.getInitialProps = async props => {
|
||||
const cookies = parseCookies(props.ctx.req);
|
||||
/*
|
||||
* Props should be NextPageContext but something wierd
|
||||
* happens and the context object received is not this
|
||||
* type.
|
||||
*/
|
||||
App.getInitialProps = async ({ ctx }: any) => {
|
||||
const cookies = parseCookies(ctx?.req);
|
||||
|
||||
if (!cookies?.theme) {
|
||||
return { initialConfig: 'dark' };
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
readCookie,
|
||||
getAccounts,
|
||||
} from 'server/helpers/fileHelpers';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { ContextType, SSOType } from 'server/types/apiTypes';
|
||||
import cookie from 'cookie';
|
||||
import schema from 'server/schema';
|
||||
|
||||
@ -33,6 +33,16 @@ const ssoMacaroon = readMacaroons(macaroonPath);
|
||||
const ssoCert = readFile(lnCertPath);
|
||||
const accountConfig = getAccounts(accountConfigPath);
|
||||
|
||||
let ssoAccount: SSOType | null = null;
|
||||
|
||||
if (ssoMacaroon && lnServerUrl) {
|
||||
ssoAccount = {
|
||||
macaroon: ssoMacaroon,
|
||||
host: lnServerUrl,
|
||||
cert: ssoCert,
|
||||
};
|
||||
}
|
||||
|
||||
readCookie(cookiePath);
|
||||
|
||||
const apolloServer = new ApolloServer({
|
||||
@ -56,12 +66,16 @@ const apolloServer = new ApolloServer({
|
||||
}
|
||||
}
|
||||
|
||||
let account = null;
|
||||
let account = '';
|
||||
if (AccountAuth) {
|
||||
logger.silly('AccountAuth cookie found in request');
|
||||
try {
|
||||
const cookieAccount = jwt.verify(AccountAuth, secret);
|
||||
account = cookieAccount['id'] || '';
|
||||
if (typeof cookieAccount === 'object') {
|
||||
account = (cookieAccount as { id?: string })['id'] ?? '';
|
||||
} else {
|
||||
account = cookieAccount;
|
||||
}
|
||||
} catch (error) {
|
||||
logger.silly('Account authentication cookie failed');
|
||||
}
|
||||
@ -72,7 +86,7 @@ const apolloServer = new ApolloServer({
|
||||
secret,
|
||||
ssoVerified,
|
||||
account,
|
||||
sso: { macaroon: ssoMacaroon, cert: ssoCert, host: lnServerUrl || null },
|
||||
sso: ssoVerified ? ssoAccount : null,
|
||||
accounts: accountConfig,
|
||||
res,
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ const ChatView = () => {
|
||||
const { minorVersion } = useStatusState();
|
||||
const { chats, sender, sentChats, initialized } = useChatState();
|
||||
const bySender = separateBySender([...chats, ...sentChats]);
|
||||
const senders = getSenders(bySender);
|
||||
const senders = getSenders(bySender) || [];
|
||||
|
||||
const [user, setUser] = React.useState('');
|
||||
const [showContacts, setShowContacts] = React.useState(false);
|
||||
|
@ -165,9 +165,9 @@ const FeesView = () => {
|
||||
<CardWithTitle>
|
||||
<SubTitle>Channel Details</SubTitle>
|
||||
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{data.getChannelFees.map((channel: ChannelFeeType, index: number) => (
|
||||
{data.getChannelFees.map((channel, index) => (
|
||||
<FeeCard
|
||||
channel={channel}
|
||||
channel={channel as ChannelFeeType}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
|
@ -4,6 +4,7 @@ import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetForwardsQuery } from 'src/graphql/queries/__generated__/getForwards.generated';
|
||||
import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
|
||||
import { withApollo } from 'config/client';
|
||||
import { ForwardType } from 'src/graphql/types';
|
||||
import {
|
||||
SubTitle,
|
||||
Card,
|
||||
@ -63,11 +64,13 @@ const ForwardsView = () => {
|
||||
{renderButton('threeMonths', '3M')}
|
||||
</SingleLine>
|
||||
</CardTitle>
|
||||
{data.getForwards.forwards.length <= 0 && renderNoForwards()}
|
||||
{data?.getForwards?.forwards &&
|
||||
data.getForwards.forwards.length <= 0 &&
|
||||
renderNoForwards()}
|
||||
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{data.getForwards.forwards.map((forward, index: number) => (
|
||||
{data?.getForwards?.forwards?.map((forward, index) => (
|
||||
<ForwardCard
|
||||
forward={forward}
|
||||
forward={forward as ForwardType}
|
||||
key={index}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
|
@ -3,6 +3,7 @@ import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetPeersQuery } from 'src/graphql/queries/__generated__/getPeers.generated';
|
||||
import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
|
||||
import { withApollo } from 'config/client';
|
||||
import { PeerType } from 'src/graphql/types';
|
||||
import {
|
||||
CardWithTitle,
|
||||
SubTitle,
|
||||
@ -21,7 +22,7 @@ const PeersView = () => {
|
||||
variables: { auth },
|
||||
});
|
||||
|
||||
if (loading || !data || !data.getPeers) {
|
||||
if (loading || !data?.getPeers) {
|
||||
return <LoadingCard title={'Peers'} />;
|
||||
}
|
||||
|
||||
@ -33,11 +34,11 @@ const PeersView = () => {
|
||||
<Card mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{data.getPeers.map((peer, index: number) => (
|
||||
<PeersCard
|
||||
peer={peer}
|
||||
peer={peer as PeerType}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
key={`${index}-${peer.public_key}`}
|
||||
key={`${index}-${peer?.public_key}`}
|
||||
/>
|
||||
))}
|
||||
</Card>
|
||||
|
@ -5,6 +5,7 @@ import { useGetOffersQuery } from 'src/graphql/hodlhodl/__generated__/query.gene
|
||||
import { GridWrapper } from 'src/components/gridWrapper/GridWrapper';
|
||||
import { withApollo } from 'config/client';
|
||||
import getConfig from 'next/config';
|
||||
import { HodlOfferType } from 'src/graphql/types';
|
||||
import {
|
||||
CardWithTitle,
|
||||
SubTitle,
|
||||
@ -27,7 +28,7 @@ export interface QueryProps {
|
||||
limit: number;
|
||||
offset: number;
|
||||
};
|
||||
filters: {};
|
||||
filters: { [key: string]: string };
|
||||
sort: {
|
||||
by: string;
|
||||
direction: string;
|
||||
@ -119,13 +120,13 @@ const TradingView = () => {
|
||||
</Card>
|
||||
<Card bottom={'8px'} mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{amountOfOffers <= 0 && <DarkSubTitle>No Offers Found</DarkSubTitle>}
|
||||
{data.getOffers.map((offer, index: number) => (
|
||||
{data.getOffers.map((offer, index) => (
|
||||
<OfferCard
|
||||
offer={offer}
|
||||
offer={offer as HodlOfferType}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
key={`${index}-${offer.id}`}
|
||||
key={`${index}-${offer?.id}`}
|
||||
/>
|
||||
))}
|
||||
</Card>
|
||||
|
@ -49,7 +49,10 @@ const TransactionsView = () => {
|
||||
<CardWithTitle>
|
||||
<SubTitle>Transactions</SubTitle>
|
||||
<Card bottom={'8px'} mobileCardPadding={'0'} mobileNoBackground={true}>
|
||||
{resumeList.map((entry, index: number) => {
|
||||
{resumeList?.map((entry, index: number) => {
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
if (entry.__typename === 'InvoiceType') {
|
||||
return (
|
||||
<InvoiceCard
|
||||
@ -61,15 +64,18 @@ const TransactionsView = () => {
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PaymentsCard
|
||||
payment={entry}
|
||||
key={index}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
/>
|
||||
);
|
||||
if (entry.__typename === 'PaymentType') {
|
||||
return (
|
||||
<PaymentsCard
|
||||
payment={entry}
|
||||
key={index}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
<ColorButton
|
||||
fullWidth={true}
|
||||
@ -79,14 +85,14 @@ const TransactionsView = () => {
|
||||
variables: { auth, token },
|
||||
updateQuery: (
|
||||
prev,
|
||||
{
|
||||
fetchMoreResult: result,
|
||||
}: { fetchMoreResult: GetResumeQuery }
|
||||
) => {
|
||||
if (!result) return prev;
|
||||
const newToken = result.getResume.token || '';
|
||||
const prevEntries = prev.getResume.resume;
|
||||
const newEntries = result.getResume.resume;
|
||||
{ fetchMoreResult }: { fetchMoreResult?: GetResumeQuery }
|
||||
): GetResumeQuery => {
|
||||
if (!fetchMoreResult?.getResume) return prev;
|
||||
const newToken = fetchMoreResult.getResume.token || '';
|
||||
const prevEntries = prev?.getResume
|
||||
? prev.getResume.resume
|
||||
: [];
|
||||
const newEntries = fetchMoreResult.getResume.resume;
|
||||
|
||||
const allTransactions = newToken
|
||||
? [...prevEntries, ...newEntries]
|
||||
|
@ -71,7 +71,7 @@ describe('getParsedAccount', () => {
|
||||
return 'something else ';
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'regtest');
|
||||
expect(account.macaroon).toContain('macaroon');
|
||||
expect(account?.macaroon).toContain('macaroon');
|
||||
});
|
||||
|
||||
it('picks up other networks', () => {
|
||||
@ -94,7 +94,7 @@ describe('getParsedAccount', () => {
|
||||
return 'something else ';
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.macaroon).toContain('macaroon');
|
||||
expect(account?.macaroon).toContain('macaroon');
|
||||
});
|
||||
|
||||
describe('macaroon handling', () => {
|
||||
@ -109,7 +109,7 @@ describe('getParsedAccount', () => {
|
||||
};
|
||||
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.macaroon).toBe('RAW MACAROON');
|
||||
expect(account?.macaroon).toBe('RAW MACAROON');
|
||||
});
|
||||
it('falls back to macaroon path after that', () => {
|
||||
const raw = {
|
||||
@ -130,7 +130,7 @@ describe('getParsedAccount', () => {
|
||||
}
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.macaroon).toBe('yay');
|
||||
expect(account?.macaroon).toBe('yay');
|
||||
});
|
||||
|
||||
it('falls back to lnd dir finally', () => {
|
||||
@ -152,7 +152,7 @@ describe('getParsedAccount', () => {
|
||||
}
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.macaroon).toBe('yay');
|
||||
expect(account?.macaroon).toBe('yay');
|
||||
});
|
||||
});
|
||||
|
||||
@ -168,7 +168,7 @@ describe('getParsedAccount', () => {
|
||||
};
|
||||
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.cert).toBe('RAW CERT');
|
||||
expect(account?.cert).toBe('RAW CERT');
|
||||
});
|
||||
|
||||
it('falls back to certificate path after that', () => {
|
||||
@ -188,7 +188,7 @@ describe('getParsedAccount', () => {
|
||||
}
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.cert).toBe('yay');
|
||||
expect(account?.cert).toBe('yay');
|
||||
});
|
||||
|
||||
it('falls back to lnd dir finally', () => {
|
||||
@ -207,7 +207,7 @@ describe('getParsedAccount', () => {
|
||||
}
|
||||
});
|
||||
const account = getParsedAccount(raw, 0, masterPassword, 'mainnet');
|
||||
expect(account.cert).toBe('yay');
|
||||
expect(account?.cert).toBe('yay');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { getErrorMsg } from './helpers';
|
||||
import { logger } from './logger';
|
||||
|
||||
export const to = promise => {
|
||||
export const to = async <T>(promise: Promise<T>) => {
|
||||
return promise
|
||||
.then(data => data)
|
||||
.catch(err => {
|
||||
@ -10,6 +10,15 @@ export const to = promise => {
|
||||
});
|
||||
};
|
||||
|
||||
export const toWithError = promise => {
|
||||
return promise.then(data => [data, undefined]).catch(err => [undefined, err]);
|
||||
/*
|
||||
* This is hard/impossible to type correctly. What we are describing
|
||||
* here is a set of two states: either we have a result and no error,
|
||||
* _or_ we have no result and an error. Unfortunately TypeScript is
|
||||
* not able to infer this correctly...
|
||||
* https://github.com/microsoft/TypeScript/issues/12184
|
||||
*/
|
||||
export const toWithError = async <T>(promise: Promise<T>) => {
|
||||
return promise
|
||||
.then(data => [data, undefined] as const)
|
||||
.catch(err => [undefined, err] as const);
|
||||
};
|
||||
|
@ -68,10 +68,15 @@ export const createCustomRecords = ({
|
||||
];
|
||||
};
|
||||
|
||||
type DecodeMessageType = {
|
||||
type: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export const decodeMessage = ({
|
||||
type,
|
||||
value,
|
||||
}): { [key: string]: string } | {} => {
|
||||
}: DecodeMessageType): { [key: string]: string } | {} => {
|
||||
switch (type) {
|
||||
case MESSAGE_TYPE:
|
||||
return { message: bufferHexToUtf(value) };
|
||||
|
@ -6,6 +6,7 @@ import { logger } from 'server/helpers/logger';
|
||||
import yaml from 'js-yaml';
|
||||
import { getUUID } from 'src/utils/auth';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { AccountType as ContextAccountType } from 'server/types/apiTypes';
|
||||
|
||||
type EncodingType = 'hex' | 'utf-8';
|
||||
type BitcoinNetwork = 'mainnet' | 'regtest' | 'testnet';
|
||||
@ -36,7 +37,7 @@ type AccountConfigType = {
|
||||
accounts: AccountType[];
|
||||
};
|
||||
|
||||
const isValidNetwork = (network: string): network is BitcoinNetwork =>
|
||||
const isValidNetwork = (network: string | null): network is BitcoinNetwork =>
|
||||
network === 'mainnet' || network === 'regtest' || network === 'testnet';
|
||||
|
||||
export const PRE_PASS_STRING = 'thunderhub-';
|
||||
@ -78,7 +79,8 @@ export const parseYaml = (filePath: string): AccountConfigType | null => {
|
||||
|
||||
try {
|
||||
const yamlObject = yaml.safeLoad(yamlConfig);
|
||||
return yamlObject;
|
||||
// TODO: validate this, before returning?
|
||||
return yamlObject as AccountConfigType;
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
'Something went wrong while parsing the YAML config file: \n' + err
|
||||
@ -115,12 +117,15 @@ export const hashPasswords = (
|
||||
|
||||
const cloned = { ...config };
|
||||
|
||||
let hashedMasterPassword = config.masterPassword;
|
||||
let hashedMasterPassword = config?.masterPassword || '';
|
||||
|
||||
if (hashedMasterPassword?.indexOf(PRE_PASS_STRING) < 0) {
|
||||
if (
|
||||
hashedMasterPassword &&
|
||||
hashedMasterPassword.indexOf(PRE_PASS_STRING) < 0
|
||||
) {
|
||||
hasChanged = true;
|
||||
hashedMasterPassword = `${PRE_PASS_STRING}${bcrypt.hashSync(
|
||||
config.masterPassword,
|
||||
hashedMasterPassword,
|
||||
12
|
||||
)}`;
|
||||
}
|
||||
@ -178,7 +183,7 @@ const getCertificate = ({
|
||||
const getMacaroon = (
|
||||
{ macaroon, macaroonPath, network, lndDir }: AccountType,
|
||||
defaultNetwork: BitcoinNetwork
|
||||
): string => {
|
||||
): string | null => {
|
||||
if (macaroon) {
|
||||
return macaroon;
|
||||
}
|
||||
@ -203,24 +208,24 @@ const getMacaroon = (
|
||||
);
|
||||
};
|
||||
|
||||
export const getAccounts = (filePath: string) => {
|
||||
export const getAccounts = (filePath: string): ContextAccountType[] => {
|
||||
if (filePath === '') {
|
||||
logger.verbose('No account config file path provided');
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
||||
const accountConfig = parseYaml(filePath);
|
||||
if (!accountConfig) {
|
||||
logger.info(`No account config file found at path ${filePath}`);
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
return getAccountsFromYaml(accountConfig, filePath);
|
||||
return getAccountsFromYaml(accountConfig, filePath) as ContextAccountType[];
|
||||
};
|
||||
|
||||
export const getParsedAccount = (
|
||||
account: AccountType,
|
||||
index: number,
|
||||
masterPassword: string,
|
||||
masterPassword: string | null,
|
||||
defaultNetwork: BitcoinNetwork
|
||||
): ParsedAccount | null => {
|
||||
const {
|
||||
@ -276,12 +281,12 @@ export const getParsedAccount = (
|
||||
const id = getUUID(`${name}${serverUrl}${macaroon}${cert}`);
|
||||
|
||||
return {
|
||||
name,
|
||||
name: name || '',
|
||||
id,
|
||||
host: serverUrl,
|
||||
host: serverUrl || '',
|
||||
macaroon,
|
||||
cert,
|
||||
password: password || masterPassword,
|
||||
cert: cert || '',
|
||||
password: password || masterPassword || '',
|
||||
};
|
||||
};
|
||||
|
||||
@ -297,7 +302,7 @@ export const getAccountsFromYaml = (
|
||||
}
|
||||
|
||||
const { defaultNetwork, masterPassword, accounts } = hashPasswords(
|
||||
hashed,
|
||||
hashed || false,
|
||||
config,
|
||||
filePath
|
||||
);
|
||||
@ -314,7 +319,7 @@ export const getAccountsFromYaml = (
|
||||
|
||||
logger.info(
|
||||
`Server accounts that will be available: ${parsedAccounts
|
||||
.map(({ name }) => name)
|
||||
.map(account => account?.name)
|
||||
.join(', ')}`
|
||||
);
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { getNode, getChannel } from 'ln-service';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { toWithError } from 'server/helpers/async';
|
||||
import {
|
||||
LndObject,
|
||||
GetChannelType,
|
||||
GetNodeType,
|
||||
} from 'server/types/ln-service.types';
|
||||
|
||||
const errorNode = {
|
||||
alias: 'Partner node not found',
|
||||
@ -10,7 +15,7 @@ const errorNode = {
|
||||
export const getNodeFromChannel = async (
|
||||
id: string,
|
||||
publicKey: string,
|
||||
lnd
|
||||
lnd: LndObject
|
||||
) => {
|
||||
const [channelInfo, channelError] = await toWithError(
|
||||
getChannel({
|
||||
@ -19,15 +24,15 @@ export const getNodeFromChannel = async (
|
||||
})
|
||||
);
|
||||
|
||||
if (channelError) {
|
||||
if (channelError || !channelInfo) {
|
||||
logger.verbose(`Error getting channel with id ${id}: %o`, channelError);
|
||||
return errorNode;
|
||||
}
|
||||
|
||||
const partnerPublicKey =
|
||||
channelInfo.policies[0].public_key !== publicKey
|
||||
? channelInfo.policies[0].public_key
|
||||
: channelInfo.policies[1].public_key;
|
||||
(channelInfo as GetChannelType).policies[0].public_key !== publicKey
|
||||
? (channelInfo as GetChannelType).policies[0].public_key
|
||||
: (channelInfo as GetChannelType).policies[1].public_key;
|
||||
|
||||
const [nodeInfo, nodeError] = await toWithError(
|
||||
getNode({
|
||||
@ -37,7 +42,7 @@ export const getNodeFromChannel = async (
|
||||
})
|
||||
);
|
||||
|
||||
if (nodeError) {
|
||||
if (nodeError || !nodeInfo) {
|
||||
logger.verbose(
|
||||
`Error getting node with public key ${partnerPublicKey}: %o`,
|
||||
nodeError
|
||||
@ -46,7 +51,7 @@ export const getNodeFromChannel = async (
|
||||
}
|
||||
|
||||
return {
|
||||
alias: nodeInfo.alias,
|
||||
color: nodeInfo.color,
|
||||
alias: (nodeInfo as GetNodeType).alias,
|
||||
color: (nodeInfo as GetNodeType).color,
|
||||
};
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ const { nodeEnv } = serverRuntimeConfig || {};
|
||||
const { noClient } = publicRuntimeConfig || {};
|
||||
|
||||
type LndAuthType = {
|
||||
cert: string;
|
||||
cert: string | null;
|
||||
macaroon: string;
|
||||
host: string;
|
||||
};
|
||||
@ -37,9 +37,9 @@ export const getCorrectAuth = (
|
||||
): LndAuthType => {
|
||||
if (auth.type === 'test' && nodeEnv !== 'production') {
|
||||
return {
|
||||
host: process.env.TEST_HOST,
|
||||
macaroon: process.env.TEST_MACAROON,
|
||||
cert: process.env.TEST_CERT,
|
||||
host: process.env.TEST_HOST || '',
|
||||
macaroon: process.env.TEST_MACAROON || '',
|
||||
cert: process.env.TEST_CERT || '',
|
||||
};
|
||||
}
|
||||
if (auth.type === SERVER_ACCOUNT) {
|
||||
@ -65,7 +65,7 @@ export const getCorrectAuth = (
|
||||
return verifiedAccount;
|
||||
}
|
||||
if (auth.type === SSO_ACCOUNT) {
|
||||
if (!context.ssoVerified) {
|
||||
if (!context.ssoVerified || !context.sso) {
|
||||
logger.debug('SSO Account is not verified');
|
||||
throw new Error('AccountNotAuthenticated');
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ export const accountResolvers = {
|
||||
const { ip, accounts, account, sso, ssoVerified } = context;
|
||||
await requestLimiter(ip, 'getServerAccounts');
|
||||
|
||||
const { macaroon, cert, host } = sso;
|
||||
let ssoAccount = null;
|
||||
if (macaroon && host && ssoVerified) {
|
||||
if (ssoVerified && sso) {
|
||||
const { cert, host } = sso;
|
||||
logger.debug(
|
||||
`Macaroon${
|
||||
cert ? ', certificate' : ''
|
||||
|
@ -21,6 +21,11 @@ export const authResolvers = {
|
||||
const { ip, secret, sso, res } = context;
|
||||
await requestLimiter(ip, 'getAuthToken');
|
||||
|
||||
if (!sso) {
|
||||
logger.warn('No SSO account available');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!sso.host || !sso.macaroon) {
|
||||
logger.warn('Host and macaroon are required for SSO');
|
||||
return null;
|
||||
@ -38,7 +43,7 @@ export const authResolvers = {
|
||||
const cookieFile = readCookie(cookiePath);
|
||||
|
||||
if (
|
||||
cookieFile.trim() === params.cookie.trim() ||
|
||||
(cookieFile && cookieFile.trim() === params.cookie.trim()) ||
|
||||
nodeEnv === 'development'
|
||||
) {
|
||||
refreshCookie(cookiePath);
|
||||
|
@ -7,6 +7,7 @@ import { AuthType } from 'src/context/AccountContext';
|
||||
import { rebalance } from 'balanceofsatoshis/swaps';
|
||||
import { getAccountingReport } from 'balanceofsatoshis/balances';
|
||||
import request from '@alexbosworth/request';
|
||||
import { RebalanceResponseType } from 'server/types/balanceofsatoshis.types';
|
||||
|
||||
type RebalanceType = {
|
||||
auth: AuthType;
|
||||
@ -80,9 +81,9 @@ export const bosResolvers = {
|
||||
out_channels,
|
||||
...(in_through && { in_through }),
|
||||
...(is_avoiding_high_inbound && { is_avoiding_high_inbound }),
|
||||
...(max_fee > 0 && { max_fee }),
|
||||
...(max_fee_rate > 0 && { max_fee_rate }),
|
||||
...(max_rebalance > 0 && { max_rebalance }),
|
||||
...(max_fee && max_fee > 0 && { max_fee }),
|
||||
...(max_fee_rate && max_fee_rate > 0 && { max_fee_rate }),
|
||||
...(max_rebalance && max_rebalance > 0 && { max_rebalance }),
|
||||
...(node && { node }),
|
||||
...(out_through && { out_through }),
|
||||
...(target && { target }),
|
||||
@ -90,7 +91,7 @@ export const bosResolvers = {
|
||||
|
||||
logger.info('Rebalance Params: %o', filteredParams);
|
||||
|
||||
const response = await to(
|
||||
const response = await to<RebalanceResponseType>(
|
||||
rebalance({
|
||||
lnd,
|
||||
logger,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
getChainBalance as getBalance,
|
||||
getPendingChainBalance as getPending,
|
||||
getChainBalance,
|
||||
getPendingChainBalance,
|
||||
getChainTransactions,
|
||||
getUtxos,
|
||||
sendToChainAddress,
|
||||
@ -15,6 +15,14 @@ import {
|
||||
getCorrectAuth,
|
||||
} from 'server/helpers/helpers';
|
||||
import { sortBy } from 'underscore';
|
||||
import { to } from 'server/helpers/async';
|
||||
import {
|
||||
GetChainBalanceType,
|
||||
GetPendingChainBalanceType,
|
||||
GetChainTransactionsType,
|
||||
GetUtxosType,
|
||||
SendToChainAddressType,
|
||||
} from 'server/types/ln-service.types';
|
||||
|
||||
interface ChainBalanceProps {
|
||||
chain_balance: number;
|
||||
@ -36,15 +44,12 @@ export const chainResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const value: ChainBalanceProps = await getBalance({
|
||||
const value: ChainBalanceProps = await to<GetChainBalanceType>(
|
||||
getChainBalance({
|
||||
lnd,
|
||||
});
|
||||
return value.chain_balance;
|
||||
} catch (error) {
|
||||
logger.error('Error getting chain balance: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
})
|
||||
);
|
||||
return value.chain_balance;
|
||||
},
|
||||
getPendingChainBalance: async (
|
||||
_: undefined,
|
||||
@ -56,15 +61,14 @@ export const chainResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const pendingValue: PendingChainBalanceProps = await getPending({
|
||||
const pendingValue: PendingChainBalanceProps = await to<
|
||||
GetPendingChainBalanceType
|
||||
>(
|
||||
getPendingChainBalance({
|
||||
lnd,
|
||||
});
|
||||
return pendingValue.pending_chain_balance;
|
||||
} catch (error) {
|
||||
logger.error('Error getting pending chain balance: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
})
|
||||
);
|
||||
return pendingValue.pending_chain_balance;
|
||||
},
|
||||
getChainTransactions: async (
|
||||
_: undefined,
|
||||
@ -76,20 +80,17 @@ export const chainResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const transactionList = await getChainTransactions({
|
||||
const transactionList = await to<GetChainTransactionsType>(
|
||||
getChainTransactions({
|
||||
lnd,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const transactions = sortBy(
|
||||
transactionList.transactions,
|
||||
'created_at'
|
||||
).reverse();
|
||||
return transactions;
|
||||
} catch (error) {
|
||||
logger.error('Error getting chain transactions: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
const transactions = sortBy(
|
||||
transactionList.transactions,
|
||||
'created_at'
|
||||
).reverse();
|
||||
return transactions;
|
||||
},
|
||||
getUtxos: async (_: undefined, params: any, context: ContextType) => {
|
||||
await requestLimiter(context.ip, 'getUtxos');
|
||||
@ -97,14 +98,9 @@ export const chainResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const { utxos } = await getUtxos({ lnd });
|
||||
const info = await to<GetUtxosType>(getUtxos({ lnd }));
|
||||
|
||||
return utxos;
|
||||
} catch (error) {
|
||||
logger.error('Error getting utxos: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
return info?.utxos;
|
||||
},
|
||||
},
|
||||
Mutation: {
|
||||
@ -143,26 +139,23 @@ export const chainResolvers = {
|
||||
|
||||
const sendAll = params.sendAll ? { is_send_all: true } : {};
|
||||
|
||||
try {
|
||||
const send = await sendToChainAddress({
|
||||
const send = await to<SendToChainAddressType>(
|
||||
sendToChainAddress({
|
||||
lnd,
|
||||
address: params.address,
|
||||
...(params.tokens && { tokens: params.tokens }),
|
||||
...props,
|
||||
...sendAll,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
confirmationCount: send.confirmation_count,
|
||||
id: send.id,
|
||||
isConfirmed: send.is_confirmed,
|
||||
isOutgoing: send.is_outgoing,
|
||||
...(send.tokens && { tokens: send.tokens }),
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error sending to chain address: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
return {
|
||||
confirmationCount: send.confirmation_count,
|
||||
id: send.id,
|
||||
isConfirmed: send.is_confirmed,
|
||||
isOutgoing: send.is_outgoing,
|
||||
...(send.tokens && { tokens: send.tokens }),
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -2,19 +2,19 @@ import { gql } from 'apollo-server-micro';
|
||||
|
||||
export const chainTypes = gql`
|
||||
type getUtxosType {
|
||||
address: String
|
||||
address_format: String
|
||||
confirmation_count: Int
|
||||
output_script: String
|
||||
tokens: Int
|
||||
transaction_id: String
|
||||
transaction_vout: Int
|
||||
address: String!
|
||||
address_format: String!
|
||||
confirmation_count: Int!
|
||||
output_script: String!
|
||||
tokens: Int!
|
||||
transaction_id: String!
|
||||
transaction_vout: Int!
|
||||
}
|
||||
type sendToType {
|
||||
confirmationCount: String
|
||||
id: String
|
||||
isConfirmed: Boolean
|
||||
isOutgoing: Boolean
|
||||
confirmationCount: String!
|
||||
id: String!
|
||||
isConfirmed: Boolean!
|
||||
isOutgoing: Boolean!
|
||||
tokens: Int
|
||||
}
|
||||
|
||||
@ -22,10 +22,10 @@ export const chainTypes = gql`
|
||||
block_id: String
|
||||
confirmation_count: Int
|
||||
confirmation_height: Int
|
||||
created_at: String
|
||||
created_at: String!
|
||||
fee: Int
|
||||
id: String
|
||||
output_addresses: [String]
|
||||
tokens: Int
|
||||
id: String!
|
||||
output_addresses: [String]!
|
||||
tokens: Int!
|
||||
}
|
||||
`;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { toWithError } from 'server/helpers/async';
|
||||
import { getChannel } from 'ln-service';
|
||||
import { GetChannelType } from 'server/types/ln-service.types';
|
||||
import { openChannel } from './resolvers/mutation/openChannel';
|
||||
import { closeChannel } from './resolvers/mutation/closeChannel';
|
||||
import { updateFees } from './resolvers/mutation/updateFees';
|
||||
@ -53,7 +54,7 @@ export const channelResolvers = {
|
||||
let node_policies = null;
|
||||
let partner_node_policies = null;
|
||||
|
||||
channel.policies.forEach(policy => {
|
||||
(channel as GetChannelType).policies.forEach(policy => {
|
||||
if (localKey && localKey === policy.public_key) {
|
||||
node_policies = {
|
||||
...policy,
|
||||
@ -67,7 +68,11 @@ export const channelResolvers = {
|
||||
}
|
||||
});
|
||||
|
||||
return { ...channel, node_policies, partner_node_policies };
|
||||
return {
|
||||
...(channel as GetChannelType),
|
||||
node_policies,
|
||||
partner_node_policies,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1,12 +1,8 @@
|
||||
import { getChannelBalance as getLnChannelBalance } from 'ln-service';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import {
|
||||
getAuthLnd,
|
||||
getErrorMsg,
|
||||
getCorrectAuth,
|
||||
} from 'server/helpers/helpers';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
|
||||
interface ChannelBalanceProps {
|
||||
channel_balance: number;
|
||||
@ -23,16 +19,13 @@ export const getChannelBalance = async (
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
try {
|
||||
const channelBalance: ChannelBalanceProps = await getLnChannelBalance({
|
||||
const channelBalance: ChannelBalanceProps = await to(
|
||||
getLnChannelBalance({
|
||||
lnd,
|
||||
});
|
||||
return {
|
||||
confirmedBalance: channelBalance.channel_balance,
|
||||
pendingBalance: channelBalance.pending_balance,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error getting channel balance: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
})
|
||||
);
|
||||
return {
|
||||
confirmedBalance: channelBalance.channel_balance,
|
||||
pendingBalance: channelBalance.pending_balance,
|
||||
};
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { to } from 'server/helpers/async';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { getChannelAge } from 'server/schema/health/helpers';
|
||||
import { GetChannelsType } from 'server/types/ln-service.types';
|
||||
|
||||
export const getChannels = async (
|
||||
_: undefined,
|
||||
@ -17,7 +18,7 @@ export const getChannels = async (
|
||||
|
||||
const { public_key, current_block_height } = await to(getWalletInfo({ lnd }));
|
||||
|
||||
const { channels } = await to(
|
||||
const { channels } = await to<GetChannelsType>(
|
||||
getLnChannels({
|
||||
lnd,
|
||||
is_active: params.active,
|
||||
|
@ -55,36 +55,36 @@ export const channelTypes = gql`
|
||||
}
|
||||
|
||||
type channelBalanceType {
|
||||
confirmedBalance: Int
|
||||
pendingBalance: Int
|
||||
confirmedBalance: Int!
|
||||
pendingBalance: Int!
|
||||
}
|
||||
|
||||
type channelType {
|
||||
capacity: Int
|
||||
commit_transaction_fee: Int
|
||||
commit_transaction_weight: Int
|
||||
id: String
|
||||
is_active: Boolean
|
||||
is_closing: Boolean
|
||||
is_opening: Boolean
|
||||
is_partner_initiated: Boolean
|
||||
is_private: Boolean
|
||||
capacity: Int!
|
||||
commit_transaction_fee: Int!
|
||||
commit_transaction_weight: Int!
|
||||
id: String!
|
||||
is_active: Boolean!
|
||||
is_closing: Boolean!
|
||||
is_opening: Boolean!
|
||||
is_partner_initiated: Boolean!
|
||||
is_private: Boolean!
|
||||
is_static_remote_key: Boolean
|
||||
local_balance: Int
|
||||
local_reserve: Int
|
||||
partner_public_key: String
|
||||
received: Int
|
||||
remote_balance: Int
|
||||
remote_reserve: Int
|
||||
sent: Int
|
||||
local_balance: Int!
|
||||
local_reserve: Int!
|
||||
partner_public_key: String!
|
||||
received: Int!
|
||||
remote_balance: Int!
|
||||
remote_reserve: Int!
|
||||
sent: Int!
|
||||
time_offline: Int
|
||||
time_online: Int
|
||||
transaction_id: String
|
||||
transaction_vout: Int
|
||||
unsettled_balance: Int
|
||||
partner_node_info: Node
|
||||
transaction_id: String!
|
||||
transaction_vout: Int!
|
||||
unsettled_balance: Int!
|
||||
partner_node_info: Node!
|
||||
partner_fee_info: Channel
|
||||
channel_age: Int
|
||||
channel_age: Int!
|
||||
}
|
||||
|
||||
type closeChannelType {
|
||||
@ -93,21 +93,21 @@ export const channelTypes = gql`
|
||||
}
|
||||
|
||||
type closedChannelType {
|
||||
capacity: Int
|
||||
capacity: Int!
|
||||
close_confirm_height: Int
|
||||
close_transaction_id: String
|
||||
final_local_balance: Int
|
||||
final_time_locked_balance: Int
|
||||
final_local_balance: Int!
|
||||
final_time_locked_balance: Int!
|
||||
id: String
|
||||
is_breach_close: Boolean
|
||||
is_cooperative_close: Boolean
|
||||
is_funding_cancel: Boolean
|
||||
is_local_force_close: Boolean
|
||||
is_remote_force_close: Boolean
|
||||
partner_public_key: String
|
||||
transaction_id: String
|
||||
transaction_vout: Int
|
||||
partner_node_info: Node
|
||||
is_breach_close: Boolean!
|
||||
is_cooperative_close: Boolean!
|
||||
is_funding_cancel: Boolean!
|
||||
is_local_force_close: Boolean!
|
||||
is_remote_force_close: Boolean!
|
||||
partner_public_key: String!
|
||||
transaction_id: String!
|
||||
transaction_vout: Int!
|
||||
partner_node_info: Node!
|
||||
}
|
||||
|
||||
type openChannelType {
|
||||
@ -117,19 +117,19 @@ export const channelTypes = gql`
|
||||
|
||||
type pendingChannelType {
|
||||
close_transaction_id: String
|
||||
is_active: Boolean
|
||||
is_closing: Boolean
|
||||
is_opening: Boolean
|
||||
local_balance: Int
|
||||
local_reserve: Int
|
||||
partner_public_key: String
|
||||
received: Int
|
||||
remote_balance: Int
|
||||
remote_reserve: Int
|
||||
sent: Int
|
||||
is_active: Boolean!
|
||||
is_closing: Boolean!
|
||||
is_opening: Boolean!
|
||||
local_balance: Int!
|
||||
local_reserve: Int!
|
||||
partner_public_key: String!
|
||||
received: Int!
|
||||
remote_balance: Int!
|
||||
remote_reserve: Int!
|
||||
sent: Int!
|
||||
transaction_fee: Int
|
||||
transaction_id: String
|
||||
transaction_vout: Int
|
||||
partner_node_info: Node
|
||||
transaction_id: String!
|
||||
transaction_vout: Int!
|
||||
partner_node_info: Node!
|
||||
}
|
||||
`;
|
||||
|
@ -16,6 +16,10 @@ import {
|
||||
decodeMessage,
|
||||
} from 'server/helpers/customRecords';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import {
|
||||
GetInvoicesType,
|
||||
GetWalletInfoType,
|
||||
} from 'server/types/ln-service.types';
|
||||
|
||||
export const chatResolvers = {
|
||||
Query: {
|
||||
@ -25,7 +29,7 @@ export const chatResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
const invoiceList = await to(
|
||||
const invoiceList = await to<GetInvoicesType>(
|
||||
getInvoices({
|
||||
lnd,
|
||||
limit: params.initialize ? 100 : 5,
|
||||
@ -72,7 +76,11 @@ export const chatResolvers = {
|
||||
logger.debug(`Error verifying message: ${messageToVerify}`);
|
||||
}
|
||||
|
||||
if (!error && verified?.signed_by === customRecords.sender) {
|
||||
if (
|
||||
!error &&
|
||||
(verified as { signed_by: string })?.signed_by ===
|
||||
customRecords.sender
|
||||
) {
|
||||
isVerified = true;
|
||||
}
|
||||
}
|
||||
@ -88,7 +96,7 @@ export const chatResolvers = {
|
||||
);
|
||||
|
||||
const filtered = await getFiltered();
|
||||
const final = filtered.filter(message => !!message);
|
||||
const final = filtered.filter(Boolean) || [];
|
||||
|
||||
return { token: invoiceList.next, messages: final };
|
||||
},
|
||||
@ -126,7 +134,7 @@ export const chatResolvers = {
|
||||
messageToSend = `${params.tokens},${params.message}`;
|
||||
}
|
||||
|
||||
const nodeInfo = await to(
|
||||
const nodeInfo = await to<GetWalletInfoType>(
|
||||
getWalletInfo({
|
||||
lnd,
|
||||
})
|
||||
@ -167,7 +175,8 @@ export const chatResolvers = {
|
||||
messages: customRecords,
|
||||
})
|
||||
);
|
||||
return safe_fee;
|
||||
// +1 is needed so that a fee of 0 doesnt evaluate to false
|
||||
return safe_fee + 1;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -3,13 +3,13 @@ import { gql } from 'apollo-server-micro';
|
||||
export const chatTypes = gql`
|
||||
type getMessagesType {
|
||||
token: String
|
||||
messages: [messagesType]
|
||||
messages: [messagesType]!
|
||||
}
|
||||
|
||||
type messagesType {
|
||||
date: String
|
||||
id: String
|
||||
verified: Boolean
|
||||
date: String!
|
||||
id: String!
|
||||
verified: Boolean!
|
||||
contentType: String
|
||||
sender: String
|
||||
alias: String
|
||||
|
@ -15,7 +15,7 @@ export const githubResolvers = {
|
||||
|
||||
const [response, error] = await toWithError(fetch(appUrls.github));
|
||||
|
||||
if (error) {
|
||||
if (error || !response) {
|
||||
logger.debug('Unable to get latest github version');
|
||||
throw new Error('NoGithubVersion');
|
||||
}
|
||||
|
@ -1,6 +1,15 @@
|
||||
import { groupBy } from 'underscore';
|
||||
import { ForwardType } from 'server/types/ln-service.types';
|
||||
|
||||
export const getChannelVolume = forwards => {
|
||||
type GroupedObject = {
|
||||
[key: string]: ForwardType[];
|
||||
};
|
||||
|
||||
type TotalGroupedObject = {
|
||||
[key: string]: { tokens: number }[];
|
||||
};
|
||||
|
||||
export const getChannelVolume = (forwards: ForwardType[]) => {
|
||||
const orderedIncoming = groupBy(forwards, f => f.incoming_channel);
|
||||
const orderedOutgoing = groupBy(forwards, f => f.outgoing_channel);
|
||||
|
||||
@ -14,7 +23,7 @@ export const getChannelVolume = forwards => {
|
||||
return reduceTokens(together);
|
||||
};
|
||||
|
||||
const reduceTokens = array => {
|
||||
const reduceTokens = (array: GroupedObject | TotalGroupedObject) => {
|
||||
const reducedArray = [];
|
||||
for (const key in array) {
|
||||
if (Object.prototype.hasOwnProperty.call(array, key)) {
|
||||
|
@ -4,6 +4,7 @@ import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { to, toWithError } from 'server/helpers/async';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { GetChannelsType, GetChannelType } from 'server/types/ln-service.types';
|
||||
import { getFeeScore, getAverage, getMyFeeScore } from '../helpers';
|
||||
|
||||
type ChannelFeesType = {
|
||||
@ -22,28 +23,30 @@ export default async (_: undefined, params: any, context: ContextType) => {
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
const { public_key } = await to(getWalletInfo({ lnd }));
|
||||
const { channels } = await to(getChannels({ lnd }));
|
||||
const { channels } = await to<GetChannelsType>(getChannels({ lnd }));
|
||||
|
||||
const getChannelList = () =>
|
||||
Promise.all(
|
||||
channels
|
||||
.map(async channel => {
|
||||
const { id, partner_public_key: publicKey } = channel;
|
||||
const [{ policies }, channelError] = await toWithError(
|
||||
const [channelInfo, channelError] = await toWithError(
|
||||
getChannel({
|
||||
lnd,
|
||||
id,
|
||||
})
|
||||
);
|
||||
|
||||
if (channelError) {
|
||||
if (channelError || !channelInfo) {
|
||||
logger.debug(
|
||||
`Error getting channel with id ${id}: %o`,
|
||||
channelError
|
||||
);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
const policies = (channelInfo as GetChannelType).policies;
|
||||
|
||||
let partnerBaseFee = 0;
|
||||
let partnerFeeRate = 0;
|
||||
let myBaseFee = 0;
|
||||
@ -77,7 +80,7 @@ export default async (_: undefined, params: any, context: ContextType) => {
|
||||
|
||||
const list = await getChannelList();
|
||||
|
||||
const health = list.map((channel: ChannelFeesType) => {
|
||||
const health = (list as ChannelFeesType[]).map((channel: ChannelFeesType) => {
|
||||
const partnerRateScore = getFeeScore(2000, channel.partnerFeeRate);
|
||||
const partnerBaseScore = getFeeScore(100000, channel.partnerBaseFee);
|
||||
const myRateScore = getMyFeeScore(2000, channel.myFeeRate, 200);
|
||||
|
@ -3,6 +3,7 @@ import { getCorrectAuth, getAuthLnd } from 'server/helpers/helpers';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { GetChannelsType } from 'server/types/ln-service.types';
|
||||
import { getAverage } from '../helpers';
|
||||
|
||||
const halfMonthInMilliSeconds = 1296000000;
|
||||
@ -13,7 +14,7 @@ export default async (_: undefined, params: any, context: ContextType) => {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
const { channels } = await to(getChannels({ lnd }));
|
||||
const { channels } = await to<GetChannelsType>(getChannels({ lnd }));
|
||||
|
||||
const health = channels.map(channel => {
|
||||
const {
|
||||
|
@ -4,6 +4,10 @@ import { getCorrectAuth, getAuthLnd } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { subMonths } from 'date-fns';
|
||||
import { ContextType } from 'server/types/apiTypes';
|
||||
import {
|
||||
GetChannelsType,
|
||||
GetForwardsType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { getChannelVolume, getChannelIdInfo, getAverage } from '../helpers';
|
||||
|
||||
const monthInBlocks = 4380;
|
||||
@ -18,15 +22,20 @@ export default async (_: undefined, params: any, context: ContextType) => {
|
||||
const after = subMonths(new Date(), 1).toISOString();
|
||||
|
||||
const { current_block_height } = await to(getWalletInfo({ lnd }));
|
||||
const { channels } = await to(getChannels({ lnd }));
|
||||
const { forwards } = await to(getForwards({ lnd, after, before }));
|
||||
const { channels } = await to<GetChannelsType>(getChannels({ lnd }));
|
||||
const { forwards } = await to<GetForwardsType>(
|
||||
getForwards({ lnd, after, before })
|
||||
);
|
||||
|
||||
const channelVolume = getChannelVolume(forwards);
|
||||
const channelVolume: { channel: string; tokens: number }[] = getChannelVolume(
|
||||
forwards
|
||||
);
|
||||
|
||||
const channelDetails = channels
|
||||
.map(channel => {
|
||||
const { tokens } =
|
||||
channelVolume.find(c => c.channel === channel.id) || {};
|
||||
const { tokens } = channelVolume.find(c => c.channel === channel.id) || {
|
||||
tokens: 0,
|
||||
};
|
||||
const info = getChannelIdInfo(channel.id);
|
||||
|
||||
if (!info) return;
|
||||
@ -45,23 +54,26 @@ export default async (_: undefined, params: any, context: ContextType) => {
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
const average = getAverage(channelDetails.map(c => c.volumeNormalized));
|
||||
const average = getAverage(channelDetails.map(c => c?.volumeNormalized || 0));
|
||||
|
||||
const health = channelDetails.map(channel => {
|
||||
const diff = (channel.volumeNormalized - average) / average || -1;
|
||||
const score = Math.round((diff + 1) * 100);
|
||||
const health = channelDetails
|
||||
.map(channel => {
|
||||
if (!channel) return null;
|
||||
const diff = (channel.volumeNormalized - average) / average || -1;
|
||||
const score = Math.round((diff + 1) * 100);
|
||||
|
||||
return {
|
||||
id: channel.id,
|
||||
score,
|
||||
volumeNormalized: channel.volumeNormalized,
|
||||
averageVolumeNormalized: average,
|
||||
partner: { publicKey: channel.publicKey, lnd },
|
||||
};
|
||||
});
|
||||
return {
|
||||
id: channel.id,
|
||||
score,
|
||||
volumeNormalized: channel.volumeNormalized,
|
||||
averageVolumeNormalized: average,
|
||||
partner: { publicKey: channel.publicKey, lnd },
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
const globalAverage = Math.round(
|
||||
getAverage(health.map(c => Math.min(c.score, 100)))
|
||||
getAverage(health.map(c => Math.min(c?.score || 0, 100)))
|
||||
);
|
||||
|
||||
return { score: globalAverage, channels: health };
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
getLnd,
|
||||
} from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { DecodedType } from 'server/types/ln-service.types';
|
||||
|
||||
const KEYSEND_TYPE = '5482373484';
|
||||
|
||||
@ -26,7 +27,7 @@ export const invoiceResolvers = {
|
||||
|
||||
const lnd = getLnd(params.auth, context);
|
||||
|
||||
const decoded = await to(
|
||||
const decoded = await to<DecodedType>(
|
||||
decodePaymentRequest({
|
||||
lnd,
|
||||
request: params.request,
|
||||
|
@ -4,16 +4,16 @@ export const invoiceTypes = gql`
|
||||
type decodeType {
|
||||
chain_address: String
|
||||
cltv_delta: Int
|
||||
description: String
|
||||
description: String!
|
||||
description_hash: String
|
||||
destination: String
|
||||
expires_at: String
|
||||
id: String
|
||||
mtokens: String
|
||||
destination: String!
|
||||
expires_at: String!
|
||||
id: String!
|
||||
mtokens: String!
|
||||
payment: String
|
||||
routes: [[RouteType]]
|
||||
safe_tokens: Int
|
||||
tokens: Int
|
||||
routes: [[RouteType]]!
|
||||
safe_tokens: Int!
|
||||
tokens: Int!
|
||||
destination_node: Node!
|
||||
probe_route: ProbeRoute
|
||||
}
|
||||
@ -23,7 +23,7 @@ export const invoiceTypes = gql`
|
||||
channel: String
|
||||
cltv_delta: Int
|
||||
fee_rate: Int
|
||||
public_key: String
|
||||
public_key: String!
|
||||
}
|
||||
|
||||
type payType {
|
||||
|
@ -6,14 +6,18 @@ import { appUrls } from 'server/utils/appUrls';
|
||||
|
||||
export const lnpayResolvers = {
|
||||
Query: {
|
||||
getLnPay: async (_: undefined, params: any, context: ContextType) => {
|
||||
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) {
|
||||
if (error || !response) {
|
||||
logger.debug('Unable to get lnpay invoice: %o', error);
|
||||
throw new Error('NoLnPayInvoice');
|
||||
}
|
||||
@ -26,7 +30,7 @@ export const lnpayResolvers = {
|
||||
|
||||
const [response, error] = await toWithError(fetch(appUrls.lnpay));
|
||||
|
||||
if (error) {
|
||||
if (error || !response) {
|
||||
logger.debug('Unable to connect to ThunderHub LNPAY');
|
||||
throw new Error('NoLnPay');
|
||||
}
|
||||
|
@ -1,16 +1,24 @@
|
||||
import {
|
||||
getNode as getLnNode,
|
||||
getWalletInfo,
|
||||
getClosedChannels,
|
||||
} from 'ln-service';
|
||||
import { getNode, getWalletInfo, getClosedChannels } from 'ln-service';
|
||||
import { to, toWithError } from 'server/helpers/async';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import {
|
||||
ClosedChannelsType,
|
||||
LndObject,
|
||||
GetWalletInfoType,
|
||||
GetNodeType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { getAuthLnd, getCorrectAuth, getLnd } from '../../helpers/helpers';
|
||||
import { ContextType } from '../../types/apiTypes';
|
||||
import { logger } from '../../helpers/logger';
|
||||
|
||||
const errorNode = { alias: 'Node not found' };
|
||||
|
||||
type NodeParent = {
|
||||
lnd: LndObject;
|
||||
publicKey: string;
|
||||
withChannels?: boolean;
|
||||
};
|
||||
|
||||
export const nodeResolvers = {
|
||||
Query: {
|
||||
getNode: async (_: undefined, params: any, context: ContextType) => {
|
||||
@ -27,13 +35,13 @@ export const nodeResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
const info = await to(
|
||||
const info = await to<GetWalletInfoType>(
|
||||
getWalletInfo({
|
||||
lnd,
|
||||
})
|
||||
);
|
||||
|
||||
const closedChannels = await to(
|
||||
const closedChannels: ClosedChannelsType = await to(
|
||||
getClosedChannels({
|
||||
lnd,
|
||||
})
|
||||
@ -46,7 +54,7 @@ export const nodeResolvers = {
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
node: async parent => {
|
||||
node: async (parent: NodeParent) => {
|
||||
const { lnd, withChannels, publicKey } = parent;
|
||||
|
||||
if (!lnd) {
|
||||
@ -60,19 +68,19 @@ export const nodeResolvers = {
|
||||
}
|
||||
|
||||
const [info, error] = await toWithError(
|
||||
getLnNode({
|
||||
getNode({
|
||||
lnd,
|
||||
is_omitting_channels: !withChannels,
|
||||
public_key: publicKey,
|
||||
})
|
||||
);
|
||||
|
||||
if (error) {
|
||||
if (error || !info) {
|
||||
logger.debug(`Error getting node with key: ${publicKey}`);
|
||||
return errorNode;
|
||||
}
|
||||
|
||||
return { ...info, public_key: publicKey };
|
||||
return { ...(info as GetNodeType), public_key: publicKey };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -11,24 +11,24 @@ export const nodeTypes = gql`
|
||||
}
|
||||
|
||||
type Node {
|
||||
node: nodeType
|
||||
node: nodeType!
|
||||
}
|
||||
|
||||
type nodeInfoType {
|
||||
chains: [String]
|
||||
color: String
|
||||
active_channels_count: Int
|
||||
closed_channels_count: Int
|
||||
alias: String
|
||||
current_block_hash: String
|
||||
current_block_height: Int
|
||||
is_synced_to_chain: Boolean
|
||||
is_synced_to_graph: Boolean
|
||||
latest_block_at: String
|
||||
peers_count: Int
|
||||
pending_channels_count: Int
|
||||
public_key: String
|
||||
uris: [String]
|
||||
version: String
|
||||
chains: [String!]!
|
||||
color: String!
|
||||
active_channels_count: Int!
|
||||
closed_channels_count: Int!
|
||||
alias: String!
|
||||
current_block_hash: String!
|
||||
current_block_height: Int!
|
||||
is_synced_to_chain: Boolean!
|
||||
is_synced_to_graph: Boolean!
|
||||
latest_block_at: String!
|
||||
peers_count: Int!
|
||||
pending_channels_count: Int!
|
||||
public_key: String!
|
||||
uris: [String!]!
|
||||
version: String!
|
||||
}
|
||||
`;
|
||||
|
@ -2,15 +2,15 @@ import { gql } from 'apollo-server-micro';
|
||||
|
||||
export const peerTypes = gql`
|
||||
type peerType {
|
||||
bytes_received: Int
|
||||
bytes_sent: Int
|
||||
is_inbound: Boolean
|
||||
bytes_received: Int!
|
||||
bytes_sent: Int!
|
||||
is_inbound: Boolean!
|
||||
is_sync_peer: Boolean
|
||||
ping_time: Int
|
||||
public_key: String
|
||||
socket: String
|
||||
tokens_received: Int
|
||||
tokens_sent: Int
|
||||
partner_node_info: Node
|
||||
ping_time: Int!
|
||||
public_key: String!
|
||||
socket: String!
|
||||
tokens_received: Int!
|
||||
tokens_sent: Int!
|
||||
partner_node_info: Node!
|
||||
}
|
||||
`;
|
||||
|
@ -8,6 +8,13 @@ import { logger } from 'server/helpers/logger';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getLnd } from 'server/helpers/helpers';
|
||||
import { toWithError, to } from 'server/helpers/async';
|
||||
import { LndObject, ProbeForRouteType } from 'server/types/ln-service.types';
|
||||
|
||||
type RouteParent = {
|
||||
lnd: LndObject;
|
||||
destination: string;
|
||||
tokens: number;
|
||||
};
|
||||
|
||||
export const routeResolvers = {
|
||||
Query: {
|
||||
@ -37,7 +44,7 @@ export const routeResolvers = {
|
||||
},
|
||||
},
|
||||
ProbeRoute: {
|
||||
route: async parent => {
|
||||
route: async (parent: RouteParent) => {
|
||||
const { lnd, destination, tokens } = parent;
|
||||
|
||||
if (!lnd) {
|
||||
@ -61,19 +68,20 @@ export const routeResolvers = {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!info.route) {
|
||||
if (!(info as ProbeForRouteType).route) {
|
||||
logger.debug(
|
||||
`No route found to destination ${destination} for ${tokens} tokens`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const hopsWithNodes = info.route.hops.map(h => ({
|
||||
...h,
|
||||
node: { lnd, publicKey: h.public_key },
|
||||
}));
|
||||
const hopsWithNodes =
|
||||
(info as ProbeForRouteType).route?.hops.map(h => ({
|
||||
...h,
|
||||
node: { lnd, publicKey: h.public_key },
|
||||
})) || [];
|
||||
|
||||
return { ...info.route, hops: hopsWithNodes };
|
||||
return { ...(info as ProbeForRouteType).route, hops: hopsWithNodes };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -19,12 +19,17 @@ export const tbaseResolvers = {
|
||||
body: JSON.stringify({ query }),
|
||||
})
|
||||
);
|
||||
if (fetchError) return [];
|
||||
if (fetchError || !response) return [];
|
||||
const result = await response.json();
|
||||
const { errors, data } = result || {};
|
||||
if (errors) return [];
|
||||
|
||||
return data?.getNodes?.filter(n => n.public_key && n.socket) || [];
|
||||
return (
|
||||
data?.getNodes?.filter(
|
||||
(n: { public_key: string; socket: string }) =>
|
||||
n.public_key && n.socket
|
||||
) || []
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ export const tbaseTypes = gql`
|
||||
type baseNodesType {
|
||||
_id: String
|
||||
name: String
|
||||
public_key: String
|
||||
socket: String
|
||||
public_key: String!
|
||||
socket: String!
|
||||
}
|
||||
`;
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
getLnd,
|
||||
} from 'server/helpers/helpers';
|
||||
import { toWithError } from 'server/helpers/async';
|
||||
import { ChannelType } from 'server/types/ln-service.types';
|
||||
|
||||
export const toolsResolvers = {
|
||||
Query: {
|
||||
@ -25,7 +26,7 @@ export const toolsResolvers = {
|
||||
const auth = getCorrectAuth(params.auth, context);
|
||||
const lnd = getAuthLnd(auth);
|
||||
|
||||
let backupObj = { backup: '', channels: [] };
|
||||
let backupObj = { backup: '', channels: [] as ChannelType[] };
|
||||
try {
|
||||
backupObj = JSON.parse(params.backup);
|
||||
} catch (error) {
|
||||
|
@ -1,67 +0,0 @@
|
||||
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[];
|
||||
}
|
||||
|
||||
interface InvoiceMessagesType {
|
||||
type: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface InvoicePaymentProps {
|
||||
confirmed_at: string;
|
||||
created_at: string;
|
||||
created_height: number;
|
||||
in_channel: string;
|
||||
is_canceled: boolean;
|
||||
is_confirmed: boolean;
|
||||
is_held: boolean;
|
||||
messages: InvoiceMessagesType[];
|
||||
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;
|
||||
}
|
@ -10,8 +10,16 @@ import { ContextType } from 'server/types/apiTypes';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { ForwardCompleteProps } from '../widgets/resolvers/interface';
|
||||
import { PaymentsProps, InvoicesProps } from './interface';
|
||||
import {
|
||||
GetInvoicesType,
|
||||
GetPaymentsType,
|
||||
InvoiceType,
|
||||
PaymentType,
|
||||
GetForwardsType,
|
||||
} from 'server/types/ln-service.types';
|
||||
|
||||
type TransactionType = InvoiceType | PaymentType;
|
||||
type TransactionWithType = { isTypeOf: string } & TransactionType;
|
||||
|
||||
export const transactionResolvers = {
|
||||
Query: {
|
||||
@ -30,7 +38,7 @@ export const transactionResolvers = {
|
||||
let token = '';
|
||||
let withInvoices = true;
|
||||
|
||||
const invoiceList: InvoicesProps = await to(
|
||||
const invoiceList = await to<GetInvoicesType>(
|
||||
getInvoices({
|
||||
lnd,
|
||||
...invoiceProps,
|
||||
@ -52,10 +60,10 @@ export const transactionResolvers = {
|
||||
const { date } = invoices[invoices.length - 1];
|
||||
firstInvoiceDate = invoices[0].date;
|
||||
lastInvoiceDate = date;
|
||||
token = invoiceList.next;
|
||||
token = invoiceList.next || '';
|
||||
}
|
||||
|
||||
const paymentList: PaymentsProps = await to(
|
||||
const paymentList = await to<GetPaymentsType>(
|
||||
getPayments({
|
||||
lnd,
|
||||
})
|
||||
@ -70,7 +78,7 @@ export const transactionResolvers = {
|
||||
isTypeOf: 'PaymentType',
|
||||
}));
|
||||
|
||||
const filterArray = payment => {
|
||||
const filterArray = (payment: typeof payments[number]) => {
|
||||
const last =
|
||||
compareDesc(new Date(lastInvoiceDate), new Date(payment.date)) === 1;
|
||||
const first = params.token
|
||||
@ -123,7 +131,7 @@ export const transactionResolvers = {
|
||||
})
|
||||
);
|
||||
|
||||
const forwardsList: ForwardCompleteProps = await to(
|
||||
const forwardsList = await to<GetForwardsType>(
|
||||
getLnForwards({
|
||||
lnd,
|
||||
after: startDate,
|
||||
@ -153,7 +161,7 @@ export const transactionResolvers = {
|
||||
},
|
||||
},
|
||||
Transaction: {
|
||||
__resolveType(parent) {
|
||||
__resolveType(parent: TransactionWithType) {
|
||||
return parent.isTypeOf;
|
||||
},
|
||||
},
|
||||
|
@ -24,7 +24,7 @@ export const transactionTypes = gql`
|
||||
destination_node: Node
|
||||
fee: Int!
|
||||
fee_mtokens: String!
|
||||
hops: [Node]
|
||||
hops: [Node!]!
|
||||
id: String!
|
||||
index: Int
|
||||
is_confirmed: Boolean!
|
||||
|
@ -49,7 +49,7 @@ export const queryTypes = gql`
|
||||
getTimeHealth(auth: authType!): channelsTimeHealth
|
||||
getFeeHealth(auth: authType!): channelsFeeHealth
|
||||
getChannelBalance(auth: authType!): channelBalanceType
|
||||
getChannels(auth: authType!, active: Boolean): [channelType]
|
||||
getChannels(auth: authType!, active: Boolean): [channelType]!
|
||||
getClosedChannels(auth: authType!, type: String): [closedChannelType]
|
||||
getPendingChannels(auth: authType!): [pendingChannelType]
|
||||
getChannelFees(auth: authType!): [channelFeeType]
|
||||
|
@ -2,14 +2,14 @@ import { gql } from 'apollo-server-micro';
|
||||
|
||||
export const walletTypes = gql`
|
||||
type walletInfoType {
|
||||
build_tags: [String]
|
||||
commit_hash: String
|
||||
is_autopilotrpc_enabled: Boolean
|
||||
is_chainrpc_enabled: Boolean
|
||||
is_invoicesrpc_enabled: Boolean
|
||||
is_signrpc_enabled: Boolean
|
||||
is_walletrpc_enabled: Boolean
|
||||
is_watchtowerrpc_enabled: Boolean
|
||||
is_wtclientrpc_enabled: Boolean
|
||||
build_tags: [String!]!
|
||||
commit_hash: String!
|
||||
is_autopilotrpc_enabled: Boolean!
|
||||
is_chainrpc_enabled: Boolean!
|
||||
is_invoicesrpc_enabled: Boolean!
|
||||
is_signrpc_enabled: Boolean!
|
||||
is_walletrpc_enabled: Boolean!
|
||||
is_watchtowerrpc_enabled: Boolean!
|
||||
is_wtclientrpc_enabled: Boolean!
|
||||
}
|
||||
`;
|
||||
|
@ -3,6 +3,7 @@ import { ContextType } from 'server/types/apiTypes';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getLnd } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { GetChannelsType } from 'server/types/ln-service.types';
|
||||
|
||||
export const getChannelReport = async (
|
||||
_: undefined,
|
||||
@ -13,7 +14,7 @@ export const getChannelReport = async (
|
||||
|
||||
const lnd = getLnd(params.auth, context);
|
||||
|
||||
const info = await to(getChannels({ lnd }));
|
||||
const info = await to<GetChannelsType>(getChannels({ lnd }));
|
||||
|
||||
if (!info || info?.channels?.length <= 0) {
|
||||
return;
|
||||
|
@ -6,8 +6,11 @@ import { getNodeFromChannel } from 'server/helpers/getNodeFromChannel';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import {
|
||||
GetForwardsType,
|
||||
GetWalletInfoType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { countArray, countRoutes } from './helpers';
|
||||
import { ForwardCompleteProps } from './interface';
|
||||
|
||||
export const getForwardChannelsReport = async (
|
||||
_: undefined,
|
||||
@ -76,7 +79,7 @@ export const getForwardChannelsReport = async (
|
||||
})
|
||||
);
|
||||
|
||||
const forwardsList: ForwardCompleteProps = await to(
|
||||
const forwardsList = await to<GetForwardsType>(
|
||||
getForwards({
|
||||
lnd,
|
||||
after: startDate,
|
||||
@ -84,7 +87,7 @@ export const getForwardChannelsReport = async (
|
||||
})
|
||||
);
|
||||
|
||||
const walletInfo: { public_key: string } = await to(
|
||||
const walletInfo = await to<GetWalletInfoType>(
|
||||
getWalletInfo({
|
||||
lnd,
|
||||
})
|
||||
@ -101,9 +104,15 @@ export const getForwardChannelsReport = async (
|
||||
|
||||
while (!finishedFetching) {
|
||||
if (next) {
|
||||
const moreForwards = await to(getForwards({ lnd, token: next }));
|
||||
const moreForwards = await to<GetForwardsType>(
|
||||
getForwards({ lnd, token: next })
|
||||
);
|
||||
forwards = [...forwards, ...moreForwards.forwards];
|
||||
next = moreForwards.next;
|
||||
if (moreForwards.next) {
|
||||
next = moreForwards.next;
|
||||
} else {
|
||||
finishedFetching = true;
|
||||
}
|
||||
} else {
|
||||
finishedFetching = true;
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import { ContextType } from 'server/types/apiTypes';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import { GetForwardsType } from 'server/types/ln-service.types';
|
||||
import { reduceForwardArray } from './helpers';
|
||||
import { ForwardCompleteProps } from './interface';
|
||||
|
||||
export const getForwardReport = async (
|
||||
_: undefined,
|
||||
@ -45,7 +45,7 @@ export const getForwardReport = async (
|
||||
startDate = subHours(endDate, 24);
|
||||
}
|
||||
|
||||
const forwardsList: ForwardCompleteProps = await to(
|
||||
const forwardsList = await to<GetForwardsType>(
|
||||
getForwards({
|
||||
lnd,
|
||||
after: startDate,
|
||||
@ -64,7 +64,9 @@ export const getForwardReport = async (
|
||||
|
||||
while (!finishedFetching) {
|
||||
if (next) {
|
||||
const moreForwards = await to(getForwards({ lnd, token: next }));
|
||||
const moreForwards = await to<GetForwardsType>(
|
||||
getForwards({ lnd, token: next })
|
||||
);
|
||||
forwards = [...forwards, ...moreForwards.forwards];
|
||||
next = moreForwards.next;
|
||||
} else {
|
||||
|
@ -5,6 +5,10 @@ import { ContextType } from 'server/types/apiTypes';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { getAuthLnd, getCorrectAuth } from 'server/helpers/helpers';
|
||||
import { to } from 'server/helpers/async';
|
||||
import {
|
||||
GetInvoicesType,
|
||||
GetPaymentsType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { reduceInOutArray } from './helpers';
|
||||
|
||||
export const getInOut = async (
|
||||
@ -35,8 +39,10 @@ export const getInOut = async (
|
||||
difference = (date: string) => differenceInHours(endDate, new Date(date));
|
||||
}
|
||||
|
||||
const invoiceList = await to(getInvoices({ lnd, limit: 50 }));
|
||||
const paymentList = await to(getPayments({ lnd }));
|
||||
const invoiceList = await to<GetInvoicesType>(
|
||||
getInvoices({ lnd, limit: 50 })
|
||||
);
|
||||
const paymentList = await to<GetPaymentsType>(getPayments({ lnd }));
|
||||
|
||||
let invoiceArray = invoiceList.invoices;
|
||||
let next = invoiceList.next;
|
||||
@ -51,7 +57,9 @@ export const getInOut = async (
|
||||
const dif = difference(lastInvoice.created_at);
|
||||
|
||||
if (next && dif < periods) {
|
||||
const newInvoices = await to(getInvoices({ lnd, token: next }));
|
||||
const newInvoices = await to<GetInvoicesType>(
|
||||
getInvoices({ lnd, token: next })
|
||||
);
|
||||
invoiceArray = [...invoiceArray, ...newInvoices.invoices];
|
||||
next = newInvoices.next;
|
||||
} else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { reduce, groupBy } from 'underscore';
|
||||
import { ForwardType } from 'server/types/ln-service.types';
|
||||
import {
|
||||
ForwardProps,
|
||||
ReduceObjectProps,
|
||||
ListProps,
|
||||
InOutProps,
|
||||
@ -11,7 +11,7 @@ export const reduceForwardArray = (list: ListProps) => {
|
||||
const reducedOrder = [];
|
||||
for (const key in list) {
|
||||
if (Object.prototype.hasOwnProperty.call(list, key)) {
|
||||
const element: ForwardProps[] = list[key];
|
||||
const element: ForwardType[] = list[key];
|
||||
const reducedArray: ReduceObjectProps = reduce(
|
||||
element,
|
||||
(a: ReduceObjectProps, b: ReduceObjectProps) => {
|
||||
@ -19,7 +19,8 @@ export const reduceForwardArray = (list: ListProps) => {
|
||||
fee: a.fee + b.fee,
|
||||
tokens: a.tokens + b.tokens,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ fee: 0, tokens: 0 }
|
||||
);
|
||||
reducedOrder.push({
|
||||
period: Number(key),
|
||||
@ -39,9 +40,10 @@ export const reduceInOutArray = (list: InOutListProps) => {
|
||||
const element: InOutProps[] = list[key];
|
||||
const reducedArray: InOutProps = reduce(
|
||||
element,
|
||||
(a: ReduceObjectProps, b: ReduceObjectProps) => ({
|
||||
(a, b) => ({
|
||||
tokens: a.tokens + b.tokens,
|
||||
})
|
||||
}),
|
||||
{ tokens: 0 }
|
||||
);
|
||||
reducedOrder.push({
|
||||
period: Number(key),
|
||||
@ -53,7 +55,7 @@ export const reduceInOutArray = (list: InOutListProps) => {
|
||||
return reducedOrder;
|
||||
};
|
||||
|
||||
export const countArray = (list: ForwardProps[], type: boolean) => {
|
||||
export const countArray = (list: ForwardType[], type: boolean) => {
|
||||
const inOrOut = type ? 'incoming_channel' : 'outgoing_channel';
|
||||
const grouped = groupBy(list, inOrOut);
|
||||
|
||||
@ -82,7 +84,7 @@ export const countArray = (list: ForwardProps[], type: boolean) => {
|
||||
return channelInfo;
|
||||
};
|
||||
|
||||
export const countRoutes = (list: ForwardProps[]) => {
|
||||
export const countRoutes = (list: ForwardType[]) => {
|
||||
const grouped = groupBy(list, 'route');
|
||||
|
||||
const channelInfo = [];
|
||||
|
@ -1,20 +1,7 @@
|
||||
export interface ForwardProps {
|
||||
created_at: string;
|
||||
fee: number;
|
||||
fee_mtokens: string;
|
||||
incoming_channel: string;
|
||||
mtokens: string;
|
||||
outgoing_channel: string;
|
||||
tokens: number;
|
||||
}
|
||||
|
||||
export interface ForwardCompleteProps {
|
||||
forwards: ForwardProps[];
|
||||
next: string;
|
||||
}
|
||||
import { ForwardType } from 'server/types/ln-service.types';
|
||||
|
||||
export interface ListProps {
|
||||
[key: string]: ForwardProps[];
|
||||
[key: string]: ForwardType[];
|
||||
}
|
||||
|
||||
export interface ReduceObjectProps {
|
||||
|
@ -49,11 +49,7 @@ export const ContextMockNoSSO: ContextType = {
|
||||
secret: '123456789',
|
||||
ssoVerified: true,
|
||||
account: 'accountID',
|
||||
sso: {
|
||||
macaroon: null,
|
||||
cert: null,
|
||||
host: null,
|
||||
},
|
||||
sso: null,
|
||||
accounts: [
|
||||
{
|
||||
name: 'account',
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { ServerResponse } from 'http';
|
||||
|
||||
type SSOType = {
|
||||
macaroon: string | null;
|
||||
export type SSOType = {
|
||||
macaroon: string;
|
||||
cert: string | null;
|
||||
host: string | null;
|
||||
host: string;
|
||||
};
|
||||
|
||||
type AccountType = {
|
||||
export type AccountType = {
|
||||
name: string;
|
||||
id: string;
|
||||
host: string;
|
||||
@ -20,7 +20,7 @@ export type ContextType = {
|
||||
secret: string;
|
||||
ssoVerified: boolean;
|
||||
account: string | null;
|
||||
sso: SSOType;
|
||||
sso: SSOType | null;
|
||||
accounts: AccountType[];
|
||||
res: ServerResponse;
|
||||
};
|
||||
|
1
server/types/balanceofsatoshis.types.ts
Normal file
1
server/types/balanceofsatoshis.types.ts
Normal file
@ -0,0 +1 @@
|
||||
export type RebalanceResponseType = { rebalance: [{}, {}, {}] };
|
94
server/types/ln-service.types.ts
Normal file
94
server/types/ln-service.types.ts
Normal file
@ -0,0 +1,94 @@
|
||||
export type LndObject = {};
|
||||
|
||||
export type ChannelType = {
|
||||
id: string;
|
||||
tokens: number;
|
||||
is_partner_initiated: boolean;
|
||||
commit_transaction_fee: number;
|
||||
is_active: boolean;
|
||||
local_balance: number;
|
||||
remote_balance: number;
|
||||
partner_public_key: string;
|
||||
time_offline?: number;
|
||||
time_online?: number;
|
||||
};
|
||||
|
||||
export type DecodedType = {
|
||||
destination: string;
|
||||
tokens: number;
|
||||
};
|
||||
|
||||
export type ClosedChannelsType = {
|
||||
channels: [];
|
||||
};
|
||||
|
||||
export type InvoiceType = {
|
||||
id: string;
|
||||
created_at: string;
|
||||
confirmed_at: string;
|
||||
tokens: number;
|
||||
is_confirmed: boolean;
|
||||
received: number;
|
||||
payments: { messages: [{ type: string; value: string }] }[];
|
||||
};
|
||||
|
||||
export type PaymentType = {
|
||||
created_at: string;
|
||||
is_confirmed: boolean;
|
||||
tokens: number;
|
||||
destination: string;
|
||||
hops: string[];
|
||||
};
|
||||
|
||||
export type ForwardType = {
|
||||
tokens: number;
|
||||
incoming_channel: string;
|
||||
outgoing_channel: string;
|
||||
created_at: string;
|
||||
fee: number;
|
||||
};
|
||||
|
||||
export type GetWalletInfoType = {
|
||||
alias: string;
|
||||
public_key: string;
|
||||
};
|
||||
|
||||
export type GetNodeType = { alias: string; color: string };
|
||||
|
||||
export type UtxoType = {};
|
||||
|
||||
export type ChainTransaction = {};
|
||||
|
||||
export type ProbeForRouteType = { route?: { hops: [{ public_key: string }] } };
|
||||
|
||||
export type GetChannelType = {
|
||||
policies: {
|
||||
public_key: string;
|
||||
base_fee_mtokens: string;
|
||||
fee_rate: number;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type GetChannelsType = { channels: ChannelType[] };
|
||||
|
||||
export type GetForwardsType = { forwards: ForwardType[]; next?: string };
|
||||
|
||||
export type GetInvoicesType = { invoices: InvoiceType[]; next?: string };
|
||||
|
||||
export type GetPaymentsType = { payments: PaymentType[]; next?: string };
|
||||
|
||||
export type GetChainBalanceType = { chain_balance: number };
|
||||
|
||||
export type GetPendingChainBalanceType = { pending_chain_balance: number };
|
||||
|
||||
export type GetChainTransactionsType = { transactions: ChainTransaction[] };
|
||||
|
||||
export type GetUtxosType = { utxos: UtxoType[] };
|
||||
|
||||
export type SendToChainAddressType = {
|
||||
id: string;
|
||||
confirmation_count: number;
|
||||
is_confirmed: boolean;
|
||||
is_outgoing: boolean;
|
||||
tokens: number | null;
|
||||
};
|
@ -3,6 +3,7 @@ import {
|
||||
useAccountDispatch,
|
||||
useAccountState,
|
||||
CompleteAccount,
|
||||
AccountProps,
|
||||
} from 'src/context/AccountContext';
|
||||
import { addIdAndTypeToAccount } from 'src/context/helpers/context';
|
||||
import { useGetServerAccountsQuery } from 'src/graphql/queries/__generated__/getServerAccounts.generated';
|
||||
@ -12,7 +13,7 @@ import { appendBasePath } from 'src/utils/basePath';
|
||||
import { getUrlParam } from 'src/utils/url';
|
||||
import { useGetAuthTokenQuery } from 'src/graphql/queries/__generated__/getAuthToken.generated';
|
||||
|
||||
export const ServerAccounts = () => {
|
||||
export const ServerAccounts: React.FC = () => {
|
||||
const { hasAccount } = useAccountState();
|
||||
const dispatch = useAccountDispatch();
|
||||
const { push, pathname, query } = useRouter();
|
||||
@ -46,7 +47,9 @@ export const ServerAccounts = () => {
|
||||
const session = sessionStorage.getItem('session') || null;
|
||||
const changeId = localStorage.getItem('active') || null;
|
||||
const savedAccounts = JSON.parse(localStorage.getItem('accounts') || '[]');
|
||||
const accountsToAdd = savedAccounts.map(a => addIdAndTypeToAccount(a));
|
||||
const accountsToAdd = savedAccounts.map((a: AccountProps) =>
|
||||
addIdAndTypeToAccount(a)
|
||||
);
|
||||
dispatch({
|
||||
type: 'initialize',
|
||||
accountsToAdd,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useAccountState, CLIENT_ACCOUNT } from 'src/context/AccountContext';
|
||||
|
||||
export const AdminSwitch = ({ children }) => {
|
||||
export const AdminSwitch: React.FC = ({ children }) => {
|
||||
const { account, session } = useAccountState();
|
||||
|
||||
if (account?.type === CLIENT_ACCOUNT) {
|
||||
@ -9,5 +10,5 @@ export const AdminSwitch = ({ children }) => {
|
||||
}
|
||||
}
|
||||
|
||||
return children;
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
@ -11,10 +11,10 @@ type PriceProps = {
|
||||
};
|
||||
|
||||
type AnimatedProps = {
|
||||
amount: number;
|
||||
amount?: number;
|
||||
};
|
||||
|
||||
export const AnimatedNumber = ({ amount = 0 }: AnimatedProps) => {
|
||||
export const AnimatedNumber: React.FC<AnimatedProps> = ({ amount = 0 }) => {
|
||||
const { value } = useSpring({
|
||||
from: { value: 0 },
|
||||
value: amount,
|
||||
|
@ -13,11 +13,16 @@ type AdminProps = {
|
||||
setChecked: (state: boolean) => void;
|
||||
};
|
||||
|
||||
export const AdminCheck = ({ host, admin, cert, setChecked }: AdminProps) => {
|
||||
export const AdminCheck: React.FC<AdminProps> = ({
|
||||
host,
|
||||
admin,
|
||||
cert,
|
||||
setChecked,
|
||||
}) => {
|
||||
const { data, loading } = useGetCanAdminQuery({
|
||||
fetchPolicy: 'network-only',
|
||||
skip: !admin,
|
||||
variables: { auth: getAuthObj(host, null, admin, cert) },
|
||||
variables: { auth: getAuthObj(host, undefined, admin, cert) },
|
||||
onError: () => {
|
||||
setChecked(false);
|
||||
},
|
||||
|
@ -53,7 +53,7 @@ export const ViewCheck = ({
|
||||
if (loading) {
|
||||
return <ScaleLoader height={20} color={themeColors.blue3} />;
|
||||
}
|
||||
if (data?.getNodeInfo.alias) {
|
||||
if (data?.getNodeInfo?.alias) {
|
||||
return <Check size={18} />;
|
||||
}
|
||||
return <X size={18} />;
|
||||
|
@ -105,11 +105,11 @@ export const Auth = ({ type, status, callback, setStatus }: AuthProps) => {
|
||||
dispatchAccount({
|
||||
type: 'addAccountAndSave',
|
||||
accountToAdd: {
|
||||
name,
|
||||
name: name || '',
|
||||
host,
|
||||
admin: encryptedAdmin,
|
||||
viewOnly: correctViewOnly,
|
||||
cert,
|
||||
admin: encryptedAdmin || '',
|
||||
viewOnly: correctViewOnly || '',
|
||||
cert: cert || '',
|
||||
},
|
||||
...(!correctViewOnly && { session: admin }),
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ import { useGetBitcoinFeesQuery } from 'src/graphql/queries/__generated__/getBit
|
||||
import { useBitcoinDispatch } from '../../context/BitcoinContext';
|
||||
import { useConfigState } from '../../context/ConfigContext';
|
||||
|
||||
export const BitcoinFees = () => {
|
||||
export const BitcoinFees: React.FC = () => {
|
||||
const { fetchFees } = useConfigState();
|
||||
const setInfo = useBitcoinDispatch();
|
||||
|
||||
@ -27,7 +27,10 @@ export const BitcoinFees = () => {
|
||||
useEffect(() => {
|
||||
if (!loading && data && data.getBitcoinFees && fetchFees) {
|
||||
const { fast, halfHour, hour } = data.getBitcoinFees;
|
||||
setInfo({ type: 'fetched', state: { fast, halfHour, hour } });
|
||||
setInfo({
|
||||
type: 'fetched',
|
||||
state: { fast: fast || 0, halfHour: halfHour || 0, hour: hour || 0 },
|
||||
});
|
||||
}
|
||||
}, [data, loading, setInfo, fetchFees]);
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { useGetBitcoinPriceQuery } from 'src/graphql/queries/__generated__/getBi
|
||||
import { usePriceDispatch } from '../../context/PriceContext';
|
||||
import { useConfigState } from '../../context/ConfigContext';
|
||||
|
||||
export const BitcoinPrice = () => {
|
||||
export const BitcoinPrice: React.FC = () => {
|
||||
const { fetchPrices } = useConfigState();
|
||||
const setPrices = usePriceDispatch();
|
||||
const { loading, data, stopPolling } = useGetBitcoinPriceQuery({
|
||||
|
@ -27,7 +27,16 @@ export const SecureButton: React.FC<SecureButtonProps> = ({
|
||||
|
||||
const { session, account } = useAccountState();
|
||||
|
||||
if (account.type === CLIENT_ACCOUNT && !account.admin && !session) {
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
account &&
|
||||
account.type === CLIENT_ACCOUNT &&
|
||||
!account.admin &&
|
||||
!session
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,10 @@ export const SecureWrapper: React.FC<SecureButtonProps> = ({
|
||||
|
||||
const { account, session } = useAccountState();
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (account.type === CLIENT_ACCOUNT && !account.admin && !session) {
|
||||
return null;
|
||||
}
|
||||
|
@ -4,11 +4,12 @@ import { useRouter } from 'next/router';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetMessagesQuery } from 'src/graphql/queries/__generated__/getMessages.generated';
|
||||
import { useStatusState } from 'src/context/StatusContext';
|
||||
import { MessagesType } from 'src/graphql/types';
|
||||
import { useChatState, useChatDispatch } from '../../context/ChatContext';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
import { useConfigState } from '../../context/ConfigContext';
|
||||
|
||||
export const ChatFetcher = () => {
|
||||
export const ChatFetcher: React.FC = () => {
|
||||
const newChatToastId = 'newChatToastId';
|
||||
|
||||
const { chatPollingSpeed } = useConfigState();
|
||||
@ -39,9 +40,7 @@ export const ChatFetcher = () => {
|
||||
for (let i = 0; i < messages.length; i += 1) {
|
||||
if (index < 0) {
|
||||
const element = messages[i];
|
||||
const { id } = element;
|
||||
|
||||
if (id === lastChat) {
|
||||
if (element?.id === lastChat) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
@ -61,8 +60,15 @@ export const ChatFetcher = () => {
|
||||
}
|
||||
|
||||
const newMessages = messages.slice(0, index);
|
||||
const last = newMessages[0]?.id;
|
||||
dispatch({ type: 'additional', chats: newMessages, lastChat: last });
|
||||
|
||||
if (newMessages?.length) {
|
||||
const last = newMessages[0]?.id || '';
|
||||
dispatch({
|
||||
type: 'additional',
|
||||
chats: (newMessages as MessagesType[]) || [],
|
||||
lastChat: last,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [data, loading, error, dispatch, lastChat, pathname]);
|
||||
|
||||
|
@ -2,10 +2,11 @@ import * as React from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetMessagesLazyQuery } from 'src/graphql/queries/__generated__/getMessages.generated';
|
||||
import { MessagesType } from 'src/graphql/types';
|
||||
import { useChatDispatch } from '../../context/ChatContext';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
|
||||
export const ChatInit = () => {
|
||||
export const ChatInit: React.FC = () => {
|
||||
const { auth, account } = useAccountState();
|
||||
const dispatch = useChatDispatch();
|
||||
|
||||
@ -45,17 +46,17 @@ export const ChatInit = () => {
|
||||
if (!initLoading && !initError && initData && initData.getMessages) {
|
||||
const { messages } = initData.getMessages;
|
||||
|
||||
if (messages.length <= 0) {
|
||||
if (!messages?.length) {
|
||||
dispatch({ type: 'initialized' });
|
||||
return;
|
||||
}
|
||||
|
||||
const lastChat = messages[0].id || '';
|
||||
const sender = messages[0].sender || '';
|
||||
const lastChat = messages[0]?.id || '';
|
||||
const sender = messages[0]?.sender || '';
|
||||
|
||||
dispatch({
|
||||
type: 'initialized',
|
||||
chats: messages,
|
||||
chats: messages as MessagesType[],
|
||||
lastChat,
|
||||
sender,
|
||||
});
|
||||
|
@ -78,7 +78,7 @@ export const Separation = styled.div<SeparationProps>`
|
||||
`;
|
||||
|
||||
interface SubCardProps {
|
||||
color?: string;
|
||||
subColor?: string | null;
|
||||
padding?: string;
|
||||
withMargin?: string;
|
||||
noCard?: boolean;
|
||||
|
@ -39,7 +39,8 @@ export const copyLink = (text: string) => (
|
||||
</CopyToClipboard>
|
||||
);
|
||||
|
||||
export const getTransactionLink = (transaction: string) => {
|
||||
export const getTransactionLink = (transaction: string | null | undefined) => {
|
||||
if (!transaction) return null;
|
||||
if (disableLinks) {
|
||||
return (
|
||||
<>
|
||||
@ -59,7 +60,8 @@ export const getTransactionLink = (transaction: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const getWithCopy = (text: string) => {
|
||||
export const getWithCopy = (text: string | null | undefined) => {
|
||||
if (!text) return null;
|
||||
return (
|
||||
<>
|
||||
{shorten(text)}
|
||||
@ -68,7 +70,10 @@ export const getWithCopy = (text: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const getNodeLink = (publicKey: string, alias?: string) => {
|
||||
export const getNodeLink = (
|
||||
publicKey: string | undefined | null,
|
||||
alias?: string | undefined | null
|
||||
) => {
|
||||
if (!publicKey || (alias && alias === 'Node not found')) {
|
||||
return 'Node not found';
|
||||
}
|
||||
@ -88,15 +93,23 @@ export const getNodeLink = (publicKey: string, alias?: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const getDateDif = (date: string) => {
|
||||
export const getDateDif = (date: string | null | undefined): string | null => {
|
||||
if (!date) return null;
|
||||
return formatDistanceToNowStrict(new Date(date));
|
||||
};
|
||||
|
||||
export const getFormatDate = (date: string) => {
|
||||
export const getFormatDate = (
|
||||
date: string | null | undefined
|
||||
): string | null => {
|
||||
if (!date) return null;
|
||||
return format(new Date(date), 'dd/MM/yyyy - HH:mm:ss');
|
||||
};
|
||||
|
||||
export const getMessageDate = (date: string, formatType?: string): string => {
|
||||
export const getMessageDate = (
|
||||
date: string | null | undefined,
|
||||
formatType?: string
|
||||
): string => {
|
||||
if (!date) return '';
|
||||
let distance = formatDistanceToNowStrict(new Date(date));
|
||||
|
||||
if (distance.indexOf('minute') >= 0 || distance.indexOf('second') >= 0) {
|
||||
@ -143,10 +156,10 @@ export const getStatusDot = (status: boolean, type: string) => {
|
||||
|
||||
export const renderLine = (
|
||||
title: string,
|
||||
content: number | string | JSX.Element,
|
||||
content: number | string | JSX.Element | undefined | null,
|
||||
key?: string | number,
|
||||
deleteCallback?: () => void
|
||||
) => {
|
||||
): JSX.Element | null => {
|
||||
if (!content) return null;
|
||||
return (
|
||||
<DetailLine key={key}>
|
||||
|
@ -37,9 +37,9 @@ const InputLine = styled(SingleLine)`
|
||||
|
||||
type InputWithDecoProps = {
|
||||
title: string;
|
||||
value?: string | number;
|
||||
value?: string | number | null;
|
||||
noInput?: boolean;
|
||||
amount?: number;
|
||||
amount?: number | null;
|
||||
override?: string;
|
||||
customAmount?: string;
|
||||
color?: string;
|
||||
@ -62,13 +62,14 @@ export const InputWithDeco: React.FC<InputWithDecoProps> = ({
|
||||
inputCallback,
|
||||
}) => {
|
||||
const showAmount = !!amount || customAmount;
|
||||
let correctValue = value;
|
||||
let correctValue = value ? value : '';
|
||||
|
||||
if (inputType === 'number') {
|
||||
correctValue = value > 0 ? value : undefined;
|
||||
if (inputType === 'number' && value) {
|
||||
correctValue = value && value > 0 ? value : '';
|
||||
}
|
||||
|
||||
const props = noInput ? {} : { value: correctValue };
|
||||
|
||||
return (
|
||||
<InputLine>
|
||||
<InputTitleRow>
|
||||
|
@ -83,14 +83,18 @@ export const Link: React.FC<LinkProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
const linkProps = {
|
||||
href: to,
|
||||
...(basePath !== '' ? { as: `${basePath}${to}` } : {}),
|
||||
};
|
||||
if (to) {
|
||||
const linkProps = {
|
||||
href: to,
|
||||
...(basePath !== '' ? { as: `${basePath}${to}` } : {}),
|
||||
};
|
||||
|
||||
return (
|
||||
<RouterLink {...linkProps}>
|
||||
<CorrectLink {...props}>{children}</CorrectLink>
|
||||
</RouterLink>
|
||||
);
|
||||
return (
|
||||
<RouterLink {...linkProps}>
|
||||
<CorrectLink {...props}>{children}</CorrectLink>
|
||||
</RouterLink>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
@ -30,7 +30,7 @@ export const NodeCard = ({ account, accountId }: NodeCardProps) => {
|
||||
triggerOnce: true,
|
||||
});
|
||||
|
||||
const auth = getAuthObj(host, viewOnly, null, cert);
|
||||
const auth = getAuthObj(host, viewOnly, undefined, cert);
|
||||
|
||||
const { data, loading, error } = useGetNodeInfoQuery({
|
||||
ssr: false,
|
||||
@ -64,7 +64,13 @@ export const NodeCard = ({ account, accountId }: NodeCardProps) => {
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (loading || !data || !data.getNodeInfo || !data.getChannelBalance) {
|
||||
if (
|
||||
loading ||
|
||||
!data?.getNodeInfo ||
|
||||
!data?.getChannelBalance ||
|
||||
!data?.getChainBalance ||
|
||||
!data?.getPendingChainBalance
|
||||
) {
|
||||
return <ScaleLoader height={20} color={themeColors.blue3} />;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useAccountDispatch } from 'src/context/AccountContext';
|
||||
import { GetNodeInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import { NodeInfoType, ChannelBalanceType } from 'src/graphql/types';
|
||||
import {
|
||||
SubTitle,
|
||||
SingleLine,
|
||||
@ -13,7 +14,7 @@ import { ColorButton } from '../buttons/colorButton/ColorButton';
|
||||
import { useStatusDispatch } from '../../context/StatusContext';
|
||||
|
||||
interface NodeInfoModalProps {
|
||||
account: GetNodeInfoQuery;
|
||||
account: GetNodeInfoQuery | null | undefined;
|
||||
accountId: string;
|
||||
}
|
||||
|
||||
@ -22,6 +23,10 @@ export const NodeInfoModal = ({ account, accountId }: NodeInfoModalProps) => {
|
||||
|
||||
const dispatchAccount = useAccountDispatch();
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
active_channels_count,
|
||||
closed_channels_count,
|
||||
@ -30,9 +35,12 @@ export const NodeInfoModal = ({ account, accountId }: NodeInfoModalProps) => {
|
||||
is_synced_to_chain,
|
||||
peers_count,
|
||||
version,
|
||||
} = account.getNodeInfo;
|
||||
} = account.getNodeInfo as NodeInfoType;
|
||||
|
||||
const { confirmedBalance, pendingBalance } = account.getChannelBalance;
|
||||
const {
|
||||
confirmedBalance,
|
||||
pendingBalance,
|
||||
} = account.getChannelBalance as ChannelBalanceType;
|
||||
|
||||
const chainBalance = account.getChainBalance;
|
||||
const pendingChainBalance = account.getPendingChainBalance;
|
||||
|
@ -14,14 +14,14 @@ export const Price = ({
|
||||
breakNumber = false,
|
||||
override,
|
||||
}: {
|
||||
amount: number | string;
|
||||
amount: number | string | null | undefined;
|
||||
breakNumber?: boolean;
|
||||
override?: string;
|
||||
}): JSX.Element => {
|
||||
const { currency, displayValues } = useConfigState();
|
||||
const { fiat, prices, dontShow } = usePriceState();
|
||||
|
||||
if (!displayValues) {
|
||||
if (!displayValues || !amount) {
|
||||
return <>-</>;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ export const Price = ({
|
||||
};
|
||||
|
||||
interface GetPriceProps {
|
||||
amount: number | string;
|
||||
amount: number | string | null | undefined;
|
||||
breakNumber?: boolean;
|
||||
override?: string;
|
||||
noUnit?: boolean;
|
||||
@ -68,6 +68,7 @@ export const getPrice = (
|
||||
override,
|
||||
noUnit,
|
||||
}: GetPriceProps): string => {
|
||||
if (!amount) return '-';
|
||||
const { prices, dontShow, fiat } = priceContext;
|
||||
|
||||
if (!displayValues) {
|
||||
|
@ -3,10 +3,11 @@ import { useRouter } from 'next/router';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useAccountState } from 'src/context/AccountContext';
|
||||
import { useGetNodeInfoQuery } from 'src/graphql/queries/__generated__/getNodeInfo.generated';
|
||||
import { useStatusDispatch } from '../../context/StatusContext';
|
||||
import { NodeInfoType, ChannelBalanceType } from 'src/graphql/types';
|
||||
import { useStatusDispatch, StatusState } from '../../context/StatusContext';
|
||||
import { appendBasePath } from '../../utils/basePath';
|
||||
|
||||
export const StatusCheck = () => {
|
||||
export const StatusCheck: React.FC = () => {
|
||||
const dispatch = useStatusDispatch();
|
||||
const { push } = useRouter();
|
||||
|
||||
@ -21,7 +22,7 @@ export const StatusCheck = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
toast.error(`Unable to connect to ${account.name}`);
|
||||
account && toast.error(`Unable to connect to ${account.name}`);
|
||||
stopPolling();
|
||||
dispatch({ type: 'disconnected' });
|
||||
push(appendBasePath('/'));
|
||||
@ -33,6 +34,7 @@ export const StatusCheck = () => {
|
||||
getChannelBalance,
|
||||
getNodeInfo,
|
||||
} = data;
|
||||
|
||||
const {
|
||||
alias,
|
||||
color,
|
||||
@ -42,14 +44,17 @@ export const StatusCheck = () => {
|
||||
pending_channels_count,
|
||||
closed_channels_count,
|
||||
peers_count,
|
||||
} = getNodeInfo;
|
||||
const { confirmedBalance, pendingBalance } = getChannelBalance;
|
||||
} = getNodeInfo as NodeInfoType;
|
||||
const {
|
||||
confirmedBalance,
|
||||
pendingBalance,
|
||||
} = getChannelBalance as ChannelBalanceType;
|
||||
|
||||
const versionNumber = version.split(' ');
|
||||
const onlyVersion = versionNumber[0].split('-');
|
||||
const numbers = onlyVersion[0].split('.');
|
||||
|
||||
const state = {
|
||||
const state: StatusState = {
|
||||
alias,
|
||||
color,
|
||||
syncedToChain: is_synced_to_chain,
|
||||
@ -57,8 +62,8 @@ export const StatusCheck = () => {
|
||||
mayorVersion: Number(numbers[0]),
|
||||
minorVersion: Number(numbers[1]),
|
||||
revision: Number(numbers[2]),
|
||||
chainBalance: getChainBalance,
|
||||
chainPending: getPendingChainBalance,
|
||||
chainBalance: getChainBalance || 0,
|
||||
chainPending: getPendingChainBalance || 0,
|
||||
channelBalance: confirmedBalance,
|
||||
channelPending: pendingBalance,
|
||||
activeChannelCount: active_channels_count,
|
||||
|
@ -16,14 +16,6 @@ export const SERVER_ACCOUNT: SERVER_ACCOUNT_TYPE = 'server';
|
||||
|
||||
type HasAccountType = 'fetched' | 'false' | 'error';
|
||||
|
||||
export type AccountProps = {
|
||||
name: string;
|
||||
host: string;
|
||||
admin: string;
|
||||
viewOnly: string;
|
||||
cert: string;
|
||||
};
|
||||
|
||||
export type AuthType =
|
||||
| {
|
||||
type: ACCOUNT_TYPE;
|
||||
@ -36,24 +28,34 @@ export type AuthType =
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type AccountProps = {
|
||||
name: string;
|
||||
host: string;
|
||||
admin: string;
|
||||
viewOnly: string;
|
||||
cert: string;
|
||||
};
|
||||
|
||||
export type AccountType = {
|
||||
type: ACCOUNT_TYPE;
|
||||
id: string;
|
||||
} & AccountProps;
|
||||
|
||||
export type CompleteAccount =
|
||||
| AccountType
|
||||
| {
|
||||
type: SERVER_ACCOUNT_TYPE;
|
||||
id: string;
|
||||
name: string;
|
||||
loggedIn?: boolean;
|
||||
};
|
||||
export type ServerAccountType = {
|
||||
type: SERVER_ACCOUNT_TYPE;
|
||||
id: string;
|
||||
name: string;
|
||||
loggedIn?: boolean;
|
||||
};
|
||||
|
||||
export type CompleteAccount = AccountType | ServerAccountType;
|
||||
|
||||
export const defaultAuth = { type: SERVER_ACCOUNT, id: '' };
|
||||
|
||||
type State = {
|
||||
initialized: boolean;
|
||||
finishedFetch: boolean;
|
||||
auth: AuthType | null;
|
||||
auth: AuthType;
|
||||
activeAccount: string | null;
|
||||
session: string | null;
|
||||
account: CompleteAccount | null;
|
||||
@ -64,9 +66,9 @@ type State = {
|
||||
type ActionType =
|
||||
| {
|
||||
type: 'initialize';
|
||||
changeId: string;
|
||||
changeId: string | null;
|
||||
accountsToAdd: CompleteAccount[];
|
||||
session: string;
|
||||
session: string | null;
|
||||
}
|
||||
| {
|
||||
type: 'changeAccount' | 'deleteAccount';
|
||||
@ -106,7 +108,7 @@ const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
|
||||
const initialState: State = {
|
||||
initialized: false,
|
||||
finishedFetch: false,
|
||||
auth: null,
|
||||
auth: defaultAuth,
|
||||
session: null,
|
||||
activeAccount: null,
|
||||
account: null,
|
||||
@ -171,11 +173,11 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
...state,
|
||||
account: null,
|
||||
activeAccount: null,
|
||||
auth: null,
|
||||
auth: defaultAuth,
|
||||
session: null,
|
||||
};
|
||||
case 'deleteAccount': {
|
||||
if (!state.accounts || state?.accounts?.length <= 0) {
|
||||
if (!state.accounts || state?.accounts?.length <= 0 || !state.account) {
|
||||
return state;
|
||||
}
|
||||
const { accounts, id } = deleteAccountById(
|
||||
|
@ -45,7 +45,7 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
}
|
||||
};
|
||||
|
||||
const BitcoinInfoProvider = ({ children }) => {
|
||||
const BitcoinInfoProvider: React.FC = ({ children }) => {
|
||||
const [state, dispatch] = useReducer(stateReducer, initialState);
|
||||
|
||||
return (
|
||||
|
@ -1,30 +1,14 @@
|
||||
import React, { createContext, useContext, useReducer } from 'react';
|
||||
import { MessagesType } from 'src/graphql/types';
|
||||
|
||||
type ChatProps = {
|
||||
date?: string;
|
||||
contentType?: string;
|
||||
alias?: string;
|
||||
message?: string;
|
||||
id?: string;
|
||||
sender?: string;
|
||||
tokens?: number;
|
||||
};
|
||||
|
||||
type SentChatProps = {
|
||||
date?: string;
|
||||
contentType?: string;
|
||||
alias?: string;
|
||||
message?: string;
|
||||
id?: string;
|
||||
sender?: string;
|
||||
export interface SentChatProps extends MessagesType {
|
||||
isSent?: boolean;
|
||||
feePaid?: number;
|
||||
tokens?: number;
|
||||
};
|
||||
}
|
||||
|
||||
type State = {
|
||||
initialized: boolean;
|
||||
chats: ChatProps[];
|
||||
chats: MessagesType[];
|
||||
sentChats: SentChatProps[];
|
||||
lastChat: string;
|
||||
sender: string;
|
||||
@ -33,14 +17,14 @@ type State = {
|
||||
type ActionType =
|
||||
| {
|
||||
type: 'initialized';
|
||||
chats?: ChatProps[];
|
||||
chats?: MessagesType[];
|
||||
lastChat?: string;
|
||||
sender?: string;
|
||||
sentChats?: SentChatProps[];
|
||||
}
|
||||
| {
|
||||
type: 'additional';
|
||||
chats: ChatProps[];
|
||||
chats: MessagesType[];
|
||||
lastChat: string;
|
||||
}
|
||||
| {
|
||||
@ -108,7 +92,7 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
}
|
||||
};
|
||||
|
||||
const ChatProvider = ({ children }) => {
|
||||
const ChatProvider: React.FC = ({ children }) => {
|
||||
const [state, dispatch] = useReducer(stateReducer, initialState);
|
||||
|
||||
return (
|
||||
|
@ -115,11 +115,17 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
return newState;
|
||||
}
|
||||
case 'themeChange': {
|
||||
Cookies.set('theme', action.theme, { expires: 365, sameSite: 'strict' });
|
||||
return {
|
||||
...state,
|
||||
theme: action.theme,
|
||||
};
|
||||
if (settings.theme) {
|
||||
Cookies.set('theme', settings.theme, {
|
||||
expires: 365,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
return {
|
||||
...state,
|
||||
theme: settings.theme,
|
||||
};
|
||||
}
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
|
@ -57,7 +57,7 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
}
|
||||
};
|
||||
|
||||
const PriceProvider = ({ children }) => {
|
||||
const PriceProvider: React.FC = ({ children }) => {
|
||||
const [state, dispatch] = useReducer(stateReducer, initialState);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -24,7 +24,7 @@ type Dispatch = (action: ActionType) => void;
|
||||
export const StateContext = createContext<State | undefined>(undefined);
|
||||
export const DispatchContext = createContext<Dispatch | undefined>(undefined);
|
||||
|
||||
const initialState = {
|
||||
const initialState: State = {
|
||||
inChannel: null,
|
||||
outChannel: null,
|
||||
};
|
||||
@ -42,7 +42,7 @@ const stateReducer = (state: State, action: ActionType): State => {
|
||||
}
|
||||
};
|
||||
|
||||
const RebalanceProvider = ({ children }) => {
|
||||
const RebalanceProvider: React.FC = ({ children }) => {
|
||||
const [state, dispatch] = useReducer(stateReducer, initialState);
|
||||
|
||||
return (
|
||||
|
@ -4,7 +4,7 @@ type StateStatus = {
|
||||
connected: boolean;
|
||||
};
|
||||
|
||||
type State = {
|
||||
export type StatusState = {
|
||||
alias: string;
|
||||
color: string;
|
||||
syncedToChain: boolean;
|
||||
@ -22,11 +22,11 @@ type State = {
|
||||
peersCount: number;
|
||||
};
|
||||
|
||||
type CompleteState = State & StateStatus;
|
||||
type CompleteState = StatusState & StateStatus;
|
||||
|
||||
type ActionType = {
|
||||
type: 'connected' | 'disconnected';
|
||||
state?: State;
|
||||
state?: StatusState;
|
||||
};
|
||||
|
||||
type Dispatch = (action: ActionType) => void;
|
||||
@ -53,10 +53,13 @@ const initialState = {
|
||||
peersCount: 0,
|
||||
};
|
||||
|
||||
const stateReducer = (state: State, action: ActionType): CompleteState => {
|
||||
const stateReducer = (
|
||||
state: StatusState,
|
||||
action: ActionType
|
||||
): CompleteState => {
|
||||
switch (action.type) {
|
||||
case 'connected':
|
||||
return { ...action.state, connected: true } || initialState;
|
||||
return { ...state, ...action.state, connected: true } || initialState;
|
||||
case 'disconnected':
|
||||
return initialState;
|
||||
default:
|
||||
@ -64,7 +67,7 @@ const stateReducer = (state: State, action: ActionType): CompleteState => {
|
||||
}
|
||||
};
|
||||
|
||||
const StatusProvider = ({ children }) => {
|
||||
const StatusProvider: React.FC = ({ children }) => {
|
||||
const [state, dispatch] = useReducer(stateReducer, initialState);
|
||||
|
||||
return (
|
||||
|
@ -4,10 +4,16 @@ import {
|
||||
AccountProps,
|
||||
CLIENT_ACCOUNT,
|
||||
AuthType,
|
||||
defaultAuth,
|
||||
} from '../AccountContext';
|
||||
|
||||
export const getAccountById = (id: string, accounts: CompleteAccount[]) => {
|
||||
const correctAccount: CompleteAccount | null = accounts.find(
|
||||
export const getAccountById = (
|
||||
id: string | null,
|
||||
accounts: CompleteAccount[]
|
||||
) => {
|
||||
if (!id) return { account: null, id: null };
|
||||
|
||||
const correctAccount: CompleteAccount | null | undefined = accounts.find(
|
||||
a => a.id === id
|
||||
);
|
||||
|
||||
@ -48,10 +54,10 @@ export const addIdAndTypeToAccount = (
|
||||
};
|
||||
|
||||
export const getAuthFromAccount = (
|
||||
account: CompleteAccount,
|
||||
session?: string
|
||||
account: CompleteAccount | undefined | null,
|
||||
session?: string | null
|
||||
): AuthType => {
|
||||
if (!account) return null;
|
||||
if (!account) return defaultAuth;
|
||||
if (account.type !== CLIENT_ACCOUNT) {
|
||||
return {
|
||||
type: account.type,
|
||||
@ -60,10 +66,10 @@ export const getAuthFromAccount = (
|
||||
}
|
||||
const { host, viewOnly, cert } = account;
|
||||
if (!host) {
|
||||
return null;
|
||||
return defaultAuth;
|
||||
}
|
||||
if (!viewOnly && !session) {
|
||||
return null;
|
||||
return defaultAuth;
|
||||
}
|
||||
return {
|
||||
type: account.type,
|
||||
|
@ -22,23 +22,19 @@ export type DecodeRequestQuery = { __typename?: 'Query' } & {
|
||||
| 'tokens'
|
||||
> & {
|
||||
destination_node: { __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<Types.NodeType, 'alias'>
|
||||
>;
|
||||
node: { __typename?: 'nodeType' } & Pick<Types.NodeType, 'alias'>;
|
||||
};
|
||||
routes?: Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'RouteType' } & Pick<
|
||||
Types.RouteType,
|
||||
| 'base_fee_mtokens'
|
||||
| 'channel'
|
||||
| 'cltv_delta'
|
||||
| 'fee_rate'
|
||||
| 'public_key'
|
||||
>
|
||||
routes: Array<
|
||||
Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'RouteType' } & Pick<
|
||||
Types.RouteType,
|
||||
| 'base_fee_mtokens'
|
||||
| 'channel'
|
||||
| 'cltv_delta'
|
||||
| 'fee_rate'
|
||||
| 'public_key'
|
||||
>
|
||||
>
|
||||
>
|
||||
@ -71,11 +67,9 @@ export type DecodeRequestQuery = { __typename?: 'Query' } & {
|
||||
| 'timeout'
|
||||
> & {
|
||||
node: { __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>;
|
||||
};
|
||||
}
|
||||
|
@ -16,11 +16,9 @@ export type ChannelFeesQuery = { __typename?: 'Query' } & {
|
||||
'id' | 'partner_public_key'
|
||||
> & {
|
||||
partner_node_info: { __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>;
|
||||
};
|
||||
channelInfo?: Types.Maybe<
|
||||
|
@ -9,65 +9,55 @@ export type GetChannelsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
export type GetChannelsQuery = { __typename?: 'Query' } & {
|
||||
getChannels?: Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'channelType' } & Pick<
|
||||
Types.ChannelType,
|
||||
| 'capacity'
|
||||
| 'commit_transaction_fee'
|
||||
| 'commit_transaction_weight'
|
||||
| 'id'
|
||||
| 'is_active'
|
||||
| 'is_closing'
|
||||
| 'is_opening'
|
||||
| 'is_partner_initiated'
|
||||
| 'is_private'
|
||||
| 'is_static_remote_key'
|
||||
| 'local_balance'
|
||||
| 'local_reserve'
|
||||
| 'partner_public_key'
|
||||
| 'received'
|
||||
| 'remote_balance'
|
||||
| 'remote_reserve'
|
||||
| 'sent'
|
||||
| 'time_offline'
|
||||
| 'time_online'
|
||||
| 'transaction_id'
|
||||
| 'transaction_vout'
|
||||
| 'unsettled_balance'
|
||||
| 'channel_age'
|
||||
> & {
|
||||
partner_node_info?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
| 'alias'
|
||||
| 'capacity'
|
||||
| 'channel_count'
|
||||
| 'color'
|
||||
| 'updated_at'
|
||||
>
|
||||
>;
|
||||
}
|
||||
getChannels: Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'channelType' } & Pick<
|
||||
Types.ChannelType,
|
||||
| 'capacity'
|
||||
| 'commit_transaction_fee'
|
||||
| 'commit_transaction_weight'
|
||||
| 'id'
|
||||
| 'is_active'
|
||||
| 'is_closing'
|
||||
| 'is_opening'
|
||||
| 'is_partner_initiated'
|
||||
| 'is_private'
|
||||
| 'is_static_remote_key'
|
||||
| 'local_balance'
|
||||
| 'local_reserve'
|
||||
| 'partner_public_key'
|
||||
| 'received'
|
||||
| 'remote_balance'
|
||||
| 'remote_reserve'
|
||||
| 'sent'
|
||||
| 'time_offline'
|
||||
| 'time_online'
|
||||
| 'transaction_id'
|
||||
| 'transaction_vout'
|
||||
| 'unsettled_balance'
|
||||
| 'channel_age'
|
||||
> & {
|
||||
partner_node_info: { __typename?: 'Node' } & {
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>;
|
||||
partner_fee_info?: Types.Maybe<
|
||||
{ __typename?: 'Channel' } & {
|
||||
channel?: Types.Maybe<
|
||||
{ __typename?: 'singleChannelType' } & {
|
||||
partner_node_policies?: Types.Maybe<
|
||||
{ __typename?: 'nodePolicyType' } & Pick<
|
||||
Types.NodePolicyType,
|
||||
'base_fee_mtokens' | 'fee_rate' | 'cltv_delta'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>
|
||||
};
|
||||
partner_fee_info?: Types.Maybe<
|
||||
{ __typename?: 'Channel' } & {
|
||||
channel?: Types.Maybe<
|
||||
{ __typename?: 'singleChannelType' } & {
|
||||
partner_node_policies?: Types.Maybe<
|
||||
{ __typename?: 'nodePolicyType' } & Pick<
|
||||
Types.NodePolicyType,
|
||||
'base_fee_mtokens' | 'fee_rate' | 'cltv_delta'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
@ -28,20 +28,12 @@ export type GetClosedChannelsQuery = { __typename?: 'Query' } & {
|
||||
| 'transaction_id'
|
||||
| 'transaction_vout'
|
||||
> & {
|
||||
partner_node_info?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
| 'alias'
|
||||
| 'capacity'
|
||||
| 'channel_count'
|
||||
| 'color'
|
||||
| 'updated_at'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>;
|
||||
partner_node_info: { __typename?: 'Node' } & {
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>;
|
||||
};
|
||||
}
|
||||
>
|
||||
>
|
||||
|
@ -46,11 +46,9 @@ export type GetFeeHealthQuery = { __typename?: 'Query' } & {
|
||||
>;
|
||||
partner?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
|
@ -32,11 +32,9 @@ export type GetForwardsQuery = { __typename?: 'Query' } & {
|
||||
{ __typename?: 'nodePolicyType' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
@ -54,11 +52,9 @@ export type GetForwardsQuery = { __typename?: 'Query' } & {
|
||||
{ __typename?: 'nodePolicyType' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'color'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
|
@ -15,20 +15,18 @@ export type GetMessagesQuery = { __typename?: 'Query' } & {
|
||||
Types.GetMessagesType,
|
||||
'token'
|
||||
> & {
|
||||
messages?: Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'messagesType' } & Pick<
|
||||
Types.MessagesType,
|
||||
| 'date'
|
||||
| 'contentType'
|
||||
| 'alias'
|
||||
| 'message'
|
||||
| 'id'
|
||||
| 'sender'
|
||||
| 'verified'
|
||||
| 'tokens'
|
||||
>
|
||||
messages: Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'messagesType' } & Pick<
|
||||
Types.MessagesType,
|
||||
| 'date'
|
||||
| 'contentType'
|
||||
| 'alias'
|
||||
| 'message'
|
||||
| 'id'
|
||||
| 'sender'
|
||||
| 'verified'
|
||||
| 'tokens'
|
||||
>
|
||||
>
|
||||
>;
|
||||
|
@ -11,11 +11,9 @@ export type GetNodeQueryVariables = Types.Exact<{
|
||||
|
||||
export type GetNodeQuery = { __typename?: 'Query' } & {
|
||||
getNode: { __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
@ -23,20 +23,12 @@ export type GetPeersQuery = { __typename?: 'Query' } & {
|
||||
| 'tokens_received'
|
||||
| 'tokens_sent'
|
||||
> & {
|
||||
partner_node_info?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
| 'alias'
|
||||
| 'capacity'
|
||||
| 'channel_count'
|
||||
| 'color'
|
||||
| 'updated_at'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>;
|
||||
partner_node_info: { __typename?: 'Node' } & {
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>;
|
||||
};
|
||||
}
|
||||
>
|
||||
>
|
||||
|
@ -28,20 +28,12 @@ export type GetPendingChannelsQuery = { __typename?: 'Query' } & {
|
||||
| 'transaction_id'
|
||||
| 'transaction_vout'
|
||||
> & {
|
||||
partner_node_info?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
| 'alias'
|
||||
| 'capacity'
|
||||
| 'channel_count'
|
||||
| 'color'
|
||||
| 'updated_at'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>;
|
||||
partner_node_info: { __typename?: 'Node' } & {
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'capacity' | 'channel_count' | 'color' | 'updated_at'
|
||||
>;
|
||||
};
|
||||
}
|
||||
>
|
||||
>
|
||||
|
@ -57,27 +57,19 @@ export type GetResumeQuery = { __typename?: 'Query' } & {
|
||||
> & {
|
||||
destination_node?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
hops?: Types.Maybe<
|
||||
Array<
|
||||
Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'public_key'
|
||||
>
|
||||
>;
|
||||
}
|
||||
>
|
||||
>
|
||||
hops: Array<
|
||||
{ __typename?: 'Node' } & {
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias' | 'public_key'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
})
|
||||
>
|
||||
|
@ -27,11 +27,9 @@ export type GetTimeHealthQuery = { __typename?: 'Query' } & {
|
||||
> & {
|
||||
partner?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
|
@ -19,11 +19,9 @@ export type GetVolumeHealthQuery = { __typename?: 'Query' } & {
|
||||
> & {
|
||||
partner?: Types.Maybe<
|
||||
{ __typename?: 'Node' } & {
|
||||
node?: Types.Maybe<
|
||||
{ __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>
|
||||
node: { __typename?: 'nodeType' } & Pick<
|
||||
Types.NodeType,
|
||||
'alias'
|
||||
>;
|
||||
}
|
||||
>;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loadingβ¦
Reference in New Issue
Block a user