Channel pagination
This commit is contained in:
		
							parent
							
								
									7f7fa2eb6a
								
							
						
					
					
						commit
						6e2b1d633b
					
				@ -34,7 +34,7 @@ export class AddressLabelsComponent implements OnChanges {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleChannel() {
 | 
					  handleChannel() {
 | 
				
			||||||
    this.label = `Channel open: ${this.channel.alias_left} <> ${this.channel.alias_right}`;
 | 
					    this.label = `Channel open: ${this.channel.node_left.alias} <> ${this.channel.node_right.alias}`;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleVin() {
 | 
					  handleVin() {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ChannelBoxComponent } from './channel-box.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('ChannelBoxComponent', () => {
 | 
				
			||||||
 | 
					  let component: ChannelBoxComponent;
 | 
				
			||||||
 | 
					  let fixture: ComponentFixture<ChannelBoxComponent>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(async () => {
 | 
				
			||||||
 | 
					    await TestBed.configureTestingModule({
 | 
				
			||||||
 | 
					      declarations: [ ChannelBoxComponent ]
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .compileComponents();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    fixture = TestBed.createComponent(ChannelBoxComponent);
 | 
				
			||||||
 | 
					    component = fixture.componentInstance;
 | 
				
			||||||
 | 
					    fixture.detectChanges();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should create', () => {
 | 
				
			||||||
 | 
					    expect(component).toBeTruthy();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -1,44 +1,39 @@
 | 
				
			|||||||
<div>
 | 
					<div *ngIf="channels$ | async as response; else skeleton">
 | 
				
			||||||
 | 
					  <h2 class="float-left">Channels ({{ response.totalItems }})</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <form [formGroup]="channelStatusForm" class="formRadioGroup float-right">
 | 
				
			||||||
 | 
					    <div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="status">
 | 
				
			||||||
 | 
					      <label ngbButtonLabel class="btn-primary btn-sm">
 | 
				
			||||||
 | 
					        <input ngbButton type="radio" [value]="'open'" fragment="open"> Open
 | 
				
			||||||
 | 
					      </label>
 | 
				
			||||||
 | 
					      <label ngbButtonLabel class="btn-primary btn-sm">
 | 
				
			||||||
 | 
					        <input ngbButton type="radio" [value]="'closed'" fragment="closed"> Closed
 | 
				
			||||||
 | 
					      </label>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <table class="table table-borderless">
 | 
					  <table class="table table-borderless">
 | 
				
			||||||
    <thead>
 | 
					    <ng-container *ngTemplateOutlet="tableHeader"></ng-container>
 | 
				
			||||||
      <th class="alias text-left" i18n="nodes.alias">Node Alias</th>
 | 
					    <tbody>
 | 
				
			||||||
      <th class="alias text-left d-none d-md-table-cell" i18n="channels.transaction"> </th>
 | 
					      <tr *ngFor="let channel of response.channels; let i = index;">
 | 
				
			||||||
      <th class="alias text-left d-none d-md-table-cell" i18n="nodes.alias">Status</th>
 | 
					 | 
				
			||||||
      <th class="channels text-left d-none d-md-table-cell" i18n="channels.rate">Fee Rate</th>
 | 
					 | 
				
			||||||
      <th class="capacity text-right d-none d-md-table-cell" i18n="nodes.capacity">Capacity</th>
 | 
					 | 
				
			||||||
      <th class="capacity text-left" i18n="channels.id">Channel ID</th>
 | 
					 | 
				
			||||||
    </thead>
 | 
					 | 
				
			||||||
    <tbody *ngIf="channels$ | async as channels; else skeleton">
 | 
					 | 
				
			||||||
      <tr *ngFor="let channel of channels; let i = index;">
 | 
					 | 
				
			||||||
        <ng-container *ngTemplateOutlet="tableTemplate; context: { $implicit: channel, node: channel.node_left.public_key === publicKey ? channel.node_right : channel.node_left }"></ng-container>
 | 
					        <ng-container *ngTemplateOutlet="tableTemplate; context: { $implicit: channel, node: channel.node_left.public_key === publicKey ? channel.node_right : channel.node_left }"></ng-container>
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
    </tbody>
 | 
					    </tbody>
 | 
				
			||||||
    <ng-template #skeleton>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
 | 
					 | 
				
			||||||
          <td class="alias text-left" style="width: 370px;">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td class="alias text-left">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td class="capacity text-left d-none d-md-table-cell">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td class="channels text-left d-none d-md-table-cell">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td class="channels text-right d-none d-md-table-cell">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td class="channels text-left">
 | 
					 | 
				
			||||||
            <span class="skeleton-loader"></span>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </ng-template>
 | 
					 | 
				
			||||||
  </table>
 | 
					  </table>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  <ngb-pagination class="pagination-container float-right" [size]="paginationSize" [collectionSize]="response.totalItems" [rotate]="true" [pageSize]="itemsPerPage" [(page)]="page" (pageChange)="pageChange(page)" [maxSize]="paginationMaxSize" [boundaryLinks]="true" [ellipses]="false"></ngb-pagination>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					<ng-template #tableHeader>
 | 
				
			||||||
 | 
					  <thead>
 | 
				
			||||||
 | 
					    <th class="alias text-left" i18n="nodes.alias">Node Alias</th>
 | 
				
			||||||
 | 
					    <th class="alias text-left d-none d-md-table-cell" i18n="channels.transaction"> </th>
 | 
				
			||||||
 | 
					    <th class="alias text-left d-none d-md-table-cell" i18n="nodes.alias">Status</th>
 | 
				
			||||||
 | 
					    <th class="channels text-left d-none d-md-table-cell" i18n="channels.rate">Fee Rate</th>
 | 
				
			||||||
 | 
					    <th class="capacity text-right d-none d-md-table-cell" i18n="nodes.capacity">Capacity</th>
 | 
				
			||||||
 | 
					    <th class="capacity text-right" i18n="channels.id">Channel ID</th>
 | 
				
			||||||
 | 
					  </thead>
 | 
				
			||||||
 | 
					</ng-template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<ng-template #tableTemplate let-channel let-node="node">
 | 
					<ng-template #tableTemplate let-channel let-node="node">
 | 
				
			||||||
  <td class="alias text-left">
 | 
					  <td class="alias text-left">
 | 
				
			||||||
@ -50,7 +45,7 @@
 | 
				
			|||||||
      <app-clipboard [text]="node.public_key" size="small"></app-clipboard>
 | 
					      <app-clipboard [text]="node.public_key" size="small"></app-clipboard>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </td>
 | 
					  </td>
 | 
				
			||||||
  <td class="alias text-left">
 | 
					  <td class="alias text-left d-none d-md-table-cell">
 | 
				
			||||||
    <div class="second-line">{{ node.channels }} channels</div>
 | 
					    <div class="second-line">{{ node.channels }} channels</div>
 | 
				
			||||||
    <div class="second-line"><app-amount [satoshis]="node.capacity" digitsInfo="1.2-2"></app-amount></div>
 | 
					    <div class="second-line"><app-amount [satoshis]="node.capacity" digitsInfo="1.2-2"></app-amount></div>
 | 
				
			||||||
  </td>
 | 
					  </td>
 | 
				
			||||||
@ -65,7 +60,37 @@
 | 
				
			|||||||
  <td class="capacity text-right d-none d-md-table-cell">
 | 
					  <td class="capacity text-right d-none d-md-table-cell">
 | 
				
			||||||
    <app-amount [satoshis]="channel.capacity" digitsInfo="1.2-2"></app-amount>
 | 
					    <app-amount [satoshis]="channel.capacity" digitsInfo="1.2-2"></app-amount>
 | 
				
			||||||
  </td>
 | 
					  </td>
 | 
				
			||||||
  <td class="capacity text-left">
 | 
					  <td class="capacity text-right">
 | 
				
			||||||
    <a [routerLink]="['/lightning/channel' | relativeUrl, channel.id]">{{ channel.short_id }}</a>
 | 
					    <a [routerLink]="['/lightning/channel' | relativeUrl, channel.id]">{{ channel.short_id }}</a>
 | 
				
			||||||
   </td>
 | 
					   </td>
 | 
				
			||||||
</ng-template>
 | 
					</ng-template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ng-template #skeleton>
 | 
				
			||||||
 | 
					  <h2 class="float-left">Channels</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <table class="table table-borderless">
 | 
				
			||||||
 | 
					  <ng-container *ngTemplateOutlet="tableHeader"></ng-container>
 | 
				
			||||||
 | 
					  <tbody>
 | 
				
			||||||
 | 
					    <tr *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
 | 
				
			||||||
 | 
					      <td class="alias text-left" style="width: 370px;">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					      <td class="alias text-left">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					      <td class="capacity text-left d-none d-md-table-cell">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					      <td class="channels text-left d-none d-md-table-cell">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					      <td class="channels text-right d-none d-md-table-cell">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					      <td class="channels text-left">
 | 
				
			||||||
 | 
					        <span class="skeleton-loader"></span>
 | 
				
			||||||
 | 
					      </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					  </tbody>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					</ng-template>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit } from '@angular/core';
 | 
				
			||||||
import { Observable } from 'rxjs';
 | 
					import { FormBuilder, FormGroup } from '@angular/forms';
 | 
				
			||||||
 | 
					import { BehaviorSubject, combineLatest, merge, Observable, of } from 'rxjs';
 | 
				
			||||||
 | 
					import { map, startWith, switchMap } from 'rxjs/operators';
 | 
				
			||||||
import { LightningApiService } from '../lightning-api.service';
 | 
					import { LightningApiService } from '../lightning-api.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@ -8,16 +10,53 @@ import { LightningApiService } from '../lightning-api.service';
 | 
				
			|||||||
  styleUrls: ['./channels-list.component.scss'],
 | 
					  styleUrls: ['./channels-list.component.scss'],
 | 
				
			||||||
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
					  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class ChannelsListComponent implements OnChanges {
 | 
					export class ChannelsListComponent implements OnInit, OnChanges {
 | 
				
			||||||
  @Input() publicKey: string;
 | 
					  @Input() publicKey: string;
 | 
				
			||||||
  channels$: Observable<any[]>;
 | 
					  channels$: Observable<any>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // @ts-ignore
 | 
				
			||||||
 | 
					  paginationSize: 'sm' | 'lg' = 'md';
 | 
				
			||||||
 | 
					  paginationMaxSize = 10;
 | 
				
			||||||
 | 
					  itemsPerPage = 25;
 | 
				
			||||||
 | 
					  page = 1;
 | 
				
			||||||
 | 
					  channelsPage$ = new BehaviorSubject<number>(1);
 | 
				
			||||||
 | 
					  channelStatusForm: FormGroup;
 | 
				
			||||||
 | 
					  defaultStatus = 'open';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private lightningApiService: LightningApiService,
 | 
					    private lightningApiService: LightningApiService,
 | 
				
			||||||
  ) { }
 | 
					    private formBuilder: FormBuilder,
 | 
				
			||||||
 | 
					  ) { 
 | 
				
			||||||
 | 
					    this.channelStatusForm = this.formBuilder.group({
 | 
				
			||||||
 | 
					      status: [this.defaultStatus],
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit() {
 | 
				
			||||||
 | 
					    if (document.body.clientWidth < 670) {
 | 
				
			||||||
 | 
					      this.paginationSize = 'sm';
 | 
				
			||||||
 | 
					      this.paginationMaxSize = 3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnChanges(): void {
 | 
					  ngOnChanges(): void {
 | 
				
			||||||
    this.channels$ = this.lightningApiService.getChannelsByNodeId$(this.publicKey);
 | 
					    this.channels$ = combineLatest([
 | 
				
			||||||
 | 
					      this.channelsPage$,
 | 
				
			||||||
 | 
					      this.channelStatusForm.get('status').valueChanges.pipe(startWith(this.defaultStatus))
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					    .pipe(
 | 
				
			||||||
 | 
					      switchMap(([page, status]) =>this.lightningApiService.getChannelsByNodeId$(this.publicKey, (page -1) * this.itemsPerPage, status)),
 | 
				
			||||||
 | 
					      map((response) => {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          channels: response.body,
 | 
				
			||||||
 | 
					          totalItems: parseInt(response.headers.get('x-total-count'), 10)
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pageChange(page: number) {
 | 
				
			||||||
 | 
					    this.channelsPage$.next(page);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,12 +20,14 @@ export class LightningApiService {
 | 
				
			|||||||
    return this.httpClient.get<any>(API_BASE_URL + '/channels/' + shortId);
 | 
					    return this.httpClient.get<any>(API_BASE_URL + '/channels/' + shortId);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getChannelsByNodeId$(publicKey: string): Observable<any> {
 | 
					  getChannelsByNodeId$(publicKey: string, index: number = 0, status = 'open'): Observable<any> {
 | 
				
			||||||
    let params = new HttpParams()
 | 
					    let params = new HttpParams()
 | 
				
			||||||
      .set('public_key', publicKey)
 | 
					      .set('public_key', publicKey)
 | 
				
			||||||
 | 
					      .set('index', index)
 | 
				
			||||||
 | 
					      .set('status', status)
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return this.httpClient.get<any>(API_BASE_URL + '/channels', { params });
 | 
					    return this.httpClient.get<any>(API_BASE_URL + '/channels', { params, observe: 'response' });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getLatestStatistics$(): Observable<any> {
 | 
					  getLatestStatistics$(): Observable<any> {
 | 
				
			||||||
 | 
				
			|||||||
@ -88,7 +88,6 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    <br>
 | 
					    <br>
 | 
				
			||||||
    <h2>Channels</h2>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <app-channels-list [publicKey]="node.public_key"></app-channels-list>
 | 
					    <app-channels-list [publicKey]="node.public_key"></app-channels-list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -73,10 +73,16 @@ class ChannelsApi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async $getChannelsForNode(public_key: string): Promise<any> {
 | 
					  public async $getChannelsForNode(public_key: string, index: number, length: number, status: string): Promise<any[]> {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const query = `SELECT n1.alias AS alias_left, n2.alias AS alias_right, channels.*, ns1.channels AS channels_left, ns1.capacity AS capacity_left, ns2.channels AS channels_right, ns2.capacity AS capacity_right FROM channels LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key LEFT JOIN node_stats AS ns1 ON ns1.public_key = channels.node1_public_key LEFT JOIN node_stats AS ns2 ON ns2.public_key = channels.node2_public_key WHERE (ns1.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node1_public_key) AND ns2.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node2_public_key)) AND (node1_public_key = ? OR node2_public_key = ?) ORDER BY channels.capacity DESC`;
 | 
					      // Default active and inactive channels
 | 
				
			||||||
      const [rows]: any = await DB.query(query, [public_key, public_key]);
 | 
					      let statusQuery = '< 2';
 | 
				
			||||||
 | 
					      // Closed channels only
 | 
				
			||||||
 | 
					      if (status === 'closed') {
 | 
				
			||||||
 | 
					        statusQuery = '= 2';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const query = `SELECT n1.alias AS alias_left, n2.alias AS alias_right, channels.*, ns1.channels AS channels_left, ns1.capacity AS capacity_left, ns2.channels AS channels_right, ns2.capacity AS capacity_right FROM channels LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key LEFT JOIN node_stats AS ns1 ON ns1.public_key = channels.node1_public_key LEFT JOIN node_stats AS ns2 ON ns2.public_key = channels.node2_public_key WHERE (ns1.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node1_public_key) AND ns2.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node2_public_key)) AND (node1_public_key = ? OR node2_public_key = ?) AND status ${statusQuery} ORDER BY channels.capacity DESC LIMIT ?, ?`;
 | 
				
			||||||
 | 
					      const [rows]: any = await DB.query(query, [public_key, public_key, index, length]);
 | 
				
			||||||
      const channels = rows.map((row) => this.convertChannel(row));
 | 
					      const channels = rows.map((row) => this.convertChannel(row));
 | 
				
			||||||
      return channels;
 | 
					      return channels;
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
@ -85,13 +91,30 @@ class ChannelsApi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async $getChannelsCountForNode(public_key: string, status: string): Promise<any> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      // Default active and inactive channels
 | 
				
			||||||
 | 
					      let statusQuery = '< 2';
 | 
				
			||||||
 | 
					      // Closed channels only
 | 
				
			||||||
 | 
					      if (status === 'closed') {
 | 
				
			||||||
 | 
					        statusQuery = '= 2';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      const query = `SELECT COUNT(*) AS count FROM channels WHERE (node1_public_key = ? OR node2_public_key = ?) AND status ${statusQuery}`;
 | 
				
			||||||
 | 
					      const [rows]: any = await DB.query(query, [public_key, public_key]);
 | 
				
			||||||
 | 
					      return rows[0]['count'];
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      logger.err('$getChannelsForNode error: ' + (e instanceof Error ? e.message : e));
 | 
				
			||||||
 | 
					      throw e;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private convertChannel(channel: any): any {
 | 
					  private convertChannel(channel: any): any {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      'id': channel.id,
 | 
					      'id': channel.id,
 | 
				
			||||||
      'short_id': channel.short_id,
 | 
					      'short_id': channel.short_id,
 | 
				
			||||||
      'capacity': channel.capacity,
 | 
					      'capacity': channel.capacity,
 | 
				
			||||||
      'transaction_id': channel.transaction_id,
 | 
					      'transaction_id': channel.transaction_id,
 | 
				
			||||||
      'transaction_vout': channel.void,
 | 
					      'transaction_vout': channel.transaction_vout,
 | 
				
			||||||
      'updated_at': channel.updated_at,
 | 
					      'updated_at': channel.updated_at,
 | 
				
			||||||
      'created': channel.created,
 | 
					      'created': channel.created,
 | 
				
			||||||
      'status': channel.status,
 | 
					      'status': channel.status,
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ class ChannelsRoutes {
 | 
				
			|||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/txids', this.$getChannelsByTransactionIds)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/txids', this.$getChannelsByTransactionIds)
 | 
				
			||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/search/:search', this.$searchChannelsById)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/search/:search', this.$searchChannelsById)
 | 
				
			||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/:short_id', this.$getChannel)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'channels/:short_id', this.$getChannel)
 | 
				
			||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'channels', this.$getChannels)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'channels', this.$getChannelsForNode)
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,13 +36,18 @@ class ChannelsRoutes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private async $getChannels(req: Request, res: Response) {
 | 
					  private async $getChannelsForNode(req: Request, res: Response) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if (typeof req.query.public_key !== 'string') {
 | 
					      if (typeof req.query.public_key !== 'string') {
 | 
				
			||||||
        res.status(501).send('Missing parameter: public_key');
 | 
					        res.status(501).send('Missing parameter: public_key');
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      const channels = await channelsApi.$getChannelsForNode(req.query.public_key);
 | 
					      const index = parseInt(typeof req.query.index === 'string' ? req.query.index : '0', 10) || 0;
 | 
				
			||||||
 | 
					      const status: string = typeof req.query.status === 'string' ? req.query.status : '';
 | 
				
			||||||
 | 
					      const length = 25;
 | 
				
			||||||
 | 
					      const channels = await channelsApi.$getChannelsForNode(req.query.public_key, index, length, status);
 | 
				
			||||||
 | 
					      const channelsCount = await channelsApi.$getChannelsCountForNode(req.query.public_key, status);
 | 
				
			||||||
 | 
					      res.header('X-Total-Count', channelsCount.toString());
 | 
				
			||||||
      res.json(channels);
 | 
					      res.json(channels);
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
					      res.status(500).send(e instanceof Error ? e.message : e);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user