Assets support WIP

refs #37
This commit is contained in:
softsimon
2020-05-02 12:36:35 +07:00
parent b2d2fd225c
commit 11b1d9bbd3
12 changed files with 110 additions and 41 deletions

View File

@@ -2,7 +2,7 @@
<span>{{ conversions.USD * (satoshis / 100000000) | currency:'USD':'symbol':'1.2-2' }}</span>
</ng-container>
<ng-template #viewFiatVin>
<ng-template [ngIf]="network === 'liquid' && !satoshis" [ngIfElse]="default">
<ng-template [ngIf]="network === 'liquid' && satoshis === undefined" [ngIfElse]="default">
Confidential
</ng-template>
<ng-template #default>

View File

@@ -9,7 +9,7 @@
<div class="clearfix"></div>
<ng-template [ngIf]="!isLoadingAsset && !error">
<ng-template [ngIf]="!isLoadingAsset && !error && assetContract">
<div class="box">
<div class="row">
@@ -18,15 +18,15 @@
<tbody>
<tr>
<td>Name</td>
<td>{{ asset.name }} ({{ asset.ticker }})</td>
<td>{{ assetContract[2] }} ({{ assetContract[1] }})</td>
</tr>
<tr>
<td>Precision</td>
<td>{{ asset.precision }}</td>
<td>{{ assetContract[3] }}</td>
</tr>
<tr>
<td>Issuer</td>
<td><a target="_blank" href="{{ 'http://' + asset.contract.entity.domain }}">{{ asset.contract.entity.domain }}</a></td>
<td><a target="_blank" href="{{ 'http://' + assetContract[0] }}">{{ assetContract[0] }}</a></td>
</tr>
<tr>
<td>Issuance tx</td>
@@ -40,15 +40,15 @@
<tbody>
<tr>
<td>Circulating amount</td>
<td>{{ (asset.chain_stats.issued_amount - asset.chain_stats.burned_amount) / 100000000 | number: '1.0-' + asset.precision }}</td>
<td>{{ (asset.chain_stats.issued_amount - asset.chain_stats.burned_amount) / 100000000 | number: '1.0-' + assetContract[3] }}</td>
</tr>
<tr>
<td>Issued amount</td>
<td>{{ asset.chain_stats.issued_amount / 100000000 | number: '1.0-' + asset.precision }}</td>
<td>{{ asset.chain_stats.issued_amount / 100000000 | number: '1.0-' + assetContract[3] }}</td>
</tr>
<tr>
<td>Burned amount</td>
<td>{{ asset.chain_stats.burned_amount / 100000000 | number: '1.0-' + asset.precision }}</td>
<td>{{ asset.chain_stats.burned_amount / 100000000 | number: '1.0-' + assetContract[3] }}</td>
</tr>
</tbody>
</table>

View File

