mirror of
https://github.com/apotdevin/thunderhub.git
synced 2025-02-20 13:34:30 +01:00
chore: 🔧 enable tor proxy config (#197)
This commit is contained in:
parent
f1c9e4cf41
commit
5bcfed1b24
14 changed files with 208 additions and 75 deletions
1
.env
1
.env
|
@ -10,6 +10,7 @@
|
|||
# Server Configs
|
||||
# -----------
|
||||
# LOG_LEVEL='info'
|
||||
# TOR_PROXY_SERVER=socks://127.0.0.1:9050
|
||||
|
||||
# -----------
|
||||
# Interface Configs
|
||||
|
|
11
README.md
11
README.md
|
@ -114,6 +114,7 @@ You can define some environment variables that ThunderHub can start with. To do
|
|||
# Server Configs
|
||||
# -----------
|
||||
LOG_LEVEL = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly' # Default: 'info'
|
||||
TOR_PROXY_SERVER='socks://127.0.0.1:9050' # Default: ''
|
||||
|
||||
# -----------
|
||||
# Interface Configs
|
||||
|
@ -131,6 +132,16 @@ DISABLE_LNMARKETS = true | false # Default: false
|
|||
NO_VERSION_CHECK = true | false # Default: false
|
||||
```
|
||||
|
||||
### TOR Requests
|
||||
|
||||
ThunderHub connects to different external services for example to fetch BOS scores, BTC/fiat prices and BTC blockchain fees. Normally they are done through clearnet but you can configure a TOR proxy server so that they are all proxied through TOR.
|
||||
|
||||
You need to add the following parameter into your `.env` file with your TOR endpoint:
|
||||
|
||||
```bash
|
||||
TOR_PROXY_SERVER='socks://your.tor.endpoint' # i.e. 'socks://127.0.0.1:9050'
|
||||
```
|
||||
|
||||
### SSO Account
|
||||
|
||||
You can define an account to work with SSO cookie authentication by adding the following parameters in the `.env` file:
|
||||
|
|
|
@ -35,6 +35,7 @@ module.exports = withBundleAnalyzer({
|
|||
serverRuntimeConfig: {
|
||||
nodeEnv: process.env.NODE_ENV || 'development',
|
||||
logLevel: process.env.LOG_LEVEL || 'info',
|
||||
torProxy: process.env.TOR_PROXY_SERVER || '',
|
||||
...ssoEnv,
|
||||
...accountConfig,
|
||||
...sslEnv,
|
||||
|
|
43
package-lock.json
generated
43
package-lock.json
generated
|
@ -16439,7 +16439,8 @@
|
|||
"extract-files": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
|
||||
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
|
||||
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
|
@ -17552,6 +17553,7 @@
|
|||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz",
|
||||
"integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-fetch": "^3.0.6",
|
||||
"extract-files": "^9.0.0",
|
||||
|
@ -18303,6 +18305,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ip": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
|
||||
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
|
||||
},
|
||||
"ip-regex": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
|
||||
|
@ -26674,6 +26681,11 @@
|
|||
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
|
||||
"dev": true
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
|
||||
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
|
@ -26776,6 +26788,35 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"socks": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.5.1.tgz",
|
||||
"integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==",
|
||||
"requires": {
|
||||
"ip": "^1.1.5",
|
||||
"smart-buffer": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"socks-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==",
|
||||
"requires": {
|
||||
"agent-base": "6",
|
||||
"debug": "4",
|
||||
"socks": "^2.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-list-map": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
"graphql": "^15.4.0",
|
||||
"graphql-iso-date": "^3.6.1",
|
||||
"graphql-rate-limit": "^2.0.1",
|
||||
"graphql-request": "^3.4.0",
|
||||
"intersection-observer": "^0.12.0",
|
||||
"js-cookie": "^2.2.1",
|
||||
"js-yaml": "^3.14.1",
|
||||
|
@ -70,6 +69,7 @@
|
|||
"lodash.merge": "^4.6.2",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"next": "^10.0.3",
|
||||
"node-fetch": "^2.6.1",
|
||||
"numeral": "^2.0.6",
|
||||
"qrcode.react": "^1.0.0",
|
||||
"react": "^17.0.1",
|
||||
|
@ -87,6 +87,7 @@
|
|||
"react-toastify": "^6.2.0",
|
||||
"react-tooltip": "^4.2.11",
|
||||
"secp256k1": "^4.0.2",
|
||||
"socks-proxy-agent": "^5.0.0",
|
||||
"styled-components": "^5.2.1",
|
||||
"styled-react-modal": "^2.0.1",
|
||||
"styled-theming": "^2.2.0",
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { logger } from 'server/helpers/logger';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
export const BoltzApi = {
|
||||
getPairs: async () => {
|
||||
try {
|
||||
const response = await fetch(`${appUrls.boltz}/getpairs`);
|
||||
const response = await fetchWithProxy(`${appUrls.boltz}/getpairs`);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
logger.error('Error getting pairs from Boltz: %o', error);
|
||||
|
@ -13,7 +14,9 @@ export const BoltzApi = {
|
|||
},
|
||||
getFeeEstimations: async () => {
|
||||
try {
|
||||
const response = await fetch(`${appUrls.boltz}/getfeeestimation`);
|
||||
const response = await fetchWithProxy(
|
||||
`${appUrls.boltz}/getfeeestimation`
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
logger.error('Error getting fee estimations from Boltz: %o', error);
|
||||
|
@ -23,7 +26,7 @@ export const BoltzApi = {
|
|||
getSwapStatus: async (id: string) => {
|
||||
try {
|
||||
const body = { id };
|
||||
const response = await fetch(`${appUrls.boltz}/swapstatus`, {
|
||||
const response = await fetchWithProxy(`${appUrls.boltz}/swapstatus`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
@ -48,7 +51,7 @@ export const BoltzApi = {
|
|||
preimageHash,
|
||||
claimPublicKey,
|
||||
};
|
||||
const response = await fetch(`${appUrls.boltz}/createswap`, {
|
||||
const response = await fetchWithProxy(`${appUrls.boltz}/createswap`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
@ -65,11 +68,14 @@ export const BoltzApi = {
|
|||
currency: 'BTC',
|
||||
transactionHex,
|
||||
};
|
||||
const response = await fetch(`${appUrls.boltz}/broadcasttransaction`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
const response = await fetchWithProxy(
|
||||
`${appUrls.boltz}/broadcasttransaction`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
logger.error('Error broadcasting transaction from Boltz: %o', error);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { logger } from 'server/helpers/logger';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
export const LnMarketsApi = {
|
||||
getUser: async (token: string) => {
|
||||
try {
|
||||
const response = await fetch(`${appUrls.lnMarkets}/user`, {
|
||||
const response = await fetchWithProxy(`${appUrls.lnMarkets}/user`, {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
|
@ -21,15 +22,18 @@ export const LnMarketsApi = {
|
|||
},
|
||||
getDepositInvoice: async (token: string, amount: number) => {
|
||||
try {
|
||||
const response = await fetch(`${appUrls.lnMarkets}/user/deposit`, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ amount, unit: 'sat' }),
|
||||
});
|
||||
const response = await fetchWithProxy(
|
||||
`${appUrls.lnMarkets}/user/deposit`,
|
||||
{
|
||||
method: 'post',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ amount, unit: 'sat' }),
|
||||
}
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
|
@ -41,15 +45,18 @@ export const LnMarketsApi = {
|
|||
},
|
||||
withdraw: async (token: string, amount: number, invoice: string) => {
|
||||
try {
|
||||
const response = await fetch(`${appUrls.lnMarkets}/user/withdraw`, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ amount, unit: 'sat', invoice }),
|
||||
});
|
||||
const response = await fetchWithProxy(
|
||||
`${appUrls.lnMarkets}/user/withdraw`,
|
||||
{
|
||||
method: 'post',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ amount, unit: 'sat', invoice }),
|
||||
}
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
logger.error(`Error withdrawing from LnMarkets. Error: %o`, error);
|
||||
|
|
|
@ -11,6 +11,7 @@ import * as bip32 from 'bip32';
|
|||
import * as secp256k1 from 'secp256k1';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { decodeLnUrl } from 'src/utils/url';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
import { to } from './async';
|
||||
import { logger } from './logger';
|
||||
|
||||
|
@ -108,7 +109,7 @@ export const getLnMarketsAuth = async (
|
|||
|
||||
// Get a new lnUrl from LnMarkets
|
||||
try {
|
||||
const response = await fetch(`${appUrls.lnMarkets}/lnurl/a/c`);
|
||||
const response = await fetchWithProxy(`${appUrls.lnMarkets}/lnurl/a/c`);
|
||||
const json = await response.json();
|
||||
|
||||
logger.debug('Get lnUrl from LnMarkets response: %o', json);
|
||||
|
@ -128,7 +129,7 @@ export const getLnMarketsAuth = async (
|
|||
|
||||
// Try to authenticate with lnMarkets
|
||||
try {
|
||||
const response = await fetch(`${finalUrl}&jwt=true&expiry=3600`);
|
||||
const response = await fetchWithProxy(`${finalUrl}&jwt=true&expiry=3600`);
|
||||
const json = await response.json();
|
||||
|
||||
logger.debug('LnUrlAuth response: %o', json);
|
||||
|
|
|
@ -19,7 +19,10 @@ describe('Bitcoin Resolvers', () => {
|
|||
|
||||
expect(res.errors).toBe(undefined);
|
||||
|
||||
expect(fetchMock).toBeCalledWith('https://blockchain.info/ticker');
|
||||
expect(fetchMock).toBeCalledWith(
|
||||
'https://blockchain.info/ticker',
|
||||
undefined
|
||||
);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
test('failure', async () => {
|
||||
|
@ -54,7 +57,8 @@ describe('Bitcoin Resolvers', () => {
|
|||
expect(res.errors).toBe(undefined);
|
||||
|
||||
expect(fetchMock).toBeCalledWith(
|
||||
'https://mempool.space/api/v1/fees/recommended'
|
||||
'https://mempool.space/api/v1/fees/recommended',
|
||||
undefined
|
||||
);
|
||||
expect(res).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@ import { ContextType } from 'server/types/apiTypes';
|
|||
import { logger } from 'server/helpers/logger';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
export const bitcoinResolvers = {
|
||||
Query: {
|
||||
|
@ -13,7 +14,7 @@ export const bitcoinResolvers = {
|
|||
await requestLimiter(context.ip, 'bitcoinPrice');
|
||||
|
||||
try {
|
||||
const response = await fetch(appUrls.ticker);
|
||||
const response = await fetchWithProxy(appUrls.ticker);
|
||||
const json = await response.json();
|
||||
|
||||
return JSON.stringify(json);
|
||||
|
@ -30,7 +31,7 @@ export const bitcoinResolvers = {
|
|||
await requestLimiter(context.ip, 'bitcoinFee');
|
||||
|
||||
try {
|
||||
const response = await fetch(appUrls.fees);
|
||||
const response = await fetchWithProxy(appUrls.fees);
|
||||
const json = await response.json();
|
||||
|
||||
if (json) {
|
||||
|
|
|
@ -3,6 +3,7 @@ import { ContextType } from 'server/types/apiTypes';
|
|||
import { toWithError } from 'server/helpers/async';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
export const githubResolvers = {
|
||||
Query: {
|
||||
|
@ -13,7 +14,9 @@ export const githubResolvers = {
|
|||
) => {
|
||||
await requestLimiter(context.ip, 'getLnPay');
|
||||
|
||||
const [response, error] = await toWithError(fetch(appUrls.github));
|
||||
const [response, error] = await toWithError(
|
||||
fetchWithProxy(appUrls.github)
|
||||
);
|
||||
|
||||
if (error || !response) {
|
||||
logger.debug('Unable to get latest github version');
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
PayInvoiceType,
|
||||
} from 'server/types/ln-service.types';
|
||||
import { lnAuthUrlGenerator } from 'server/helpers/lnAuth';
|
||||
import { fetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
type LnUrlPayResponseType = {
|
||||
pr?: string;
|
||||
|
@ -74,7 +75,7 @@ export const lnUrlResolvers = {
|
|||
const finalUrl = await lnAuthUrlGenerator(url, lnd);
|
||||
|
||||
try {
|
||||
const response = await fetch(finalUrl);
|
||||
const response = await fetchWithProxy(finalUrl);
|
||||
const json = await response.json();
|
||||
|
||||
logger.debug('LnUrlAuth response: %o', json);
|
||||
|
@ -97,7 +98,7 @@ export const lnUrlResolvers = {
|
|||
await requestLimiter(context.ip, 'fetchLnUrl');
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const response = await fetchWithProxy(url);
|
||||
const json = await response.json();
|
||||
|
||||
if (json.status === 'ERROR') {
|
||||
|
@ -136,7 +137,7 @@ export const lnUrlResolvers = {
|
|||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(finalUrl);
|
||||
const response = await fetchWithProxy(finalUrl);
|
||||
lnServiceResponse = await response.json();
|
||||
|
||||
if (lnServiceResponse.status === 'ERROR') {
|
||||
|
@ -215,7 +216,7 @@ export const lnUrlResolvers = {
|
|||
const finalUrl = `${callback}?k1=${k1}&pr=${info.request}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(finalUrl);
|
||||
const response = await fetchWithProxy(finalUrl);
|
||||
const json = await response.json();
|
||||
|
||||
logger.debug('LnUrlWithdraw response: %o', json);
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
import { ContextType } from 'server/types/apiTypes';
|
||||
import { requestLimiter } from 'server/helpers/rateLimiter';
|
||||
import { toWithError } from 'server/helpers/async';
|
||||
import { appUrls } from 'server/utils/appUrls';
|
||||
import { request, gql } from 'graphql-request';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { appConstants } from 'server/utils/appConstants';
|
||||
import cookieLib from 'cookie';
|
||||
import { graphqlFetchWithProxy } from 'server/utils/fetch';
|
||||
|
||||
const getBaseCanConnectQuery = gql`
|
||||
const getBaseCanConnectQuery = `
|
||||
{
|
||||
hello
|
||||
}
|
||||
`;
|
||||
|
||||
const getBaseInfoQuery = gql`
|
||||
const getBaseInfoQuery = `
|
||||
{
|
||||
getInfo {
|
||||
lastBosUpdate
|
||||
|
@ -24,7 +23,7 @@ const getBaseInfoQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const getBaseNodesQuery = gql`
|
||||
const getBaseNodesQuery = `
|
||||
{
|
||||
getNodes {
|
||||
_id
|
||||
|
@ -35,7 +34,7 @@ const getBaseNodesQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const getBasePointsQuery = gql`
|
||||
const getBasePointsQuery = `
|
||||
{
|
||||
getPoints {
|
||||
alias
|
||||
|
@ -44,7 +43,7 @@ const getBasePointsQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const createBaseInvoiceQuery = gql`
|
||||
const createBaseInvoiceQuery = `
|
||||
mutation CreateInvoice($amount: Int!) {
|
||||
createInvoice(amount: $amount) {
|
||||
request
|
||||
|
@ -53,7 +52,7 @@ const createBaseInvoiceQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const createBaseTokenInvoiceQuery = gql`
|
||||
const createBaseTokenInvoiceQuery = `
|
||||
mutation CreateTokenInvoice($days: Int) {
|
||||
createTokenInvoice(days: $days) {
|
||||
request
|
||||
|
@ -62,7 +61,7 @@ const createBaseTokenInvoiceQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const createThunderPointsQuery = gql`
|
||||
const createThunderPointsQuery = `
|
||||
mutation CreatePoints(
|
||||
$id: String!
|
||||
$alias: String!
|
||||
|
@ -73,13 +72,13 @@ const createThunderPointsQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const createBaseTokenQuery = gql`
|
||||
const createBaseTokenQuery = `
|
||||
mutation CreateBaseToken($id: String!) {
|
||||
createBaseToken(id: $id)
|
||||
}
|
||||
`;
|
||||
|
||||
const getBosScoresQuery = gql`
|
||||
const getBosScoresQuery = `
|
||||
{
|
||||
getBosScores {
|
||||
updated
|
||||
|
@ -94,7 +93,7 @@ const getBosScoresQuery = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
const getBosNodeScoresQuery = gql`
|
||||
const getBosNodeScoresQuery = `
|
||||
query GetNodeScores($publicKey: String!, $token: String!) {
|
||||
getNodeScores(publicKey: $publicKey, token: $token) {
|
||||
alias
|
||||
|
@ -111,8 +110,9 @@ export const tbaseResolvers = {
|
|||
getBaseInfo: async (_: undefined, __: undefined, context: ContextType) => {
|
||||
await requestLimiter(context.ip, 'getBaseInfo');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBaseInfoQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBaseInfoQuery
|
||||
);
|
||||
|
||||
if (error || !data?.getInfo) {
|
||||
|
@ -129,8 +129,9 @@ export const tbaseResolvers = {
|
|||
): Promise<boolean> => {
|
||||
await requestLimiter(context.ip, 'getBaseCanConnect');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBaseCanConnectQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBaseCanConnectQuery
|
||||
);
|
||||
|
||||
if (error || !data?.hello) return false;
|
||||
|
@ -149,11 +150,13 @@ export const tbaseResolvers = {
|
|||
|
||||
await requestLimiter(ip, 'getBosNodeScores');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBosNodeScoresQuery, {
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBosNodeScoresQuery,
|
||||
{
|
||||
publicKey,
|
||||
token: tokenAuth,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
|
@ -166,12 +169,14 @@ export const tbaseResolvers = {
|
|||
getBosScores: async (_: undefined, __: any, context: ContextType) => {
|
||||
await requestLimiter(context.ip, 'getBosScores');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBosScoresQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBosScoresQuery
|
||||
);
|
||||
|
||||
if (error || !data?.getBosScores) {
|
||||
logger.error('Error getting BOS scores');
|
||||
logger.error(error);
|
||||
throw new GraphQLError('ErrorGettingBosScores');
|
||||
}
|
||||
|
||||
|
@ -180,8 +185,9 @@ export const tbaseResolvers = {
|
|||
getBaseNodes: async (_: undefined, __: any, context: ContextType) => {
|
||||
await requestLimiter(context.ip, 'getBaseNodes');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBaseNodesQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBaseNodesQuery
|
||||
);
|
||||
|
||||
if (error || !data?.getNodes) return [];
|
||||
|
@ -193,8 +199,9 @@ export const tbaseResolvers = {
|
|||
getBasePoints: async (_: undefined, __: any, context: ContextType) => {
|
||||
await requestLimiter(context.ip, 'getBasePoints');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, getBasePointsQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
getBasePointsQuery
|
||||
);
|
||||
|
||||
if (error || !data?.getPoints) return [];
|
||||
|
@ -212,8 +219,10 @@ export const tbaseResolvers = {
|
|||
|
||||
if (!params?.amount) return '';
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, createBaseInvoiceQuery, params)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
createBaseInvoiceQuery,
|
||||
params
|
||||
);
|
||||
|
||||
if (error) return null;
|
||||
|
@ -228,8 +237,10 @@ export const tbaseResolvers = {
|
|||
) => {
|
||||
await requestLimiter(ip, 'createBaseInvoice');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, createBaseTokenQuery, { id })
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
createBaseTokenQuery,
|
||||
{ id }
|
||||
);
|
||||
|
||||
if (error || !data?.createBaseToken) {
|
||||
|
@ -278,8 +289,9 @@ export const tbaseResolvers = {
|
|||
) => {
|
||||
await requestLimiter(context.ip, 'createBaseTokenInvoice');
|
||||
|
||||
const [data, error] = await toWithError(
|
||||
request(appUrls.tbase, createBaseTokenInvoiceQuery)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
createBaseTokenInvoiceQuery
|
||||
);
|
||||
|
||||
if (error || !data?.createTokenInvoice) {
|
||||
|
@ -295,11 +307,13 @@ export const tbaseResolvers = {
|
|||
): Promise<boolean> => {
|
||||
await requestLimiter(context.ip, 'createThunderPoints');
|
||||
|
||||
const [info, error] = await toWithError(
|
||||
request(appUrls.tbase, createThunderPointsQuery, params)
|
||||
const { data, error } = await graphqlFetchWithProxy(
|
||||
appUrls.tbase,
|
||||
createThunderPointsQuery,
|
||||
params
|
||||
);
|
||||
|
||||
if (error || !info?.createPoints) return false;
|
||||
if (error || !data?.createPoints) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
|
41
server/utils/fetch.ts
Normal file
41
server/utils/fetch.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { Agent } from 'https';
|
||||
import getConfig from 'next/config';
|
||||
import { SocksProxyAgent } from 'socks-proxy-agent';
|
||||
import fetch from 'node-fetch';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { logger } from 'server/helpers/logger';
|
||||
|
||||
const { serverRuntimeConfig } = getConfig() || { serverRuntimeConfig: {} };
|
||||
const { torProxy } = serverRuntimeConfig;
|
||||
|
||||
let agent: Agent | null = null;
|
||||
|
||||
if (torProxy) {
|
||||
logger.info(`Using tor proxy for external requests: ${torProxy}`);
|
||||
agent = new SocksProxyAgent(torProxy) as any;
|
||||
}
|
||||
|
||||
export const fetchWithProxy = (url: string, options?: {}) => {
|
||||
return agent ? fetch(url, { agent, ...options }) : fetch(url, options);
|
||||
};
|
||||
|
||||
export const graphqlFetchWithProxy = async (
|
||||
url: string,
|
||||
query: string,
|
||||
variables?: { [key: string]: string | number | string[] }
|
||||
): Promise<{
|
||||
data: any;
|
||||
error: undefined | GraphQLError;
|
||||
}> => {
|
||||
return fetchWithProxy(url, {
|
||||
method: 'post',
|
||||
headers: { Accept: 'application/json' },
|
||||
body: JSON.stringify({ query, variables }),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => data)
|
||||
.catch(error => {
|
||||
logger.error('Error doing graphql fetch: %o', error);
|
||||
return { data: undefined, error };
|
||||
});
|
||||
};
|
Loading…
Add table
Reference in a new issue