mirror of
https://github.com/mempool/mempool.git
synced 2025-02-24 14:50:52 +01:00
Parse & display liquidity ads on node page
This commit is contained in:
parent
010e9f2bb1
commit
c2ab0bc715
4 changed files with 151 additions and 14 deletions
31
frontend/src/app/lightning/node/liquidity-ad.ts
Normal file
31
frontend/src/app/lightning/node/liquidity-ad.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
export interface ILiquidityAd {
|
||||
funding_weight: number;
|
||||
lease_fee_basis: number; // lease fee rate in parts-per-thousandth
|
||||
lease_fee_base_sat: number; // fixed lease fee in sats
|
||||
channel_fee_max_rate: number; // max routing fee rate in parts-per-thousandth
|
||||
channel_fee_max_base: number; // max routing base fee in milli-sats
|
||||
compact_lease?: string;
|
||||
}
|
||||
|
||||
export function parseLiquidityAdHex(compact_lease: string): ILiquidityAd | false {
|
||||
if (!compact_lease || compact_lease.length < 20 || compact_lease.length > 28) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const liquidityAd: ILiquidityAd = {
|
||||
funding_weight: parseInt(compact_lease.slice(0, 4), 16),
|
||||
lease_fee_basis: parseInt(compact_lease.slice(4, 8), 16),
|
||||
channel_fee_max_rate: parseInt(compact_lease.slice(8, 12), 16),
|
||||
lease_fee_base_sat: parseInt(compact_lease.slice(12, 20), 16),
|
||||
channel_fee_max_base: compact_lease.length > 20 ? parseInt(compact_lease.slice(20), 16) : 0,
|
||||
}
|
||||
if (Object.values(liquidityAd).reduce((valid: boolean, value: number): boolean => (valid && !isNaN(value) && value >= 0), true)) {
|
||||
liquidityAd.compact_lease = compact_lease;
|
||||
return liquidityAd;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -127,19 +127,84 @@
|
|||
|
||||
<div *ngIf="hasDetails" [hidden]="!showDetails" id="details" class="details mt-3">
|
||||
<div class="box">
|
||||
<h5 class="mb-3" i18n="node.tlv.records">TLV extension records</h5>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr *ngFor="let recordItem of node.custom_records | keyvalue">
|
||||
<td class="tlv-type">{{ recordItem.key }}</td>
|
||||
<td class="tlv-payload">{{ recordItem.value }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<ng-template [ngIf]="liquidityAd">
|
||||
<div class="detail-section">
|
||||
<h5 class="mb-3" i18n="node.liquidity-ad">Liquidity ad</h5>
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.lease-fee-rate|Liquidity ad lease fee rate">Lease fee rate</td>
|
||||
<td>
|
||||
<span class="d-inline-block">
|
||||
{{ liquidityAd.lease_fee_basis !== null ? ((liquidityAd.lease_fee_basis * 1000) | amountShortener : 2 : undefined : true) : '-' }} <span class="symbol">ppm {{ liquidityAd.lease_fee_basis !== null ? '(' + (liquidityAd.lease_fee_basis / 10 | amountShortener : 2 : undefined : true) + '%)' : '' }}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.lease-base-fee">Lease base fee</td>
|
||||
<td>
|
||||
<app-sats [valueOverride]="liquidityAd.lease_fee_base_sat === null ? '- ' : undefined" [satoshis]="liquidityAd.lease_fee_base_sat"></app-sats>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.funding-weight">Funding weight</td>
|
||||
<td [innerHTML]="'‎' + (liquidityAd.funding_weight | wuBytes: 2)"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.channel-fee-rate|Liquidity ad channel fee rate">Channel fee rate</td>
|
||||
<td>
|
||||
<span class="d-inline-block">
|
||||
{{ liquidityAd.channel_fee_max_rate !== null ? ((liquidityAd.channel_fee_max_rate * 1000) | amountShortener : 2 : undefined : true) : '-' }} <span class="symbol">ppm {{ liquidityAd.channel_fee_max_rate !== null ? '(' + (liquidityAd.channel_fee_max_rate / 10 | amountShortener : 2 : undefined : true) + '%)' : '' }}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.channel-base-fee">Channel base fee</td>
|
||||
<td>
|
||||
<span *ngIf="liquidityAd.channel_fee_max_base !== null">
|
||||
{{ liquidityAd.channel_fee_max_base | amountShortener : 0 }}
|
||||
<span class="symbol" i18n="shared.m-sats">mSats</span>
|
||||
</span>
|
||||
<span *ngIf="liquidityAd.channel_fee_max_base === null">
|
||||
-
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" i18n="liquidity-ad.compact-lease">Compact lease</td>
|
||||
<td class="compact-lease">{{ liquidityAd.compact_lease }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="tlvRecords?.length">
|
||||
<div class="detail-section">
|
||||
<h5 class="mb-3" i18n="node.tlv.records">TLV extension records</h5>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr *ngFor="let recordItem of tlvRecords">
|
||||
<td class="tlv-type">{{ recordItem.type }}</td>
|
||||
<td class="tlv-payload">{{ recordItem.payload }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -73,17 +73,31 @@ app-fiat {
|
|||
};
|
||||
}
|
||||
|
||||
.details tbody {
|
||||
font-size: 12px;
|
||||
.details {
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 1.5rem;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tlv-type {
|
||||
font-size: 12px;
|
||||
color: #ffffff66;
|
||||
}
|
||||
|
||||
.tlv-payload {
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
.compact-lease {
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@ import { catchError, map, switchMap, tap } from 'rxjs/operators';
|
|||
import { SeoService } from '../../services/seo.service';
|
||||
import { LightningApiService } from '../lightning-api.service';
|
||||
import { GeolocationData } from '../../shared/components/geolocation/geolocation.component';
|
||||
import { ILiquidityAd, parseLiquidityAdHex } from './liquidity-ad';
|
||||
|
||||
interface CustomRecord {
|
||||
type: string;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-node',
|
||||
|
@ -26,6 +32,8 @@ export class NodeComponent implements OnInit {
|
|||
torSocketCount = 0;
|
||||
hasDetails = false;
|
||||
showDetails = false;
|
||||
liquidityAd: ILiquidityAd;
|
||||
tlvRecords: CustomRecord[];
|
||||
|
||||
constructor(
|
||||
private lightningApiService: LightningApiService,
|
||||
|
@ -38,6 +46,8 @@ export class NodeComponent implements OnInit {
|
|||
.pipe(
|
||||
switchMap((params: ParamMap) => {
|
||||
this.publicKey = params.get('public_key');
|
||||
this.tlvRecords = [];
|
||||
this.liquidityAd = null;
|
||||
return this.lightningApiService.getNode$(params.get('public_key'));
|
||||
}),
|
||||
map((node) => {
|
||||
|
@ -83,6 +93,23 @@ export class NodeComponent implements OnInit {
|
|||
}),
|
||||
tap((node) => {
|
||||
this.hasDetails = Object.keys(node.custom_records).length > 0;
|
||||
for (const [type, payload] of Object.entries(node.custom_records)) {
|
||||
if (typeof payload !== 'string') {
|
||||
break;
|
||||
}
|
||||
|
||||
let parsed = false;
|
||||
if (type === '1') {
|
||||
const ad = parseLiquidityAdHex(payload);
|
||||
if (ad) {
|
||||
parsed = true;
|
||||
this.liquidityAd = ad;
|
||||
}
|
||||
}
|
||||
if (!parsed) {
|
||||
this.tlvRecords.push({ type, payload });
|
||||
}
|
||||
}
|
||||
}),
|
||||
catchError(err => {
|
||||
this.error = err;
|
||||
|
|
Loading…
Add table
Reference in a new issue