@@ -1,15 +1,16 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { ElectrsApiService } from '../../services/electrs-api.service';
import { switchMap, filter, catchError } from 'rxjs/operators';
import { switchMap, filter, catchError, take } from 'rxjs/operators';
import { Asset, Transaction } from '../../interfaces/electrs.interface';
import { WebsocketService } from 'src/app/services/websocket.service';
import { StateService } from 'src/app/services/state.service';
import { AudioService } from 'src/app/services/audio.service';
import { ApiService } from 'src/app/services/api.service';
import { of, merge, Subscription } from 'rxjs';
import { of, merge, Subscription, combineLatest } from 'rxjs';
import { SeoService } from 'src/app/services/seo.service';
import { environment } from 'src/environments/environment';
import { AssetsService } from 'src/app/services/assets.service';
@Component({
selector: 'app-asset',
@@ -20,6 +21,7 @@ export class AssetComponent implements OnInit, OnDestroy {
network = environment.network;
asset: Asset;
assetContract: any;
assetString: string;
isLoadingAsset = true;
transactions: Transaction[];
@@ -45,6 +47,7 @@ export class AssetComponent implements OnInit, OnDestroy {
private audioService: AudioService,
private apiService: ApiService,
private seoService: SeoService,
private assetsService: AssetsService,
) { }
ngOnInit() {
@@ -57,6 +60,7 @@ export class AssetComponent implements OnInit, OnDestroy {
this.isLoadingAsset = true;
this.loadedConfirmedTxCount = 0;
this.asset = null;
this.assetContract = null;
this.isLoadingTransactions = true;
this.transactions = null;
document.body.scrollTo(0, 0);
@@ -69,22 +73,27 @@ export class AssetComponent implements OnInit, OnDestroy {
.pipe(filter((state) => state === 2 && this.transactions && this.transactions.length > 0))
)
.pipe(
switchMap(() => this.electrsApiService.getAsset$(this.assetString)
switchMap(() => {
return combineLatest([this.electrsApiService.getAsset$(this.assetString)
.pipe(
catchError((err) => {
this.isLoadingAsset = false;
this.error = err;
console.log(err);
return of(null);
})
), this.assetsService.assetsMinimal$])
.pipe(
catchError((err) => {
this.isLoadingAsset = false;
this.error = err;
console.log(err);
return of(null);
})
)
)
take(1)
);
})
);
})
)
.pipe(
switchMap((asset: Asset) => {
switchMap(([asset, assetsData]) => {
this.asset = asset;
this.assetContract = assetsData[this.asset.asset_id];
this.updateChainStats();
this.websocketService.startTrackAsset(asset.asset_id);
this.isLoadingAsset = false;

View File

@@ -1,6 +1,8 @@
import { Component, OnInit, ChangeDetectionStrategy, EventEmitter, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';
import { AssetsService } from 'src/app/services/assets.service';
@Component({
selector: 'app-search-form',
@@ -9,6 +11,9 @@ import { Router } from '@angular/router';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchFormComponent implements OnInit {
network = environment.network;
assets: object;
searchForm: FormGroup;
@Output() searchTriggered = new EventEmitter();
@@ -19,12 +24,17 @@ export class SearchFormComponent implements OnInit {
constructor(
private formBuilder: FormBuilder,
private router: Router,
private assetsService: AssetsService,
) { }
ngOnInit() {
this.searchForm = this.formBuilder.group({
searchText: ['', Validators.required],
});
this.assetsService.assetsMinimal$
.subscribe((assets) => {
this.assets = assets;
});
}
search() {
@@ -37,7 +47,11 @@ export class SearchFormComponent implements OnInit {
this.router.navigate(['/block/', searchText]);
this.searchTriggered.emit();
} else if (this.regexTransaction.test(searchText)) {
this.router.navigate(['/tx/', searchText]);
if (this.network === 'liquid' && this.assets[searchText]) {
this.router.navigate(['/asset/', searchText]);
} else {
this.router.navigate(['/tx/', searchText]);
}
this.searchTriggered.emit();
} else {
return;

View File

@@ -11,7 +11,7 @@
.position-container {
position: absolute;
left: 50%;
bottom: 150px;
bottom: 170px;
}
.chart-holder {
@@ -37,7 +37,7 @@
@media (min-width: 1920px) {
.position-container {
transform: scale(1.3);
bottom: 190px;
bottom: 210px;
}
.chart-holder {
height: calc(100% - 280px);

View File

@@ -70,10 +70,22 @@
</ng-template>
</td>
<td class="text-right nowrap">
<app-amount [satoshis]="vout.value"></app-amount>
<ng-template [ngIf]="vout.asset && vout.scriptpubkey_type === 'op_return' && vout.asset !== nativeAssetId" [ngIfElse]="defaultOutput">
<div *ngIf="assetsMinimal && assetsMinimal[vout.asset]">
{{ vout.value / 100000000 | number: '1.0-' + assetsMinimal[vout.asset][3] }} {{ assetsMinimal[vout.asset][1] }}
<br>
{{ assetsMinimal[vout.asset][0] }}
<br>
<a [routerLink]="['/asset/', vout.asset]">{{ vout.asset | shortenString : 13 }}</a>
<br><br>
</div>
</ng-template>
<ng-template #defaultOutput>
<app-amount [satoshis]="vout.value"></app-amount>
</ng-template>
</td>
<td class="pl-1 arrow-td">
<i *ngIf="!outspends[i]; else outspend" class="arrow grey"></i>
<i *ngIf="!outspends[i] || vout.scriptpubkey_type === 'op_return' || vout.scriptpubkey_type === 'fee' ; else outspend" class="arrow grey"></i>
<ng-template #outspend>
<i *ngIf="!outspends[i][vindex] || !outspends[i][vindex].spent; else spent" class="arrow green"></i>
<ng-template #spent>
@@ -97,7 +109,10 @@
&nbsp;
</span>
<button type="button" class="btn btn-sm btn-primary mt-3" (click)="switchCurrency()">
<app-amount [satoshis]="getTotalTxOutput(tx)"></app-amount>
<ng-template [ngIf]="network === 'liquid'" [ngIfElse]="defaultAmount">Confidential</ng-template>
<ng-template #defaultAmount>
<app-amount [satoshis]="getTotalTxOutput(tx)"></app-amount>
</ng-template>
</button>
</td>
</tr>

View File

@@ -3,6 +3,8 @@ import { StateService } from '../../services/state.service';
import { Observable, forkJoin } from 'rxjs';
import { Block, Outspend, Transaction } from '../../interfaces/electrs.interface';
import { ElectrsApiService } from '../../services/electrs-api.service';
import { environment } from 'src/environments/environment';
import { AssetsService } from 'src/app/services/assets.service';
@Component({
selector: 'app-transactions-list',
@@ -11,6 +13,9 @@ import { ElectrsApiService } from '../../services/electrs-api.service';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TransactionsListComponent implements OnInit, OnChanges {
network = environment.network;
nativeAssetId = environment.nativeAssetId;
@Input() transactions: Transaction[];
@Input() showConfirmations = false;
@Input() transactionPage = false;
@@ -19,15 +24,20 @@ export class TransactionsListComponent implements OnInit, OnChanges {
latestBlock$: Observable<Block>;
outspends: Outspend[] = [];
assetsMinimal: any;
constructor(
private stateService: StateService,
private electrsApiService: ElectrsApiService,
private assetsService: AssetsService,
private ref: ChangeDetectorRef,
) { }
ngOnInit() {
this.latestBlock$ = this.stateService.blocks$;
this.assetsService.assetsMinimal$.subscribe((assets) => {
this.assetsMinimal = assets;
});
}
ngOnChanges() {
@@ -66,6 +76,9 @@ export class TransactionsListComponent implements OnInit, OnChanges {
}
switchCurrency() {
if (this.network === 'liquid') {
return;
}
const oldvalue = !this.stateService.viewFiat$.value;
this.stateService.viewFiat$.next(oldvalue);
}