Enable/Disable with listConfigs

Enable/Disable with listConfigs
This commit is contained in:
Shahana Farooqui 2022-05-16 14:45:41 -04:00 committed by ShahanaFarooqui
parent 81dfa053dc
commit 1e6786a850
23 changed files with 521 additions and 388 deletions

View File

@ -1,37 +0,0 @@
import request from 'request-promise';
import { Logger } from '../../utils/logger.js';
import { Common } from '../../utils/common.js';
let options = null;
const logger = Logger;
const common = Common;
export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/signMessage';
options.form = { message: req.body.message };
request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Sign Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/checkMessage/' + req.body.message + '/' + req.body.signature;
request.get(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Verify Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};

View File

@ -82,21 +82,6 @@ export const listPayments = (req, res, next) => {
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/decode/' + req.params.payReq;
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const postPayment = (req, res, next) => {
options = common.getOptions(req);
if (options.error) {

View File

@ -0,0 +1,97 @@
import request from 'request-promise';
import { Logger } from '../../utils/logger.js';
import { Common } from '../../utils/common.js';
let options = null;
const logger = Logger;
const common = Common;
export const decodePaymentFromPaymentRequest = (selNode, payment) => {
options.url = selNode.ln_server_url + '/v1/utility/decode/' + payment;
return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
return res;
}).catch((err) => { });
};
export const decodePayments = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payments List..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
if (req.body.payments) {
const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values });
res.status(200).json(values);
}).
catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payments Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
}
else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Empty Payment List Decoded' });
return res.status(200).json([]);
}
};
export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/decode/' + req.params.payReq;
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/signMessage';
options.form = { message: req.body.message };
request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Sign Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/checkMessage/' + req.body.message + '/' + req.body.signature;
request.get(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Verify Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const listConfigs = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/listConfigs';
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Utility', 'List Configs Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};

View File

@ -9,8 +9,8 @@ import onChainCLRoutes from './onchain.js';
import paymentsCLRoutes from './payments.js';
import peersCLRoutes from './peers.js';
import networkCLRoutes from './network.js';
import messageCLRoutes from './message.js';
import offersCLRoutes from './offers.js';
import utilityCLRoutes from './utility.js';
const router = Router();
const clRoutes = [
{ path: '/getinfo', route: infoCLRoutes },
@ -22,8 +22,8 @@ const clRoutes = [
{ path: '/payments', route: paymentsCLRoutes },
{ path: '/peers', route: peersCLRoutes },
{ path: '/network', route: networkCLRoutes },
{ path: '/message', route: messageCLRoutes },
{ path: '/offers', route: offersCLRoutes }
{ path: '/offers', route: offersCLRoutes },
{ path: '/utility', route: utilityCLRoutes }
];
clRoutes.forEach((route) => {
router.use(route.path, route.route);

View File

@ -1,8 +0,0 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { signMessage, verifyMessage } from '../../controllers/cln/message.js';
const router = Router();
router.post('/sign', isAuthenticated, signMessage);
router.post('/verify', isAuthenticated, verifyMessage);
export default router;

View File

@ -1,9 +1,8 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { listPayments, decodePayment, postPayment } from '../../controllers/cln/payments.js';
import { listPayments, postPayment } from '../../controllers/cln/payments.js';
const router = Router();
router.get('/', isAuthenticated, listPayments);
router.get('/decode/:payReq', isAuthenticated, decodePayment);
router.post('/', isAuthenticated, postPayment);
export default router;

View File

@ -0,0 +1,11 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { decodePayments, decodePayment, signMessage, verifyMessage, listConfigs } from '../../controllers/cln/utility.js';
const router = Router();
router.get('/', isAuthenticated, decodePayments);
router.get('/decode/:payReq', isAuthenticated, decodePayment);
router.post('/sign', isAuthenticated, signMessage);
router.post('/verify', isAuthenticated, verifyMessage);
router.get('/listConfigs', isAuthenticated, listConfigs);
export default router;

View File

@ -1,35 +0,0 @@
import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js';
let options = null;
const logger: LoggerService = Logger;
const common: CommonService = Common;
export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/signMessage';
options.form = { message: req.body.message };
request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Sign Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/checkMessage/' + req.body.message + '/' + req.body.signature;
request.get(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Verify Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};

View File

@ -74,20 +74,6 @@ export const listPayments = (req, res, next) => {
});
};
export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/decode/' + req.params.payReq;
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const postPayment = (req, res, next) => {
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }

View File

@ -0,0 +1,94 @@
import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js';
let options = null;
const logger: LoggerService = Logger;
const common: CommonService = Common;
export const decodePaymentFromPaymentRequest = (selNode: CommonSelectedNode, payment) => {
options.url = selNode.ln_server_url + '/v1/utility/decode/' + payment;
return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
return res;
}).catch((err) => { });
};
export const decodePayments = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payments List..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
if (req.body.payments) {
const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values });
res.status(200).json(values);
}).
catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payments Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
} else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Empty Payment List Decoded' });
return res.status(200).json([]);
}
};
export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/decode/' + req.params.payReq;
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/signMessage';
options.form = { message: req.body.message };
request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Sign Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/checkMessage/' + req.body.message + '/' + req.body.signature;
request.get(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
res.status(201).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Message', 'Verify Message Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const listConfigs = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/utility/listConfigs';
request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Utility', 'List Configs Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};

