mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2024-11-19 01:40:29 +01:00
parent
9bfa04a712
commit
7f00e3de9c
1
.github/docs/Application_configurations.md
vendored
1
.github/docs/Application_configurations.md
vendored
@ -66,4 +66,5 @@ RTL_CONFIG_PATH (Path for the folder containing 'RTL-Config.json' file, Required
|
||||
BITCOIND_CONFIG_PATH (Full path of the bitcoind.conf file including the file name, Optional)<br />
|
||||
CHANNEL_BACKUP_PATH (Folder location for saving the channel backup files, valid for LND implementation only, Required if ln implementation=LND else Optional)<br />
|
||||
ENABLE_OFFERS (Boolean flag to enable the offers feature on core lighning, default false, optional)<br />
|
||||
ENABLE_PEERSWAP (Boolean flag to enable the peerswap feature on core lighning, default false, optional)<br />
|
||||
LN_API_PASSWORD (Password for Eclair implementation if the eclair.conf path is not available, Required if ln implementation=ECL && config path is undefined)<br />
|
||||
|
@ -108,6 +108,7 @@ export const getRTLConfig = (req, res, next) => {
|
||||
settings.swapServerUrl = node.swap_server_url;
|
||||
settings.boltzServerUrl = node.boltz_server_url;
|
||||
settings.enableOffers = node.enable_offers;
|
||||
settings.enablePeerswap = node.enable_peerswap;
|
||||
settings.channelBackupPath = node.channel_backup_path;
|
||||
settings.currencyUnit = node.currency_unit;
|
||||
nodesArr.push({
|
||||
@ -311,7 +312,7 @@ export const updateServiceSettings = (req, res, next) => {
|
||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
||||
const selectedNode = common.findNode(req.session.selectedNode.index);
|
||||
config.nodes.find((node) => {
|
||||
config.nodes.forEach((node) => {
|
||||
if (node.index === req.session.selectedNode.index) {
|
||||
switch (req.body.service) {
|
||||
case 'LOOP':
|
||||
@ -346,6 +347,10 @@ export const updateServiceSettings = (req, res, next) => {
|
||||
node.Settings.enableOffers = req.body.settings.enableOffers;
|
||||
selectedNode.enable_offers = req.body.settings.enableOffers;
|
||||
break;
|
||||
case 'PEERSWAP':
|
||||
node.Settings.enablePeerswap = req.body.settings.enablePeerswap;
|
||||
selectedNode.enable_peerswap = req.body.settings.enablePeerswap;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export class CommonSelectedNode {
|
||||
constructor(options, ln_server_url, macaroon_path, ln_api_password, swap_server_url, boltz_server_url, config_path, rtl_conf_file_path, swap_macaroon_path, boltz_macaroon_path, bitcoind_config_path, channel_backup_path, log_level, log_file, index, ln_node, ln_implementation, user_persona, theme_mode, theme_color, fiat_conversion, currency_unit, ln_version, api_version, enable_offers) {
|
||||
constructor(options, ln_server_url, macaroon_path, ln_api_password, swap_server_url, boltz_server_url, config_path, rtl_conf_file_path, swap_macaroon_path, boltz_macaroon_path, bitcoind_config_path, channel_backup_path, log_level, log_file, index, ln_node, ln_implementation, user_persona, theme_mode, theme_color, fiat_conversion, currency_unit, ln_version, api_version, enable_offers, enable_peerswap) {
|
||||
this.options = options;
|
||||
this.ln_server_url = ln_server_url;
|
||||
this.macaroon_path = macaroon_path;
|
||||
@ -25,6 +25,7 @@ export class CommonSelectedNode {
|
||||
this.ln_version = ln_version;
|
||||
this.api_version = api_version;
|
||||
this.enable_offers = enable_offers;
|
||||
this.enable_peerswap = enable_peerswap;
|
||||
}
|
||||
}
|
||||
export class AuthenticationConfiguration {
|
||||
@ -35,7 +36,7 @@ export class AuthenticationConfiguration {
|
||||
}
|
||||
}
|
||||
export class NodeSettingsConfiguration {
|
||||
constructor(userPersona, themeMode, themeColor, fiatConversion, currencyUnit, bitcoindConfigPath, logLevel, lnServerUrl, swapServerUrl, boltzServerUrl, channelBackupPath, enableOffers) {
|
||||
constructor(userPersona, themeMode, themeColor, fiatConversion, currencyUnit, bitcoindConfigPath, logLevel, lnServerUrl, swapServerUrl, boltzServerUrl, channelBackupPath, enableOffers, enablePeerswap) {
|
||||
this.userPersona = userPersona;
|
||||
this.themeMode = themeMode;
|
||||
this.themeColor = themeColor;
|
||||
@ -48,6 +49,7 @@ export class NodeSettingsConfiguration {
|
||||
this.boltzServerUrl = boltzServerUrl;
|
||||
this.channelBackupPath = channelBackupPath;
|
||||
this.enableOffers = enableOffers;
|
||||
this.enablePeerswap = enablePeerswap;
|
||||
}
|
||||
}
|
||||
export class LogJSONObj {
|
||||
|
@ -241,6 +241,7 @@ export class ConfigService {
|
||||
this.common.nodes[idx].boltz_macaroon_path = '';
|
||||
}
|
||||
this.common.nodes[idx].enable_offers = process.env.ENABLE_OFFERS ? process.env.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false;
|
||||
this.common.nodes[idx].enable_peerswap = process.env.ENABLE_PEERSWAP ? process.env.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false;
|
||||
this.common.nodes[idx].bitcoind_config_path = process.env.BITCOIND_CONFIG_PATH ? process.env.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
|
||||
this.common.nodes[idx].channel_backup_path = process.env.CHANNEL_BACKUP_PATH ? process.env.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index;
|
||||
try {
|
||||
|
@ -109,6 +109,7 @@ export const getRTLConfig = (req, res, next) => {
|
||||
settings.swapServerUrl = node.swap_server_url;
|
||||
settings.boltzServerUrl = node.boltz_server_url;
|
||||
settings.enableOffers = node.enable_offers;
|
||||
settings.enablePeerswap = node.enable_peerswap;
|
||||
settings.channelBackupPath = node.channel_backup_path;
|
||||
settings.currencyUnit = node.currency_unit;
|
||||
nodesArr.push({
|
||||
@ -306,7 +307,7 @@ export const updateServiceSettings = (req, res, next) => {
|
||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
||||
const selectedNode = common.findNode(req.session.selectedNode.index);
|
||||
config.nodes.find((node) => {
|
||||
config.nodes.forEach((node) => {
|
||||
if (node.index === req.session.selectedNode.index) {
|
||||
switch (req.body.service) {
|
||||
case 'LOOP':
|
||||
@ -342,6 +343,11 @@ export const updateServiceSettings = (req, res, next) => {
|
||||
selectedNode.enable_offers = req.body.settings.enableOffers;
|
||||
break;
|
||||
|
||||
case 'PEERSWAP':
|
||||
node.Settings.enablePeerswap = req.body.settings.enablePeerswap;
|
||||
selectedNode.enable_peerswap = req.body.settings.enablePeerswap;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ export class CommonSelectedNode {
|
||||
public currency_unit?: string,
|
||||
public ln_version?: string,
|
||||
public api_version?: string,
|
||||
public enable_offers?: boolean
|
||||
public enable_offers?: boolean,
|
||||
public enable_peerswap?: boolean
|
||||
) { }
|
||||
|
||||
}
|
||||
@ -54,7 +55,8 @@ export class NodeSettingsConfiguration {
|
||||
public swapServerUrl?: string,
|
||||
public boltzServerUrl?: string,
|
||||
public channelBackupPath?: string,
|
||||
public enableOffers?: boolean
|
||||
public enableOffers?: boolean,
|
||||
public enablePeerswap?: boolean
|
||||
) { }
|
||||
|
||||
}
|
||||
|
@ -226,6 +226,7 @@ export class ConfigService {
|
||||
this.common.nodes[idx].boltz_macaroon_path = '';
|
||||
}
|
||||
this.common.nodes[idx].enable_offers = process.env.ENABLE_OFFERS ? process.env.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false;
|
||||
this.common.nodes[idx].enable_peerswap = process.env.ENABLE_PEERSWAP ? process.env.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false;
|
||||
this.common.nodes[idx].bitcoind_config_path = process.env.BITCOIND_CONFIG_PATH ? process.env.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
|
||||
this.common.nodes[idx].channel_backup_path = process.env.CHANNEL_BACKUP_PATH ? process.env.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index;
|
||||
try {
|
||||
|
@ -11,15 +11,21 @@ import { NodeSettingsComponent } from './shared/components/node-config/node-sett
|
||||
import { ServicesSettingsComponent } from './shared/components/node-config/services-settings/services-settings.component';
|
||||
import { LoopServiceSettingsComponent } from './shared/components/node-config/services-settings/loop-service-settings/loop-service-settings.component';
|
||||
import { BoltzServiceSettingsComponent } from './shared/components/node-config/services-settings/boltz-service-settings/boltz-service-settings.component';
|
||||
import { ServicesComponent } from './shared/components/services/services.component';
|
||||
import { LoopComponent } from './shared/components/services/loop/loop.component';
|
||||
import { BoltzRootComponent } from './shared/components/services/boltz/boltz-root.component';
|
||||
import { LNServicesComponent } from './shared/components/ln-services/ln-services.component';
|
||||
import { LoopComponent } from './shared/components/ln-services/loop/loop.component';
|
||||
import { BoltzRootComponent } from './shared/components/ln-services/boltz/boltz-root.component';
|
||||
import { HelpComponent } from './shared/components/help/help.component';
|
||||
import { LoginComponent } from './shared/components/login/login.component';
|
||||
import { NotFoundComponent } from './shared/components/not-found/not-found.component';
|
||||
import { ErrorComponent } from './shared/components/error/error.component';
|
||||
import { AuthGuard } from './shared/services/auth.guard';
|
||||
import { ExperimentalSettingsComponent } from './shared/components/node-config/experimental-settings/experimental-settings.component';
|
||||
import { PeerswapComponent } from './shared/components/ln-services/peerswap/peerswap.component';
|
||||
import { PeerswapServiceSettingsComponent } from './shared/components/node-config/services-settings/peerswap-service-settings/peerswap-service-settings.component';
|
||||
import { SwapPeersComponent } from './shared/components/ln-services/peerswap/swap-peers/swap-peers.component';
|
||||
import { PeerswapsOutComponent } from './shared/components/ln-services/peerswap/swaps-out/swaps-out.component';
|
||||
import { PeerswapsInComponent } from './shared/components/ln-services/peerswap/swaps-in/swaps-in.component';
|
||||
import { PeerswapsCancelledComponent } from './shared/components/ln-services/peerswap/swaps-cancelled/swaps-cancelled.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', pathMatch: 'full', redirectTo: 'login' },
|
||||
@ -42,7 +48,8 @@ export const routes: Routes = [
|
||||
path: 'services', component: ServicesSettingsComponent, canActivate: [AuthGuard], children: [
|
||||
{ path: '', pathMatch: 'full', redirectTo: 'loop' },
|
||||
{ path: 'loop', component: LoopServiceSettingsComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'boltz', component: BoltzServiceSettingsComponent, canActivate: [AuthGuard] }
|
||||
{ path: 'boltz', component: BoltzServiceSettingsComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'peerswap', component: PeerswapServiceSettingsComponent, canActivate: [AuthGuard] }
|
||||
]
|
||||
},
|
||||
{ path: 'experimental', component: ExperimentalSettingsComponent, canActivate: [AuthGuard] },
|
||||
@ -50,12 +57,21 @@ export const routes: Routes = [
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'services', component: ServicesComponent, canActivate: [AuthGuard], children: [
|
||||
path: 'services', component: LNServicesComponent, canActivate: [AuthGuard], children: [
|
||||
{ path: '', pathMatch: 'full', redirectTo: 'loop' },
|
||||
{ path: 'loop', pathMatch: 'full', redirectTo: 'loop/loopout' },
|
||||
{ path: 'loop/:selTab', component: LoopComponent },
|
||||
{ path: 'boltz', pathMatch: 'full', redirectTo: 'boltz/swapout' },
|
||||
{ path: 'boltz/:selTab', component: BoltzRootComponent }
|
||||
{ path: 'boltz/:selTab', component: BoltzRootComponent },
|
||||
{
|
||||
path: 'peerswap', component: PeerswapComponent, canActivate: [AuthGuard], children: [
|
||||
{ path: '', pathMatch: 'full', redirectTo: 'peers' },
|
||||
{ path: 'peers', component: SwapPeersComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'psout', component: PeerswapsOutComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'psin', component: PeerswapsInComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'pscancelled', component: PeerswapsCancelledComponent, canActivate: [AuthGuard] }
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{ path: 'help', component: HelpComponent },
|
||||
|
@ -45,7 +45,7 @@ export const initCLNState: CLNState = {
|
||||
FetchOffers: { status: APICallStatusEnum.UN_INITIATED },
|
||||
FetchOfferBookmarks: { status: APICallStatusEnum.UN_INITIATED }
|
||||
},
|
||||
nodeSettings: { userPersona: UserPersonaEnum.OPERATOR, selCurrencyUnit: 'USD', fiatConversion: false, channelBackupPath: '', currencyUnits: [], enableOffers: false },
|
||||
nodeSettings: { userPersona: UserPersonaEnum.OPERATOR, selCurrencyUnit: 'USD', fiatConversion: false, channelBackupPath: '', currencyUnits: [], enableOffers: false, enablePeerswap: false },
|
||||
information: {},
|
||||
fees: {},
|
||||
feeRatesPerKB: {},
|
||||
|
16
src/app/shared/components/ln-services/peerswap/peerswap.component.html
Executable file
16
src/app/shared/components/ln-services/peerswap/peerswap.component.html
Executable file
@ -0,0 +1,16 @@
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="page-title-container">
|
||||
<fa-icon [icon]="faHandshake" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">Peerswap</span>
|
||||
</div>
|
||||
<div fxLayout="column" class="padding-gap-x">
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<nav mat-tab-nav-bar>
|
||||
<div role="tab" mat-tab-link *ngFor="let link of links" class="mat-tab-label" [active]="activeTab.link === link.link" (click)="activeTab = link" routerLink="{{link.link}}">{{link.name}}</div>
|
||||
</nav>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="mat-tab-body-wrapper mb-2">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
52
src/app/shared/components/ln-services/peerswap/peerswap.component.spec.ts
Executable file
52
src/app/shared/components/ln-services/peerswap/peerswap.component.spec.ts
Executable file
@ -0,0 +1,52 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
|
||||
import { RootReducer } from '../../../../store/rtl.reducers';
|
||||
import { LNDReducer } from '../../../../lnd/store/lnd.reducers';
|
||||
import { CLNReducer } from '../../../../cln/store/cln.reducers';
|
||||
import { ECLReducer } from '../../../../eclair/store/ecl.reducers';
|
||||
import { LoopService } from '../../../services/loop.service';
|
||||
|
||||
import { PeerswapComponent } from './peerswap.component';
|
||||
import { SharedModule } from '../../../shared.module';
|
||||
import { mockDataService } from '../../../test-helpers/mock-services';
|
||||
import { CommonService } from '../../../services/common.service';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { DataService } from '../../../services/data.service';
|
||||
|
||||
describe('PeerswapComponent', () => {
|
||||
let component: PeerswapComponent;
|
||||
let fixture: ComponentFixture<PeerswapComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [PeerswapComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
SharedModule,
|
||||
RouterTestingModule,
|
||||
StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer })
|
||||
],
|
||||
providers: [
|
||||
CommonService,
|
||||
{ provide: DataService, useClass: mockDataService }
|
||||
]
|
||||
}).
|
||||
compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PeerswapComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
});
|
41
src/app/shared/components/ln-services/peerswap/peerswap.component.ts
Executable file
41
src/app/shared/components/ln-services/peerswap/peerswap.component.ts
Executable file
@ -0,0 +1,41 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Router, ResolveEnd, Event } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { faHandshake } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peerswap',
|
||||
templateUrl: './peerswap.component.html',
|
||||
styleUrls: ['./peerswap.component.scss']
|
||||
})
|
||||
export class PeerswapComponent implements OnInit, OnDestroy {
|
||||
|
||||
public faHandshake = faHandshake;
|
||||
public links = [{ link: 'peers', name: 'Peers' }, { link: 'psout', name: 'Peerswap Out' }, { link: 'psin', name: 'Peerswap In' }, { link: 'pscancelled', name: 'Cancelled Peerswaps' }];
|
||||
public activeTab = this.links[0];
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
const linkFound = this.links.find((link) => this.router.url.includes(link.link));
|
||||
this.activeTab = linkFound ? linkFound : this.links[0];
|
||||
this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).
|
||||
subscribe({
|
||||
next: (value: ResolveEnd | Event) => {
|
||||
const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));
|
||||
this.activeTab = linkFound ? linkFound : this.links[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((completeSub) => {
|
||||
completeSub.next(<any>null);
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
<h1>Swap Peers</h1>
|
@ -0,0 +1,35 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SharedModule } from '../../../../shared.module';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SwapPeersComponent } from './swap-peers.component';
|
||||
|
||||
describe('SwapPeersComponent', () => {
|
||||
let component: SwapPeersComponent;
|
||||
let fixture: ComponentFixture<SwapPeersComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SwapPeersComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
SharedModule
|
||||
],
|
||||
providers: []
|
||||
}).
|
||||
compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SwapPeersComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
});
|
@ -0,0 +1,25 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peerswap-peers',
|
||||
templateUrl: './swap-peers.component.html',
|
||||
styleUrls: ['./swap-peers.component.scss']
|
||||
})
|
||||
export class SwapPeersComponent implements OnInit, OnDestroy {
|
||||
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((completeSub) => {
|
||||
completeSub.next(<any>null);
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
<h1>Peerswaps Cancelled</h1>
|
@ -0,0 +1,35 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SharedModule } from '../../../../shared.module';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { PeerswapsCancelledComponent } from './swaps-cancelled.component';
|
||||
|
||||
describe('PeerswapsCancelledComponent', () => {
|
||||
let component: PeerswapsCancelledComponent;
|
||||
let fixture: ComponentFixture<PeerswapsCancelledComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [PeerswapsCancelledComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
SharedModule
|
||||
],
|
||||
providers: []
|
||||
}).
|
||||
compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PeerswapsCancelledComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
});
|
@ -0,0 +1,25 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peerswap-cancelled',
|
||||
templateUrl: './swaps-cancelled.component.html',
|
||||
styleUrls: ['./swaps-cancelled.component.scss']
|
||||
})
|
||||
export class PeerswapsCancelledComponent implements OnInit, OnDestroy {
|
||||
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((completeSub) => {
|
||||
completeSub.next(<any>null);
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
<h1>Peerswaps In</h1>
|
@ -0,0 +1,35 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SharedModule } from '../../../../shared.module';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { PeerswapsInComponent } from './swaps-in.component';
|
||||
|
||||
describe('PeerswapsInComponent', () => {
|
||||
let component: PeerswapsInComponent;
|
||||
let fixture: ComponentFixture<PeerswapsInComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [PeerswapsInComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
SharedModule
|
||||
],
|
||||
providers: []
|
||||
}).
|
||||
compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PeerswapsInComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
});
|
@ -0,0 +1,25 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peer-swaps-in',
|
||||
templateUrl: './swaps-in.component.html',
|
||||
styleUrls: ['./swaps-in.component.scss'],
|
||||
})
|
||||
export class PeerswapsInComponent implements OnInit, OnDestroy {
|
||||
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((completeSub) => {
|
||||
completeSub.next(<any>null);
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
<h1>Peerswaps Out</h1>
|
@ -0,0 +1,35 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SharedModule } from '../../../../shared.module';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { PeerswapsOutComponent } from './swaps-out.component';
|
||||
|
||||
describe('PeerswapsOutComponent', () => {
|
||||
let component: PeerswapsOutComponent;
|
||||
let fixture: ComponentFixture<PeerswapsOutComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [PeerswapsOutComponent],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
SharedModule
|
||||
],
|
||||
providers: []
|
||||
}).
|
||||
compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PeerswapsOutComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
});
|
@ -0,0 +1,25 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peer-swaps-out',
|
||||
templateUrl: './swaps-out.component.html',
|
||||
styleUrls: ['./swaps-out.component.scss'],
|
||||
})
|
||||
export class PeerswapsOutComponent implements OnInit, OnDestroy {
|
||||
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((completeSub) => {
|
||||
completeSub.next(<any>null);
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -35,8 +35,8 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
faEye = faEye;
|
||||
public appConfig: RTLConfiguration;
|
||||
public selConfigNodeIndex: Number;
|
||||
public selNode: ConfigSettingsNode;
|
||||
public settings: Settings;
|
||||
public selNode: ConfigSettingsNode | any;
|
||||
public settings: Settings | null;
|
||||
public version = '';
|
||||
public information: GetInfoRoot = {};
|
||||
public informationChain: GetInfoChain = {};
|
||||
@ -74,7 +74,7 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
this.appConfig = appConfig;
|
||||
});
|
||||
this.store.select(rootSelNodeAndNodeData).pipe(takeUntil(this.unSubs[1])).
|
||||
subscribe((rootData: { nodeDate: GetInfoRoot, selNode: ConfigSettingsNode }) => {
|
||||
subscribe((rootData: { nodeDate: GetInfoRoot, selNode: ConfigSettingsNode | null }) => {
|
||||
this.information = rootData.nodeDate;
|
||||
if (this.information.identity_pubkey) {
|
||||
if (this.information.chains && typeof this.information.chains[0] === 'string') {
|
||||
@ -94,8 +94,8 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
this.smallScreen = true;
|
||||
}
|
||||
this.selNode = rootData.selNode;
|
||||
this.settings = this.selNode.settings;
|
||||
this.selConfigNodeIndex = +(rootData.selNode.index || 0);
|
||||
this.settings = this.selNode?.settings || null;
|
||||
this.selConfigNodeIndex = +(rootData.selNode?.index || 0);
|
||||
if (this.selNode && this.selNode.lnImplementation) {
|
||||
this.filterSideMenuNodes();
|
||||
}
|
||||
@ -143,7 +143,7 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
filterSideMenuNodes() {
|
||||
switch (this.selNode.lnImplementation?.toUpperCase()) {
|
||||
switch (this.selNode?.lnImplementation?.toUpperCase()) {
|
||||
case 'CLN':
|
||||
this.loadCLNMenu();
|
||||
break;
|
||||
@ -163,12 +163,12 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
clonedMenu = JSON.parse(JSON.stringify(MENU_DATA.LNDChildren));
|
||||
this.navMenus.data = clonedMenu?.filter((navMenuData: any) => {
|
||||
if (navMenuData.children && navMenuData.children.length) {
|
||||
navMenuData.children = navMenuData.children?.filter((navMenuChild) => ((navMenuChild.userPersona === UserPersonaEnum.ALL || navMenuChild.userPersona === this.settings.userPersona) && navMenuChild.link !== '/services/loop' && navMenuChild.link !== '/services/boltz') ||
|
||||
(navMenuChild.link === '/services/loop' && this.settings.swapServerUrl && this.settings.swapServerUrl.trim() !== '') ||
|
||||
(navMenuChild.link === '/services/boltz' && this.settings.boltzServerUrl && this.settings.boltzServerUrl.trim() !== ''));
|
||||
navMenuData.children = navMenuData.children?.filter((navMenuChild) => ((navMenuChild.userPersona === UserPersonaEnum.ALL || navMenuChild.userPersona === this.settings?.userPersona) && navMenuChild.link !== '/services/loop' && navMenuChild.link !== '/services/boltz') ||
|
||||
(navMenuChild.link === '/services/loop' && this.settings?.swapServerUrl && this.settings.swapServerUrl.trim() !== '') ||
|
||||
(navMenuChild.link === '/services/boltz' && this.settings?.boltzServerUrl && this.settings.boltzServerUrl.trim() !== ''));
|
||||
return navMenuData.children.length > 0;
|
||||
}
|
||||
return navMenuData.userPersona === UserPersonaEnum.ALL || navMenuData.userPersona === this.settings.userPersona;
|
||||
return navMenuData.userPersona === UserPersonaEnum.ALL || navMenuData.userPersona === this.settings?.userPersona;
|
||||
});
|
||||
}
|
||||
|
||||
@ -177,10 +177,11 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
|
||||
clonedMenu = JSON.parse(JSON.stringify(MENU_DATA.CLNChildren));
|
||||
this.navMenus.data = clonedMenu?.filter((navMenuData: any) => {
|
||||
if (navMenuData.children && navMenuData.children.length) {
|
||||
navMenuData.children = navMenuData.children?.filter((navMenuChild) => ((navMenuChild.userPersona === UserPersonaEnum.ALL || navMenuChild.userPersona === this.settings.userPersona) && navMenuChild.link !== '/cln/messages') ||
|
||||
(navMenuChild.link === '/cln/messages' && this.information.api_version && this.commonService.isVersionCompatible(this.information.api_version, '0.2.2')));
|
||||
navMenuData.children = navMenuData.children?.filter((navMenuChild) => ((navMenuChild.userPersona === UserPersonaEnum.ALL || navMenuChild.userPersona === this.settings?.userPersona) && navMenuChild.link !== '/services/peerswap') ||
|
||||
(navMenuChild.link === '/services/peerswap' && this.settings?.enablePeerswap));
|
||||
return navMenuData.children.length > 0;
|
||||
}
|
||||
return navMenuData.userPersona === UserPersonaEnum.ALL || navMenuData.userPersona === this.settings.userPersona;
|
||||
return navMenuData.userPersona === UserPersonaEnum.ALL || navMenuData.userPersona === this.settings?.userPersona;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<mat-card-content fxLayout="column">
|
||||
<nav mat-tab-nav-bar>
|
||||
<div role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[0].link" (click)="activeLink = links[0].link" routerLink="{{links[0].link}}">{{links[0].name}}</div>
|
||||
<div role="tab" mat-tab-link *ngIf="selNode?.lnImplementation?.toUpperCase() === 'LND'" class="mat-tab-label" [active]="activeLink === links[1].link" (click)="activeLink = links[1].link" routerLink="{{links[1].link}}" [state]="{ initial: false }">{{links[1].name}}</div>
|
||||
<div role="tab" mat-tab-link *ngIf="selNode?.lnImplementation?.toUpperCase() === 'LND' || selNode?.lnImplementation?.toUpperCase() === 'CLN'" class="mat-tab-label" [active]="activeLink === links[1].link" (click)="activeLink = links[1].link" routerLink="{{links[1].link}}" [state]="{ initial: false }">{{links[1].name}}</div>
|
||||
<div role="tab" mat-tab-link *ngIf="selNode?.lnImplementation?.toUpperCase() === 'CLN'" class="mat-tab-label" [active]="activeLink === links[2].link" (click)="activeLink = links[2].link" routerLink="{{links[2].link}}">{{links[2].name}}</div>
|
||||
<div role="tab" mat-tab-link *ngIf="showLnConfig" class="mat-tab-label" [active]="activeLink === links[3].link" (click)="activeLink = links[3].link" routerLink="{{links[3].link}}">{{links[3].name}}</div>
|
||||
</nav>
|
||||
|
@ -18,7 +18,7 @@ export class NodeConfigComponent implements OnInit, OnDestroy {
|
||||
|
||||
public faTools = faTools;
|
||||
public showLnConfig = false;
|
||||
public selNode: ConfigSettingsNode;
|
||||
public selNode: ConfigSettingsNode | any;
|
||||
public lnImplementationStr = '';
|
||||
public links = [{ link: 'layout', name: 'Layout' }, { link: 'services', name: 'Services' }, { link: 'experimental', name: 'Experimental' }, { link: 'lnconfig', name: this.lnImplementationStr }];
|
||||
public activeLink = '';
|
||||
|
@ -0,0 +1,15 @@
|
||||
<div [perfectScrollbar] fxLayout="column" fxFlex="100">
|
||||
<div fxFlex="100" class="alert alert-info mt-1">
|
||||
<fa-icon [icon]="faInfoCircle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span>Please ensure that <strong>peerswapd</strong> is running and accessible to RTL before enabling this service. Click <strong><a href="https://github.com/ElementsProject/peerswap" target="_blank">here</a></strong> to learn more about Core Lightning peerswap.</span>
|
||||
</div>
|
||||
<form fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch" class="settings-container page-sub-title-container mt-1" #form="ngForm">
|
||||
<div fxLayout="column" fxFlex="50" fxLayoutAlign="start stretch">
|
||||
<mat-slide-toggle autoFocus class="mb-1" tabindex="1" color="primary" [(ngModel)]="enablePeerswap" name="peerswap">Enable Peerswap Service</mat-slide-toggle>
|
||||
</div>
|
||||
</form>
|
||||
<div fxLayout="row" class="mt-2">
|
||||
<!-- <button class="mr-1" mat-stroked-button color="primary" type="reset" (click)="onReset()" tabindex="4">Reset</button> -->
|
||||
<button mat-flat-button color="primary" type="submit" (click)="onUpdateService()" tabindex="5">Update</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,3 @@
|
||||
h4 {
|
||||
word-break: break-word;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { ServicesEnum, UI_MESSAGES } from '../../../../services/consts-enums-functions';
|
||||
import { ConfigSettingsNode } from '../../../../models/RTLconfig';
|
||||
import { LoggerService } from '../../../../services/logger.service';
|
||||
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { updateServiceSettings } from '../../../../../store/rtl.actions';
|
||||
import { RTLState } from '../../../../../store/rtl.state';
|
||||
import { setChildNodeSettingsLND } from '../../../../../lnd/store/lnd.actions';
|
||||
import { setChildNodeSettingsCL } from '../../../../../cln/store/cln.actions';
|
||||
import { setChildNodeSettingsECL } from '../../../../../eclair/store/ecl.actions';
|
||||
import { rootSelectedNode } from '../../../../../store/rtl.selector';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-peerswap-service-settings',
|
||||
templateUrl: './peerswap-service-settings.component.html',
|
||||
styleUrls: ['./peerswap-service-settings.component.scss']
|
||||
})
|
||||
export class PeerswapServiceSettingsComponent implements OnInit, OnDestroy {
|
||||
|
||||
public faInfoCircle = faInfoCircle;
|
||||
public selNode: ConfigSettingsNode | any;
|
||||
public enablePeerswap = false;
|
||||
unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<RTLState>) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select(rootSelectedNode).
|
||||
pipe(takeUntil(this.unSubs[0])).
|
||||
subscribe((selNode) => {
|
||||
this.selNode = selNode;
|
||||
this.enablePeerswap = !!selNode?.settings.enablePeerswap;
|
||||
this.logger.info(selNode);
|
||||
});
|
||||
}
|
||||
|
||||
onUpdateService(): boolean | void {
|
||||
this.store.dispatch(updateServiceSettings({ payload: { uiMessage: UI_MESSAGES.UPDATE_PEERSWAP_SETTINGS, service: ServicesEnum.PEERSWAP, settings: { enablePeerswap: this.enablePeerswap } } }));
|
||||
this.store.dispatch(setChildNodeSettingsLND({
|
||||
payload: {
|
||||
userPersona: this.selNode.settings.userPersona, channelBackupPath: this.selNode.settings.channelBackupPath, selCurrencyUnit: this.selNode.settings.currencyUnit, currencyUnits: this.selNode.settings.currencyUnits, fiatConversion: this.selNode.settings.fiatConversion,
|
||||
lnImplementation: this.selNode.lnImplementation, swapServerUrl: this.selNode.settings.swapServerUrl, boltzServerUrl: this.selNode.settings.boltzServerUrl, enableOffers: this.selNode.settings.enableOffers, enablePeerswap: this.selNode.settings.enablePeerswap
|
||||
}
|
||||
}));
|
||||
this.store.dispatch(setChildNodeSettingsCL({
|
||||
payload: {
|
||||
userPersona: this.selNode.settings.userPersona, channelBackupPath: this.selNode.settings.channelBackupPath, selCurrencyUnit: this.selNode.settings.currencyUnit, currencyUnits: this.selNode.settings.currencyUnits, fiatConversion: this.selNode.settings.fiatConversion,
|
||||
lnImplementation: this.selNode.lnImplementation, swapServerUrl: this.selNode.settings.swapServerUrl, boltzServerUrl: this.selNode.settings.boltzServerUrl, enableOffers: this.selNode.settings.enableOffers, enablePeerswap: this.selNode.settings.enablePeerswap
|
||||
}
|
||||
}));
|
||||
this.store.dispatch(setChildNodeSettingsECL({
|
||||
payload: {
|
||||
userPersona: this.selNode.settings.userPersona, channelBackupPath: this.selNode.settings.channelBackupPath, selCurrencyUnit: this.selNode.settings.currencyUnit, currencyUnits: this.selNode.settings.currencyUnits, fiatConversion: this.selNode.settings.fiatConversion,
|
||||
lnImplementation: this.selNode.lnImplementation, swapServerUrl: this.selNode.settings.swapServerUrl, boltzServerUrl: this.selNode.settings.boltzServerUrl, enableOffers: this.selNode.settings.enableOffers, enablePeerswap: this.selNode.settings.enablePeerswap
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach((unsub) => {
|
||||
unsub.next();
|
||||
unsub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -6,8 +6,9 @@
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<nav mat-tab-nav-bar>
|
||||
<div role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[0].link" (click)="activeLink = links[0].link" routerLink="{{links[0].link}}">{{links[0].name}}</div>
|
||||
<div role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[1].link" (click)="activeLink = links[1].link" routerLink="{{links[1].link}}" [state]="{ initial: false }">{{links[1].name}}</div>
|
||||
<div *ngIf="selNode?.lnImplementation?.toUpperCase() === 'LND'" role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[0].link" (click)="activeLink = links[0].link" routerLink="{{links[0].link}}">{{links[0].name}}</div>
|
||||
<div *ngIf="selNode?.lnImplementation?.toUpperCase() === 'LND'" role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[1].link" (click)="activeLink = links[1].link" routerLink="{{links[1].link}}" [state]="{ initial: false }">{{links[1].name}}</div>
|
||||
<div *ngIf="selNode?.lnImplementation?.toUpperCase() === 'CLN'" role="tab" mat-tab-link class="mat-tab-label" [active]="activeLink === links[2].link" (click)="activeLink = links[2].link" routerLink="{{links[2].link}}">{{links[2].name}}</div>
|
||||
</nav>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="mat-tab-body-wrapper">
|
||||
<router-outlet></router-outlet>
|
||||
|
@ -1,8 +1,12 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Router, ResolveEnd, Event } from '@angular/router';
|
||||
import { Router, ResolveEnd, Event, ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { faLayerGroup } from '@fortawesome/free-solid-svg-icons';
|
||||
import { ConfigSettingsNode } from '../../../models/RTLconfig';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { RTLState } from '../../../../store/rtl.state';
|
||||
import { rootSelectedNode } from '../../../../store/rtl.selector';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-services-settings',
|
||||
@ -12,11 +16,12 @@ import { faLayerGroup } from '@fortawesome/free-solid-svg-icons';
|
||||
export class ServicesSettingsComponent implements OnInit, OnDestroy {
|
||||
|
||||
public faLayerGroup = faLayerGroup;
|
||||
public links = [{ link: 'loop', name: 'Loop' }, { link: 'boltz', name: 'Boltz' }];
|
||||
public links = [{ link: 'loop', name: 'Loop' }, { link: 'boltz', name: 'Boltz' }, { link: 'peerswap', name: 'Peerswap' }];
|
||||
public activeLink = '';
|
||||
public selNode: ConfigSettingsNode | any;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private router: Router) { }
|
||||
constructor(private store: Store<RTLState>, private router: Router, private activatedRoute: ActivatedRoute) { }
|
||||
|
||||
ngOnInit() {
|
||||
const linkFound = this.links.find((link) => this.router.url.includes(link.link));
|
||||
@ -25,9 +30,20 @@ export class ServicesSettingsComponent implements OnInit, OnDestroy {
|
||||
subscribe({
|
||||
next: (value: ResolveEnd | Event) => {
|
||||
const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));
|
||||
this.activeLink = linkFound ? linkFound.link : this.links[0].link;
|
||||
if(this.selNode.lnImplementation.toUpperCase() === 'CLN') {
|
||||
this.activeLink = this.links[2].link;
|
||||
} else {
|
||||
this.activeLink = linkFound ? linkFound.link : this.links[0].link;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.store.select(rootSelectedNode).pipe(takeUntil(this.unSubs[1])).subscribe((selNode) => {
|
||||
this.selNode = selNode;
|
||||
if (this.selNode.lnImplementation.toUpperCase() === 'CLN') {
|
||||
this.activeLink = this.links[2].link;
|
||||
this.router.navigate(['./' + this.activeLink], { relativeTo: this.activatedRoute });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
@ -24,7 +24,8 @@ export class Settings {
|
||||
public boltzServerUrl?: string,
|
||||
public channelBackupPath?: string,
|
||||
public currencyUnit?: string,
|
||||
public enableOffers?: boolean
|
||||
public enableOffers?: boolean,
|
||||
public enablePeerswap?: boolean
|
||||
) { }
|
||||
|
||||
}
|
||||
@ -84,6 +85,7 @@ export interface SelNodeChild {
|
||||
swapServerUrl?: string;
|
||||
boltzServerUrl?: string;
|
||||
enableOffers?: boolean;
|
||||
enablePeerswap?: boolean;
|
||||
}
|
||||
|
||||
export class HelpTopic {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faChartBar, faTools, faProjectDiagram, faDownload, faServer, faPercentage, faInfinity, faUserCheck, faLayerGroup, faBullhorn } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faChartBar, faTools, faProjectDiagram, faDownload, faServer, faPercentage, faInfinity, faUserCheck, faLayerGroup, faBullhorn, faHandshake } from '@fortawesome/free-solid-svg-icons';
|
||||
import { UserPersonaEnum } from '../services/consts-enums-functions';
|
||||
|
||||
export class MenuChildNode {
|
||||
@ -64,8 +64,13 @@ export const MENU_DATA: MenuRootNode = {
|
||||
{ id: 39, parentId: 3, name: 'Node/Fee Rates', iconType: 'FA', icon: faServer, link: '/cln/rates', userPersona: UserPersonaEnum.MERCHANT }
|
||||
]
|
||||
},
|
||||
{ id: 4, parentId: 0, name: 'Node Config', iconType: 'FA', icon: faTools, link: '/config', userPersona: UserPersonaEnum.ALL },
|
||||
{ id: 5, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help', userPersona: UserPersonaEnum.ALL }
|
||||
{
|
||||
id: 4, parentId: 0, name: 'Services', iconType: 'FA', icon: faLayerGroup, link: '/services/peerswap', userPersona: UserPersonaEnum.ALL, children: [
|
||||
{ id: 41, parentId: 4, name: 'Peerswap', iconType: 'FA', icon: faHandshake, link: '/services/peerswap', userPersona: UserPersonaEnum.ALL },
|
||||
]
|
||||
},
|
||||
{ id: 5, parentId: 0, name: 'Node Config', iconType: 'FA', icon: faTools, link: '/config', userPersona: UserPersonaEnum.ALL },
|
||||
{ id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help', userPersona: UserPersonaEnum.ALL }
|
||||
],
|
||||
ECLChildren: [
|
||||
{ id: 1, parentId: 0, name: 'Dashboard', iconType: 'FA', icon: faTachometerAlt, link: '/ecl/home', userPersona: UserPersonaEnum.ALL },
|
||||
|
@ -243,7 +243,8 @@ export const SCROLL_RANGES = ['MONTHLY', 'YEARLY'];
|
||||
export enum ServicesEnum {
|
||||
LOOP = 'LOOP',
|
||||
BOLTZ = 'BOLTZ',
|
||||
OFFERS = 'OFFERS'
|
||||
OFFERS = 'OFFERS',
|
||||
PEERSWAP = 'PEERSWAP'
|
||||
}
|
||||
|
||||
export const PASSWORD_BLACKLIST = ['password', 'changeme', 'moneyprintergobrrr'];
|
||||
@ -296,6 +297,7 @@ export const UI_MESSAGES = {
|
||||
WAIT_SYNC_NODE: 'Waiting for Node Sync...',
|
||||
UPDATE_BOLTZ_SETTINGS: 'Updating Boltz Service Settings...',
|
||||
UPDATE_LOOP_SETTINGS: 'Updating Loop Service Settings...',
|
||||
UPDATE_PEERSWAP_SETTINGS: 'Updating Peerswap Service Settings...',
|
||||
UPDATE_SETTING: 'Updating Setting...',
|
||||
UPDATE_UI_SETTINGS: 'Updating Settings...',
|
||||
UPDATE_NODE_SETTINGS: 'Updating Node Settings...',
|
||||
|
@ -65,6 +65,7 @@ import { NodeSettingsComponent } from './components/node-config/node-settings/no
|
||||
import { ServicesSettingsComponent } from './components/node-config/services-settings/services-settings.component';
|
||||
import { LoopServiceSettingsComponent } from './components/node-config/services-settings/loop-service-settings/loop-service-settings.component';
|
||||
import { BoltzServiceSettingsComponent } from './components/node-config/services-settings/boltz-service-settings/boltz-service-settings.component';
|
||||
import { PeerswapServiceSettingsComponent } from './components/node-config/services-settings/peerswap-service-settings/peerswap-service-settings.component';
|
||||
import { ExperimentalSettingsComponent } from './components/node-config/experimental-settings/experimental-settings.component';
|
||||
import { ErrorComponent } from './components/error/error.component';
|
||||
import { CurrencyUnitConverterComponent } from './components/currency-unit-converter/currency-unit-converter.component';
|
||||
@ -79,21 +80,26 @@ import { ErrorMessageComponent } from './components/data-modal/error-message/err
|
||||
import { TwoFactorAuthComponent } from './components/data-modal/two-factor-auth/two-factor-auth.component';
|
||||
import { LoginTokenComponent } from './components/data-modal/login-2fa-token/login-2fa-token.component';
|
||||
|
||||
import { ServicesComponent } from './components/services/services.component';
|
||||
import { LoopComponent } from '../shared/components/services/loop/loop.component';
|
||||
import { SwapsComponent } from '../shared/components/services/loop/swaps/swaps.component';
|
||||
import { LoopModalComponent } from '../shared/components/services/loop/loop-modal/loop-modal.component';
|
||||
import { LoopQuoteComponent } from '../shared/components/services/loop/loop-quote/loop-quote.component';
|
||||
import { LoopStatusComponent } from '../shared/components/services/loop/loop-status/loop-status.component';
|
||||
import { LoopOutInfoGraphicsComponent } from '../shared/components/services/loop/loop-out-info-graphics/info-graphics.component';
|
||||
import { LoopInInfoGraphicsComponent } from '../shared/components/services/loop/loop-in-info-graphics/info-graphics.component';
|
||||
import { BoltzRootComponent } from './components/services/boltz/boltz-root.component';
|
||||
import { BoltzSwapsComponent } from './components/services/boltz/swaps/swaps.component';
|
||||
import { SwapStatusComponent } from './components/services/boltz/swap-status/swap-status.component';
|
||||
import { SwapServiceInfoComponent } from './components/services/boltz/swap-service-info/swap-service-info.component';
|
||||
import { SwapModalComponent } from './components/services/boltz/swap-modal/swap-modal.component';
|
||||
import { SwapInInfoGraphicsComponent } from './components/services/boltz/swap-in-info-graphics/info-graphics.component';
|
||||
import { SwapOutInfoGraphicsComponent } from './components/services/boltz/swap-out-info-graphics/info-graphics.component';
|
||||
import { LNServicesComponent } from './components/ln-services/ln-services.component';
|
||||
import { LoopComponent } from '../shared/components/ln-services/loop/loop.component';
|
||||
import { SwapsComponent } from '../shared/components/ln-services/loop/swaps/swaps.component';
|
||||
import { LoopModalComponent } from '../shared/components/ln-services/loop/loop-modal/loop-modal.component';
|
||||
import { LoopQuoteComponent } from '../shared/components/ln-services/loop/loop-quote/loop-quote.component';
|
||||
import { LoopStatusComponent } from '../shared/components/ln-services/loop/loop-status/loop-status.component';
|
||||
import { LoopOutInfoGraphicsComponent } from '../shared/components/ln-services/loop/loop-out-info-graphics/info-graphics.component';
|
||||
import { LoopInInfoGraphicsComponent } from '../shared/components/ln-services/loop/loop-in-info-graphics/info-graphics.component';
|
||||
import { BoltzRootComponent } from './components/ln-services/boltz/boltz-root.component';
|
||||
import { BoltzSwapsComponent } from './components/ln-services/boltz/swaps/swaps.component';
|
||||
import { SwapStatusComponent } from './components/ln-services/boltz/swap-status/swap-status.component';
|
||||
import { SwapServiceInfoComponent } from './components/ln-services/boltz/swap-service-info/swap-service-info.component';
|
||||
import { SwapModalComponent } from './components/ln-services/boltz/swap-modal/swap-modal.component';
|
||||
import { SwapInInfoGraphicsComponent } from './components/ln-services/boltz/swap-in-info-graphics/info-graphics.component';
|
||||
import { SwapOutInfoGraphicsComponent } from './components/ln-services/boltz/swap-out-info-graphics/info-graphics.component';
|
||||
import { PeerswapComponent } from './components/ln-services/peerswap/peerswap.component';
|
||||
import { SwapPeersComponent } from './components/ln-services/peerswap/swap-peers/swap-peers.component';
|
||||
import { PeerswapsCancelledComponent } from './components/ln-services/peerswap/swaps-cancelled/swaps-cancelled.component';
|
||||
import { PeerswapsInComponent } from './components/ln-services/peerswap/swaps-in/swaps-in.component';
|
||||
import { PeerswapsOutComponent } from './components/ln-services/peerswap/swaps-out/swaps-out.component';
|
||||
|
||||
import { ClipboardDirective } from './directive/clipboard.directive';
|
||||
import { AutoFocusDirective } from './directive/auto-focus.directive';
|
||||
@ -244,11 +250,12 @@ export const DEFAULT_DATE_FORMAT: MatDateFormats = {
|
||||
ServicesSettingsComponent,
|
||||
LoopServiceSettingsComponent,
|
||||
BoltzServiceSettingsComponent,
|
||||
PeerswapServiceSettingsComponent,
|
||||
ExperimentalSettingsComponent,
|
||||
CurrencyUnitConverterComponent,
|
||||
HorizontalScrollerComponent,
|
||||
TransactionsReportTableComponent,
|
||||
ServicesComponent,
|
||||
LNServicesComponent,
|
||||
LoopComponent,
|
||||
SwapsComponent,
|
||||
LoopModalComponent,
|
||||
@ -262,7 +269,12 @@ export const DEFAULT_DATE_FORMAT: MatDateFormats = {
|
||||
SwapServiceInfoComponent,
|
||||
SwapModalComponent,
|
||||
SwapInInfoGraphicsComponent,
|
||||
SwapOutInfoGraphicsComponent
|
||||
SwapOutInfoGraphicsComponent,
|
||||
PeerswapComponent,
|
||||
SwapPeersComponent,
|
||||
PeerswapsCancelledComponent,
|
||||
PeerswapsInComponent,
|
||||
PeerswapsOutComponent
|
||||
],
|
||||
declarations: [
|
||||
AppSettingsComponent,
|
||||
@ -282,6 +294,7 @@ export const DEFAULT_DATE_FORMAT: MatDateFormats = {
|
||||
ServicesSettingsComponent,
|
||||
LoopServiceSettingsComponent,
|
||||
BoltzServiceSettingsComponent,
|
||||
PeerswapServiceSettingsComponent,
|
||||
ExperimentalSettingsComponent,
|
||||
CurrencyUnitConverterComponent,
|
||||
HorizontalScrollerComponent,
|
||||
@ -305,7 +318,7 @@ export const DEFAULT_DATE_FORMAT: MatDateFormats = {
|
||||
TwoFactorAuthComponent,
|
||||
LoginTokenComponent,
|
||||
TransactionsReportTableComponent,
|
||||
ServicesComponent,
|
||||
LNServicesComponent,
|
||||
LoopComponent,
|
||||
SwapsComponent,
|
||||
LoopModalComponent,
|
||||
@ -319,7 +332,12 @@ export const DEFAULT_DATE_FORMAT: MatDateFormats = {
|
||||
SwapServiceInfoComponent,
|
||||
SwapModalComponent,
|
||||
SwapInInfoGraphicsComponent,
|
||||
SwapOutInfoGraphicsComponent
|
||||
SwapOutInfoGraphicsComponent,
|
||||
PeerswapComponent,
|
||||
SwapPeersComponent,
|
||||
PeerswapsCancelledComponent,
|
||||
PeerswapsInComponent,
|
||||
PeerswapsOutComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: LoggerService, useClass: ConsoleLoggerService },
|
||||
|
@ -759,7 +759,8 @@ export const mockActionsData = {
|
||||
boltzServerUrl: '',
|
||||
channelBackupPath: '',
|
||||
currencyUnit: '',
|
||||
enableOffers: false
|
||||
enableOffers: false,
|
||||
enablePeerswap: false
|
||||
},
|
||||
authentication: {
|
||||
swapMacaroonPath: '',
|
||||
@ -782,7 +783,8 @@ export const mockActionsData = {
|
||||
lnImplementation: 'LND',
|
||||
swapServerUrl: '',
|
||||
boltzServerUrl: '',
|
||||
enableOffers: false
|
||||
enableOffers: false,
|
||||
enablePeerswap: false
|
||||
},
|
||||
setSelectedNode: {
|
||||
settings: {
|
||||
@ -802,7 +804,8 @@ export const mockActionsData = {
|
||||
boltzServerUrl: '',
|
||||
channelBackupPath: '',
|
||||
currencyUnit: '',
|
||||
enableOffers: false
|
||||
enableOffers: false,
|
||||
enablePeerswap: false
|
||||
},
|
||||
authentication: {
|
||||
swapMacaroonPath: '',
|
||||
|
@ -499,12 +499,12 @@ export class RTLEffects implements OnDestroy {
|
||||
mergeMap((action: { type: string, payload: SetSelectedNode }) => {
|
||||
this.store.dispatch(openSpinner({ payload: action.payload.uiMessage }));
|
||||
this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'UpdateSelNode', status: APICallStatusEnum.INITIATED } }));
|
||||
return this.httpClient.get(environment.CONF_API + '/updateSelNode/' + action.payload.currentLnNode.index + '/' + action.payload.prevLnNodeIndex).pipe(
|
||||
return this.httpClient.get(environment.CONF_API + '/updateSelNode/' + action.payload.currentLnNode?.index + '/' + action.payload.prevLnNodeIndex).pipe(
|
||||
map((postRes: any) => {
|
||||
this.logger.info(postRes);
|
||||
this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'UpdateSelNode', status: APICallStatusEnum.COMPLETED } }));
|
||||
this.store.dispatch(closeSpinner({ payload: action.payload.uiMessage }));
|
||||
this.initializeNode(action.payload.currentLnNode, action.payload.isInitialSetup);
|
||||
this.initializeNode(action.payload.currentLnNode!, action.payload.isInitialSetup);
|
||||
return { type: RTLActions.VOID };
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
@ -551,9 +551,9 @@ export class RTLEffects implements OnDestroy {
|
||||
const landingPage = isInitialSetup ? '' : 'HOME';
|
||||
let selNode = {};
|
||||
if (node.settings.fiatConversion && node.settings.currencyUnit) {
|
||||
selNode = { userPersona: node.settings.userPersona, channelBackupPath: node.settings.channelBackupPath, selCurrencyUnit: node.settings.currencyUnit, currencyUnits: [...CURRENCY_UNITS, node.settings.currencyUnit], fiatConversion: node.settings.fiatConversion, lnImplementation: node.lnImplementation, swapServerUrl: node.settings.swapServerUrl, boltzServerUrl: node.settings.boltzServerUrl, enableOffers: node.settings.enableOffers };
|
||||
selNode = { userPersona: node.settings.userPersona, channelBackupPath: node.settings.channelBackupPath, selCurrencyUnit: node.settings.currencyUnit, currencyUnits: [...CURRENCY_UNITS, node.settings.currencyUnit], fiatConversion: node.settings.fiatConversion, lnImplementation: node.lnImplementation, swapServerUrl: node.settings.swapServerUrl, boltzServerUrl: node.settings.boltzServerUrl, enableOffers: node.settings.enableOffers, enablePeerswap: node.settings.enablePeerswap };
|
||||
} else {
|
||||
selNode = { userPersona: node.settings.userPersona, channelBackupPath: node.settings.channelBackupPath, selCurrencyUnit: node.settings.currencyUnit, currencyUnits: CURRENCY_UNITS, fiatConversion: node.settings.fiatConversion, lnImplementation: node.lnImplementation, swapServerUrl: node.settings.swapServerUrl, boltzServerUrl: node.settings.boltzServerUrl, enableOffers: node.settings.enableOffers };
|
||||
selNode = { userPersona: node.settings.userPersona, channelBackupPath: node.settings.channelBackupPath, selCurrencyUnit: node.settings.currencyUnit, currencyUnits: CURRENCY_UNITS, fiatConversion: node.settings.fiatConversion, lnImplementation: node.lnImplementation, swapServerUrl: node.settings.swapServerUrl, boltzServerUrl: node.settings.boltzServerUrl, enableOffers: node.settings.enableOffers, enablePeerswap: node.settings.enablePeerswap };
|
||||
}
|
||||
this.sessionService.removeItem('lndUnlocked');
|
||||
this.sessionService.removeItem('clUnlocked');
|
||||
|
@ -44,6 +44,9 @@ export const RootReducer = createReducer(initRootState,
|
||||
case ServicesEnum.OFFERS:
|
||||
updatedSelNode.settings.enableOffers = payload.settings.enableOffers;
|
||||
break;
|
||||
case ServicesEnum.PEERSWAP:
|
||||
updatedSelNode.settings.enablePeerswap = payload.settings.enablePeerswap;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -9,12 +9,12 @@ import { ECLState } from '../eclair/store/ecl.state';
|
||||
export interface RootState {
|
||||
apiURL: string;
|
||||
apisCallStatus: ApiCallsListRoot;
|
||||
selNode: ConfigSettingsNode | null;
|
||||
selNode: ConfigSettingsNode | any;
|
||||
appConfig: RTLConfiguration;
|
||||
nodeData: GetInfoRoot;
|
||||
}
|
||||
|
||||
const initNodeSettings = { userPersona: 'OPERATOR', themeMode: 'DAY', themeColor: 'PURPLE', channelBackupPath: '', selCurrencyUnit: 'USD', fiatConversion: false, currencyUnits: ['Sats', 'BTC', 'USD'], bitcoindConfigPath: '', enableOffers: false };
|
||||
const initNodeSettings = { userPersona: 'OPERATOR', themeMode: 'DAY', themeColor: 'PURPLE', channelBackupPath: '', selCurrencyUnit: 'USD', fiatConversion: false, currencyUnits: ['Sats', 'BTC', 'USD'], bitcoindConfigPath: '', enableOffers: false, enablePeerswap: false };
|
||||
const initNodeAuthentication = { configPath: '', swapMacaroonPath: '', boltzMacaroonPath: '' };
|
||||
|
||||
export const initRootState: RootState = {
|
||||
|
Loading…
Reference in New Issue
Block a user