View File

@ -9,8 +9,8 @@ import onChainCLRoutes from './onchain.js';
import paymentsCLRoutes from './payments.js';
import peersCLRoutes from './peers.js';
import networkCLRoutes from './network.js';
import messageCLRoutes from './message.js';
import offersCLRoutes from './offers.js';
import utilityCLRoutes from './utility.js';
const router = Router();
@ -24,8 +24,8 @@ const clRoutes = [
{ path: '/payments', route: paymentsCLRoutes },
{ path: '/peers', route: peersCLRoutes },
{ path: '/network', route: networkCLRoutes },
{ path: '/message', route: messageCLRoutes },
{ path: '/offers', route: offersCLRoutes }
{ path: '/offers', route: offersCLRoutes },
{ path: '/utility', route: utilityCLRoutes }
];
clRoutes.forEach((route) => {

View File

@ -1,11 +0,0 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { signMessage, verifyMessage } from '../../controllers/cln/message.js';
const router = Router();
router.post('/sign', isAuthenticated, signMessage);
router.post('/verify', isAuthenticated, verifyMessage);
export default router;

View File

@ -1,12 +1,11 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { listPayments, decodePayment, postPayment } from '../../controllers/cln/payments.js';
import { listPayments, postPayment } from '../../controllers/cln/payments.js';
const router = Router();
router.get('/', isAuthenticated, listPayments);
router.get('/decode/:payReq', isAuthenticated, decodePayment);
router.post('/', isAuthenticated, postPayment);
export default router;

View File

@ -0,0 +1,14 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { decodePayments, decodePayment, signMessage, verifyMessage, listConfigs } from '../../controllers/cln/utility.js';
const router = Router();
router.get('/', isAuthenticated, decodePayments);
router.get('/decode/:payReq', isAuthenticated, decodePayment);
router.post('/sign', isAuthenticated, signMessage);
router.post('/verify', isAuthenticated, verifyMessage);
router.get('/listConfigs', isAuthenticated, listConfigs);
export default router;

View File

@ -9,7 +9,7 @@
<span class="page-title">Features</span>
</div>
<mat-accordion>
<mat-expansion-panel [expanded]="false" class="flat-expansion-panel my-1" *ngFor="let feature of features; index as i">
<mat-expansion-panel [expanded]="false" class="flat-expansion-panel my-1" *ngFor="let feature of features; index as i" (opened)="onPanelExpanded(i)">
<mat-expansion-panel-header>
<mat-panel-title fxFlex="100" fxLayoutAlign="space-between center">
<h4 class="font-bold-500">{{feature.name}}</h4>

View File

@ -47,21 +47,15 @@ export class ExperimentalSettingsComponent implements OnInit, OnDestroy {
constructor(private logger: LoggerService, private store: Store<RTLState>, private dataService: DataService) { }
ngOnInit() {
if (!this.fundingPolicy) {
this.dataService.getOrUpdateFunderPolicy().pipe(takeUntil(this.unSubs[0])).subscribe((res: any) => {
this.logger.info('Received Funder Update Policy: ' + JSON.stringify(res));
this.fundingPolicy = res;
this.features[1].enabled = !!(this.fundingPolicy && this.fundingPolicy.summary);
if (this.fundingPolicy.policy) {
this.selPolicyType = LADS_POLICY.find((policy) => policy.id === this.fundingPolicy.policy);
}
this.policyMod = this.fundingPolicy.policy_mod || this.fundingPolicy.policy_mod === 0 ? this.fundingPolicy.policy_mod : null;
this.leaseFeeBaseSat = this.fundingPolicy.lease_fee_base_msat ? this.fundingPolicy.lease_fee_base_msat / 1000 : this.fundingPolicy.lease_fee_base_msat === 0 ? 0 : null;
this.leaseFeeBasis = this.fundingPolicy.lease_fee_basis || this.fundingPolicy.lease_fee_basis === 0 ? this.fundingPolicy.lease_fee_basis : null;
this.channelFeeMaxBaseSat = this.fundingPolicy.channel_fee_max_base_msat ? this.fundingPolicy.channel_fee_max_base_msat / 1000 : this.fundingPolicy.channel_fee_max_base_msat === 0 ? 0 : null;
this.channelFeeMaxProportional = this.fundingPolicy.channel_fee_max_proportional_thousandths || this.fundingPolicy.channel_fee_max_proportional_thousandths === 0 ? this.fundingPolicy.channel_fee_max_proportional_thousandths : null;
});
}
this.dataService.listConfigs().pipe(takeUntil(this.unSubs[0])).subscribe({
next: (res: any) => {
this.logger.info('Received List Configs: ' + JSON.stringify(res));
this.features[1].enabled = !!res['experimental-dual-fund'];
}, error: (err) => {
this.logger.error('List Config Error: ' + JSON.stringify(err));
this.features[1].enabled = false;
}
});
this.store.select(rootSelectedNode).pipe(takeUntil(this.unSubs[1])).
subscribe((selNode) => {
this.selNode = selNode;
@ -75,6 +69,23 @@ export class ExperimentalSettingsComponent implements OnInit, OnDestroy {
});
}
onPanelExpanded(panelId: number) {
if (panelId === 1 && !this.fundingPolicy) {
this.dataService.getOrUpdateFunderPolicy().pipe(takeUntil(this.unSubs[3])).subscribe((res: any) => {
this.logger.info('Received Funder Update Policy: ' + JSON.stringify(res));
this.fundingPolicy = res;
if (this.fundingPolicy.policy) {
this.selPolicyType = LADS_POLICY.find((policy) => policy.id === this.fundingPolicy.policy);
}
this.policyMod = this.fundingPolicy.policy_mod || this.fundingPolicy.policy_mod === 0 ? this.fundingPolicy.policy_mod : null;
this.leaseFeeBaseSat = this.fundingPolicy.lease_fee_base_msat ? this.fundingPolicy.lease_fee_base_msat / 1000 : this.fundingPolicy.lease_fee_base_msat === 0 ? 0 : null;
this.leaseFeeBasis = this.fundingPolicy.lease_fee_basis || this.fundingPolicy.lease_fee_basis === 0 ? this.fundingPolicy.lease_fee_basis : null;
this.channelFeeMaxBaseSat = this.fundingPolicy.channel_fee_max_base_msat ? this.fundingPolicy.channel_fee_max_base_msat / 1000 : this.fundingPolicy.channel_fee_max_base_msat === 0 ? 0 : null;
this.channelFeeMaxProportional = this.fundingPolicy.channel_fee_max_proportional_thousandths || this.fundingPolicy.channel_fee_max_proportional_thousandths === 0 ? this.fundingPolicy.channel_fee_max_proportional_thousandths : null;
});
}
}
onUpdateFeature(): boolean | void {
this.logger.info(this.selNode);
this.selNode.settings.enableOffers = this.enableOffers;
@ -104,7 +115,7 @@ export class ExperimentalSettingsComponent implements OnInit, OnDestroy {
this.flgUpdateCalled = false;
this.updateMsg = '';
this.dataService.getOrUpdateFunderPolicy(this.selPolicyType.id, this.policyMod, this.leaseFeeBaseSat, this.leaseFeeBasis, this.channelFeeMaxBaseSat * 1000, this.channelFeeMaxProportional).
pipe(takeUntil(this.unSubs[3])).
pipe(takeUntil(this.unSubs[4])).
subscribe({
next: (updatePolicyRes: any) => {
this.logger.info(updatePolicyRes);
@ -121,12 +132,16 @@ export class ExperimentalSettingsComponent implements OnInit, OnDestroy {
onResetPolicy() {
this.flgUpdateCalled = false;
this.updateMsg = '';
this.selPolicyType = LADS_POLICY[0];
this.policyMod = this.fundingPolicy.policy_mod !== 0 && !this.fundingPolicy.policy_mod ? null : this.fundingPolicy.policy_mod;
this.leaseFeeBaseSat = this.fundingPolicy.lease_fee_base_msat !== 0 && !this.fundingPolicy.lease_fee_base_msat ? null : this.fundingPolicy.lease_fee_base_msat / 1000;
this.leaseFeeBasis = this.fundingPolicy.lease_fee_basis !== 0 && !this.fundingPolicy.lease_fee_basis ? null : this.fundingPolicy.lease_fee_basis;
this.channelFeeMaxBaseSat = this.fundingPolicy.channel_fee_max_base_msat !== 0 && !this.fundingPolicy.channel_fee_max_base_msat ? null : this.fundingPolicy.channel_fee_max_base_msat / 1000;
this.channelFeeMaxProportional = this.fundingPolicy.channel_fee_max_proportional_thousandths !== 0 && !this.fundingPolicy.channel_fee_max_proportional_thousandths ? null : this.fundingPolicy.channel_fee_max_proportional_thousandths;
if (this.fundingPolicy.policy) {
this.selPolicyType = LADS_POLICY.find((policy) => policy.id === this.fundingPolicy.policy);
} else {
this.selPolicyType = LADS_POLICY[0];
}
this.policyMod = this.fundingPolicy.policy_mod || this.fundingPolicy.policy_mod === 0 ? this.fundingPolicy.policy_mod : null;
this.leaseFeeBaseSat = this.fundingPolicy.lease_fee_base_msat ? this.fundingPolicy.lease_fee_base_msat / 1000 : this.fundingPolicy.lease_fee_base_msat === 0 ? 0 : null;
this.leaseFeeBasis = this.fundingPolicy.lease_fee_basis || this.fundingPolicy.lease_fee_basis === 0 ? this.fundingPolicy.lease_fee_basis : null;
this.channelFeeMaxBaseSat = this.fundingPolicy.channel_fee_max_base_msat ? this.fundingPolicy.channel_fee_max_base_msat / 1000 : this.fundingPolicy.channel_fee_max_base_msat === 0 ? 0 : null;
this.channelFeeMaxProportional = this.fundingPolicy.channel_fee_max_proportional_thousandths || this.fundingPolicy.channel_fee_max_proportional_thousandths === 0 ? this.fundingPolicy.channel_fee_max_proportional_thousandths : null;
}
ngOnDestroy() {

View File

@ -307,16 +307,18 @@ export class CommonService implements OnDestroy {
}
extractErrorMessage(err: any, genericErrorMessage: string = 'Unknown Error.') {
const msg = this.titleCase((err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.error && typeof err.error.error.error.error.error === 'string') ? err.error.error.error.error.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && typeof err.error.error.error.error === 'string') ? err.error.error.error.error :
(err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error :
(err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error :
(err.error && typeof err.error === 'string') ? err.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message :
(err.error && err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message :
(err.error && err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message :
(err.error && err.error.message && typeof err.error.message === 'string') ? err.error.message :
(err.message && typeof err.message === 'string') ? err.message : genericErrorMessage);
const msg = this.titleCase(
(err.error.text && typeof err.error.text === 'string' && err.error.text.includes('<!DOCTYPE html><html lang="en">')) ? 'API Route Does Not Exist.' :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.error && typeof err.error.error.error.error.error === 'string') ? err.error.error.error.error.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && typeof err.error.error.error.error === 'string') ? err.error.error.error.error :
(err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error :
(err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error :
(err.error && typeof err.error === 'string') ? err.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message :
(err.error && err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message :
(err.error && err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message :
(err.error && err.error.message && typeof err.error.message === 'string') ? err.error.message :
(err.message && typeof err.message === 'string') ? err.message : genericErrorMessage);
this.logger.info('Error Message: ' + msg);
return msg;
}

View File

@ -318,6 +318,7 @@ export const UI_MESSAGES = {
CREATE_OFFER: 'Creating Offer...',
DELETE_OFFER_BOOKMARK: 'Deleting Bookmark...',
GET_FUNDER_POLICY: 'Getting Or Updating Funder Policy...',
GET_LIST_CONFIGS: 'Getting List Configurations...',
LOG_OUT: 'Logging Out...'
};

View File

@ -1,8 +1,8 @@
import { Injectable, OnDestroy } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { TitleCasePipe } from '@angular/common';
import { Subject, throwError, of } from 'rxjs';
import { map, takeUntil, catchError, mergeMap, withLatestFrom } from 'rxjs/operators';
import { Subject, throwError, of, BehaviorSubject } from 'rxjs';
import { map, takeUntil, catchError, mergeMap, withLatestFrom, first } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { MatSnackBar } from '@angular/material/snack-bar';
@ -20,35 +20,16 @@ import { allChannels } from '../../lnd/store/lnd.selector';
@Injectable()
export class DataService implements OnDestroy {
private lnImplementation = 'LND';
private childAPIUrl = API_URL;
private APIUrl = API_URL;
private lnImplementation = '';
public lnImplementationUpdated: BehaviorSubject<string> = new BehaviorSubject(null);
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private httpClient: HttpClient, private store: Store<RTLState>, private logger: LoggerService, private snackBar: MatSnackBar, private titleCasePipe: TitleCasePipe) { }
getChildAPIUrl() {
return this.childAPIUrl;
}
getLnImplementation() {
return this.lnImplementation;
}
setChildAPIUrl(lnImplementation: string) {
this.lnImplementation = lnImplementation;
switch (lnImplementation) {
case 'CLN':
this.childAPIUrl = API_URL + '/cln';
break;
case 'ECL':
this.childAPIUrl = API_URL + '/ecl';
break;
default:
this.childAPIUrl = API_URL + '/lnd';
break;
}
setLnImplementation(lnImplementation: string) {
this.lnImplementation = lnImplementation.toLowerCase();
this.lnImplementationUpdated.next(this.lnImplementation);
}
getFiatRates() {
@ -56,130 +37,161 @@ export class DataService implements OnDestroy {
}
decodePayment(payment: string, fromDialog: boolean) {
const url = this.childAPIUrl + environment.PAYMENTS_API + '/decode/' + payment;
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.DECODE_PAYMENT }));
return this.httpClient.get(url).pipe(
takeUntil(this.unSubs[0]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.DECODE_PAYMENT }));
return res;
}),
catchError((err) => {
if (fromDialog) {
this.handleErrorWithoutAlert('Decode Payment', UI_MESSAGES.DECODE_PAYMENT, err);
} else {
this.handleErrorWithAlert('decodePaymentData', UI_MESSAGES.DECODE_PAYMENT, 'Decode Payment Failed', this.childAPIUrl + environment.PAYMENTS_API + '/decode/', err);
}
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
let url = this.APIUrl + '/' + updatedLnImplementation + environment.PAYMENTS_API + '/decode/' + payment;
if (updatedLnImplementation === 'cln') {
url = this.APIUrl + '/' + updatedLnImplementation + environment.UTILITY_API + '/decode/' + payment;
}
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.DECODE_PAYMENT }));
return this.httpClient.get(url).pipe(
takeUntil(this.unSubs[0]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.DECODE_PAYMENT }));
return res;
}),
catchError((err) => {
if (fromDialog) {
this.handleErrorWithoutAlert('Decode Payment', UI_MESSAGES.DECODE_PAYMENT, err);
} else {
this.handleErrorWithAlert('decodePaymentData', UI_MESSAGES.DECODE_PAYMENT, 'Decode Payment Failed', url, err);
}
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
decodePayments(payments: string) {
let url = this.childAPIUrl + environment.PAYMENTS_API;
let msg = UI_MESSAGES.DECODE_PAYMENTS;
if (this.getLnImplementation() === 'ECL') {
url = this.childAPIUrl + environment.PAYMENTS_API + '/getsentinfos';
msg = UI_MESSAGES.GET_SENT_PAYMENTS;
}
this.store.dispatch(openSpinner({ payload: msg }));
return this.httpClient.post(url, { payments: payments }).pipe(
takeUntil(this.unSubs[1]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: msg }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('decodePaymentsData', msg, msg + ' Failed', url, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
let url = '';
let msg = '';
if (updatedLnImplementation === 'ecl') {
url = this.APIUrl + '/' + updatedLnImplementation + environment.PAYMENTS_API + '/getsentinfos';
msg = UI_MESSAGES.GET_SENT_PAYMENTS;
} else if (updatedLnImplementation === 'cln') {
url = this.APIUrl + '/' + updatedLnImplementation + environment.UTILITY_API;
msg = UI_MESSAGES.DECODE_PAYMENTS;
} else {
url = this.APIUrl + '/' + updatedLnImplementation + environment.PAYMENTS_API;
msg = UI_MESSAGES.DECODE_PAYMENTS;
}
this.store.dispatch(openSpinner({ payload: msg }));
return this.httpClient.post(url, { payments: payments }).pipe(
takeUntil(this.unSubs[1]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: msg }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('decodePaymentsData', msg, msg + ' Failed', url, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
getAliasesFromPubkeys(pubkey: string, multiple: boolean) {
if (multiple) {
const pubkey_params = new HttpParams().set('pubkeys', pubkey);
return this.httpClient.get(this.childAPIUrl + environment.NETWORK_API + '/nodes', { params: pubkey_params });
} else {
return this.httpClient.get(this.childAPIUrl + environment.NETWORK_API + '/node/' + pubkey);
}
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
if (multiple) {
const pubkey_params = new HttpParams().set('pubkeys', pubkey);
return this.httpClient.get(this.APIUrl + '/' + updatedLnImplementation + environment.NETWORK_API + '/nodes', { params: pubkey_params });
} else {
return this.httpClient.get(this.APIUrl + '/' + updatedLnImplementation + environment.NETWORK_API + '/node/' + pubkey);
}
}));
}
signMessage(msg: string) {
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.SIGN_MESSAGE }));
return this.httpClient.post(this.childAPIUrl + environment.MESSAGE_API + '/sign', { message: msg }).pipe(
takeUntil(this.unSubs[2]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.SIGN_MESSAGE }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('signMessageData', UI_MESSAGES.SIGN_MESSAGE, 'Sign Message Failed', this.childAPIUrl + environment.MESSAGE_API + '/sign', err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
let url = this.APIUrl + '/' + updatedLnImplementation + environment.MESSAGE_API + '/sign';
if (updatedLnImplementation === 'cln') {
url = this.APIUrl + '/' + updatedLnImplementation + environment.UTILITY_API + '/sign';
}
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.SIGN_MESSAGE }));
return this.httpClient.post(url, { message: msg }).pipe(
takeUntil(this.unSubs[2]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.SIGN_MESSAGE }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('signMessageData', UI_MESSAGES.SIGN_MESSAGE, 'Sign Message Failed', url, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
verifyMessage(msg: string, sign: string) {
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.VERIFY_MESSAGE }));
return this.httpClient.post(this.childAPIUrl + environment.MESSAGE_API + '/verify', { message: msg, signature: sign }).pipe(
takeUntil(this.unSubs[3]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.VERIFY_MESSAGE }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('verifyMessageData', UI_MESSAGES.VERIFY_MESSAGE, 'Verify Message Failed', this.childAPIUrl + environment.MESSAGE_API + '/verify', err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
let url = this.APIUrl + '/' + updatedLnImplementation + environment.MESSAGE_API + '/verify';
if (updatedLnImplementation === 'cln') {
url = this.APIUrl + '/' + updatedLnImplementation + environment.UTILITY_API + '/verify';
}
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.VERIFY_MESSAGE }));
return this.httpClient.post(url, { message: msg, signature: sign }).pipe(
takeUntil(this.unSubs[3]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.VERIFY_MESSAGE }));
return res;
}),
catchError((err) => {
this.handleErrorWithAlert('verifyMessageData', UI_MESSAGES.VERIFY_MESSAGE, 'Verify Message Failed', url, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
bumpFee(txid: string, outputIndex: number, targetConf: number, satPerByte: number) {
const bumpFeeBody: any = { txid: txid, outputIndex: outputIndex };
if (targetConf) {
bumpFeeBody.targetConf = targetConf;
}
if (satPerByte) {
bumpFeeBody.satPerByte = satPerByte;
}
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.BUMP_FEE }));
return this.httpClient.post(this.childAPIUrl + environment.WALLET_API + '/bumpfee', bumpFeeBody).pipe(
takeUntil(this.unSubs[4]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.BUMP_FEE }));
this.snackBar.open('Successfully bumped the fee. Use the block explorer to verify transaction.');
return res;
}),
catchError((err) => {
this.handleErrorWithoutAlert('Bump Fee', UI_MESSAGES.BUMP_FEE, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
const bumpFeeBody: any = { txid: txid, outputIndex: outputIndex };
if (targetConf) {
bumpFeeBody.targetConf = targetConf;
}
if (satPerByte) {
bumpFeeBody.satPerByte = satPerByte;
}
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.BUMP_FEE }));
return this.httpClient.post(this.APIUrl + '/' + updatedLnImplementation + environment.WALLET_API + '/bumpfee', bumpFeeBody).pipe(
takeUntil(this.unSubs[4]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.BUMP_FEE }));
this.snackBar.open('Successfully bumped the fee. Use the block explorer to verify transaction.');
return res;
}),
catchError((err) => {
this.handleErrorWithoutAlert('Bump Fee', UI_MESSAGES.BUMP_FEE, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
labelUTXO(txid: string, label: string, overwrite: boolean = true) {
const labelBody = { txid: txid, label: label, overwrite: overwrite };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.LABEL_UTXO }));
return this.httpClient.post(this.childAPIUrl + environment.WALLET_API + '/label', labelBody).pipe(
takeUntil(this.unSubs[5]),
map((res) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.LABEL_UTXO }));
return res;
}), catchError((err) => {
this.handleErrorWithoutAlert('Lease UTXO', UI_MESSAGES.LABEL_UTXO, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
const labelBody = { txid: txid, label: label, overwrite: overwrite };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.LABEL_UTXO }));
return this.httpClient.post(this.APIUrl + '/' + updatedLnImplementation + environment.WALLET_API + '/label', labelBody).pipe(
takeUntil(this.unSubs[5]),
map((res) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.LABEL_UTXO }));
return res;
}), catchError((err) => {
this.handleErrorWithoutAlert('Lease UTXO', UI_MESSAGES.LABEL_UTXO, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
leaseUTXO(txid: string, output_index: number) {
const leaseBody: any = { txid: txid, outputIndex: output_index };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.LEASE_UTXO }));
return this.httpClient.post(this.childAPIUrl + environment.WALLET_API + '/lease', leaseBody).pipe(
takeUntil(this.unSubs[6])).
subscribe({
next: (res: any) => {
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
const leaseBody: any = { txid: txid, outputIndex: output_index };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.LEASE_UTXO }));
return this.httpClient.post(this.APIUrl + '/' + updatedLnImplementation + environment.WALLET_API + '/lease', leaseBody).pipe(
takeUntil(this.unSubs[6]),
map((res: any) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.LEASE_UTXO }));
this.store.dispatch(fetchTransactions());
this.store.dispatch(fetchUTXOs());
@ -190,92 +202,118 @@ export class DataService implements OnDestroy {
replace(' ', '/').
replace(' ', '/').
toUpperCase() + '.');
}, error: (err) => {
}), catchError((err) => {
this.handleErrorWithoutAlert('Lease UTXO', UI_MESSAGES.LEASE_UTXO, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
}
});
})
);
}));
}
getForwardingHistory(start: string, end: string) {
const queryHeaders: SwitchReq = { end_time: end, start_time: start };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.GET_FORWARDING_HISTORY }));
return this.httpClient.post(this.childAPIUrl + environment.SWITCH_API, queryHeaders).pipe(
takeUntil(this.unSubs[7]),
withLatestFrom(this.store.select(allChannels)),
mergeMap(([res, allChannelsSelector]: [any, { channels: Channel[], pendingChannels: PendingChannels, closedChannels: ClosedChannel[] }]) => {
if (res.forwarding_events) {
const storedChannels = [...allChannelsSelector.channels, ...allChannelsSelector.closedChannels];
res.forwarding_events.forEach((event) => {
if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].chan_id.toString() === event.chan_id_in) {
event.alias_in = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : event.chan_id_in;
if (event.alias_out) {
return;
}
}
if (storedChannels[idx].chan_id.toString() === event.chan_id_out) {
event.alias_out = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : event.chan_id_out;
if (event.alias_in) {
return;
}
}
if (idx === storedChannels.length - 1) {
if (!event.alias_in) {
event.alias_in = event.chan_id_in;
}
if (!event.alias_out) {
event.alias_out = event.chan_id_out;
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
const queryHeaders: SwitchReq = { end_time: end, start_time: start };
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.GET_FORWARDING_HISTORY }));
return this.httpClient.post(this.APIUrl + '/' + updatedLnImplementation + environment.SWITCH_API, queryHeaders).pipe(
takeUntil(this.unSubs[7]),
withLatestFrom(this.store.select(allChannels)),
mergeMap(([res, allChannelsSelector]: [any, { channels: Channel[], pendingChannels: PendingChannels, closedChannels: ClosedChannel[] }]) => {
if (res.forwarding_events) {
const storedChannels = [...allChannelsSelector.channels, ...allChannelsSelector.closedChannels];
res.forwarding_events.forEach((event) => {
if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].chan_id.toString() === event.chan_id_in) {
event.alias_in = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : event.chan_id_in;
if (event.alias_out) {
return;
}
}
if (storedChannels[idx].chan_id.toString() === event.chan_id_out) {
event.alias_out = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : event.chan_id_out;
if (event.alias_in) {
return;
}
}
if (idx === storedChannels.length - 1) {
if (!event.alias_in) {
event.alias_in = event.chan_id_in;
}
if (!event.alias_out) {
event.alias_out = event.chan_id_out;
}
}
}
} else {
event.alias_in = event.chan_id_in;
event.alias_out = event.chan_id_out;
}
} else {
event.alias_in = event.chan_id_in;
event.alias_out = event.chan_id_out;
}
});
} else {
res = {};
}
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.GET_FORWARDING_HISTORY }));
return of(res);
}),
catchError((err) => {
this.handleErrorWithAlert('getForwardingHistoryData', UI_MESSAGES.GET_FORWARDING_HISTORY, 'Forwarding History Failed', this.childAPIUrl + environment.SWITCH_API, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
}));
});
} else {
res = {};
}
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.GET_FORWARDING_HISTORY }));
return of(res);
}),
catchError((err) => {
this.handleErrorWithAlert('getForwardingHistoryData', UI_MESSAGES.GET_FORWARDING_HISTORY, 'Forwarding History Failed', this.APIUrl + '/' + updatedLnImplementation + environment.SWITCH_API, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
}));
}));
}
listConfigs() {
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.GET_LIST_CONFIGS }));
return this.httpClient.get(this.APIUrl + '/' + updatedLnImplementation + environment.UTILITY_API + '/listConfigs').pipe(
takeUntil(this.unSubs[9]),
mergeMap((res) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.GET_LIST_CONFIGS }));
return of(res);
}), catchError((err) => {
this.handleErrorWithoutAlert('List Configurations', UI_MESSAGES.GET_LIST_CONFIGS, err);
return throwError(() => this.extractErrorMessage(err));
})
);
}));
}
getOrUpdateFunderPolicy(policy?: any, policyMod?: any, leaseFeeBaseMsat?: any, leaseFeeBasis?: any, channelFeeMaxBaseMsat?: any, channelFeeMaxProportional?: any) {
const postParams = policy ? { policy: policy, policyMod: policyMod, leaseFeeBaseMsat: leaseFeeBaseMsat, leaseFeeBasis: leaseFeeBasis, channelFeeMaxBaseMsat: channelFeeMaxBaseMsat, channelFeeMaxProportional: channelFeeMaxProportional } : null;
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.GET_FUNDER_POLICY }));
return this.httpClient.post(this.childAPIUrl + environment.CHANNELS_API + '/funderUpdate', postParams).pipe(
takeUntil(this.unSubs[8]),
map((res) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.GET_FUNDER_POLICY }));
return res;
}), catchError((err) => {
this.handleErrorWithoutAlert('Funder Policy', UI_MESSAGES.GET_FUNDER_POLICY, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
return this.lnImplementationUpdated.pipe(first((val) => val !== null), mergeMap((updatedLnImplementation) => {
const postParams = policy ? { policy: policy, policyMod: policyMod, leaseFeeBaseMsat: leaseFeeBaseMsat, leaseFeeBasis: leaseFeeBasis, channelFeeMaxBaseMsat: channelFeeMaxBaseMsat, channelFeeMaxProportional: channelFeeMaxProportional } : null;
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.GET_FUNDER_POLICY }));
return this.httpClient.post(this.APIUrl + '/' + updatedLnImplementation + environment.CHANNELS_API + '/funderUpdate', postParams).pipe(
takeUntil(this.unSubs[8]),
map((res) => {
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.GET_FUNDER_POLICY }));
return res;
}), catchError((err) => {
this.handleErrorWithoutAlert('Funder Policy', UI_MESSAGES.GET_FUNDER_POLICY, err);
return throwError(() => new Error(this.extractErrorMessage(err)));
})
);
}));
}
extractErrorMessage(err: any, genericErrorMessage: string = 'Unknown Error.') {
return this.titleCasePipe.transform((err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.error && typeof err.error.error.error.error.error === 'string') ? err.error.error.error.error.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && typeof err.error.error.error.error === 'string') ? err.error.error.error.error :
(err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error :
(err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error :
(err.error && typeof err.error === 'string') ? err.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message :
(err.error && err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message :
(err.error && err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message :
(err.error && err.error.message && typeof err.error.message === 'string') ? err.error.message :
(err.message && typeof err.message === 'string') ? err.message : genericErrorMessage);
return this.titleCasePipe.transform(
(err.error.text && typeof err.error.text === 'string' && err.error.text.includes('<!DOCTYPE html><html lang="en">')) ? 'API Route Does Not Exist.' :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.error && typeof err.error.error.error.error.error === 'string') ? err.error.error.error.error.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && typeof err.error.error.error.error === 'string') ? err.error.error.error.error :
(err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error :
(err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error :
(err.error && typeof err.error === 'string') ? err.error :
(err.error && err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message :
(err.error && err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message :
(err.error && err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message :
(err.error && err.error.message && typeof err.error.message === 'string') ? err.error.message :
(err.message && typeof err.message === 'string') ? err.message : genericErrorMessage);
}
handleErrorWithoutAlert(actionName: string, uiMessage: string, err: { status: number, error: any }) {
if (err.error.text && typeof err.error.text === 'string' && err.error.text.includes('<!DOCTYPE html><html lang="en">')) {
err = { status: 403, error: { message: 'API Route Does Not Exist.' } };
}
this.logger.error('ERROR IN: ' + actionName + '\n' + JSON.stringify(err));
if (err.status === 401) {
this.logger.info('Redirecting to Login');

View File

@ -45,32 +45,13 @@ export class mockRouter {
export class mockDataService {
private lnImplementation = 'LND';
private childAPIUrl = API_URL;
private APIUrl = API_URL;
public lnImplementationUpdated: BehaviorSubject<string> = new BehaviorSubject(this.lnImplementation);
getChildAPIUrl() {
return of(this.childAPIUrl);
};
getLnImplementation() {
return of(this.lnImplementation);
};
setChildAPIUrl(lnImplementation: string) {
this.lnImplementation = lnImplementation;
switch (lnImplementation) {
case 'CLN':
this.childAPIUrl = API_URL + '/cln';
break;
case 'ECL':
this.childAPIUrl = API_URL + '/ecl';
break;
default:
this.childAPIUrl = API_URL + '/lnd';
break;
}
};
setLnImplementation(lnImplementation: string) {
this.lnImplementation = lnImplementation.toLowerCase();
this.lnImplementationUpdated.next(this.lnImplementation);
}
getFiatRates() {
return of(mockResponseData.fiatRates);

View File

@ -564,7 +564,7 @@ export class RTLEffects implements OnDestroy {
this.store.dispatch(resetECLStore({ payload: selNode }));
if (this.sessionService.getItem('token')) {
const nodeLnImplementation = node.lnImplementation ? node.lnImplementation.toUpperCase() : 'LND';
this.dataService.setChildAPIUrl(nodeLnImplementation);
this.dataService.setLnImplementation(nodeLnImplementation);
const apiUrl = (environment.production && window.location.origin) ? (window.location.origin + '/rtl/api') : API_URL;
this.wsService.connectWebSocket(apiUrl.replace(/^http/, 'ws') + environment.Web_SOCKET_API, node.index.toString());
switch (nodeLnImplementation) {

View File

@ -21,6 +21,7 @@ export const environment = {
ON_CHAIN_API: '/onchain',
MESSAGE_API: '/message',
OFFERS_API: '/offers',
UTILITY_API: '/utility',
LOOP_API: '/loop',
BOLTZ_API: '/boltz',
Web_SOCKET_API: '/ws'

View File

@ -21,6 +21,7 @@ export const environment = {
ON_CHAIN_API: '/onchain',
MESSAGE_API: '/message',
OFFERS_API: '/offers',
UTILITY_API: '/utility',
LOOP_API: '/loop',
BOLTZ_API: '/boltz',
Web_SOCKET_API: '/ws'