...
 
Commits (8)
......@@ -46,7 +46,7 @@
{{ hoverInfo.value | number: '1.3-3' }} ETH
</ng-template>
<ng-template ngSwitchCase="tokens">
{{ hoverInfo.value | number: '1.1-3' }} Tokens
{{ hoverInfo.value | number: '1.1-3' }} tokens
</ng-template>
<ng-template ngSwitchDefault>
{{ hoverInfo.value | number: '1.0-3' }} {{ rawData?.unit }}
......
......@@ -15,6 +15,15 @@
*ngIf="tab.value || tab.value === 0"
[ngSwitch]="tab?.unit"
>
<ng-template ngSwitchCase="tokens">
{{ tab.value | token: 18 | number: '1.0-3' }}
</ng-template>
<ng-template ngSwitchCase="eth">
{{ tab.value | token: 18 | number: '1.0-3' }}
</ng-template>
<ng-template ngSwitchCase="btc">
{{ tab.value | token: 18 | number: '1.0-3' }}
</ng-template>
<ng-template ngSwitchCase="number">
{{ tab.value | number }}
</ng-template>
......
......@@ -58,7 +58,7 @@ button {
}
20% {
opacity: 1;
transform: scale(1.05);
transform: scale(1.03);
}
100% {
opacity: 0.2;
......
import { Component, OnInit, Input } from '@angular/core';
import { Component, Input } from '@angular/core';
@Component({
selector: 'm-shadowboxSubmitButton',
templateUrl: './shadowbox-submit-button.component.html',
})
export class ShadowboxSubmitButtonComponent implements OnInit {
export class ShadowboxSubmitButtonComponent {
@Input() saveStatus: string = 'unsaved';
@Input() disabled: boolean = false;
constructor() {}
ngOnInit() {}
constructor() {}
}
<m-pageLayout [menu]="menu">
<!-- TODOOOJM uncomment me -->
<!-- <div class="m-analyticsDashboard" *ngIf="ready$ | async" m-pageLayout__main> -->
<div class="m-analyticsDashboard" m-pageLayout__main>
<div class="m-analyticsDashboard" *ngIf="ready$ | async" m-pageLayout__main>
<m-dashboardLayout>
<ng-container m-dashboardLayout__header>
<div>
......
import { Component, OnInit } from '@angular/core';
import { Component, Input } from '@angular/core';
@Component({
selector: 'm-walletActionButton',
templateUrl: './action-button.component.html',
})
export class WalletActionButtonComponent implements OnInit {
export class WalletActionButtonComponent {
@Input() disabled: boolean = false;
constructor() {}
ngOnInit() {}
}
<ng-container *ngIf="!inProgress; else loading">
<div class="m-walletBalance--tokens__equationWrapper">
<div class="m-walletBalance--tokens__equationLeft">
<div class="m-walletBalance--tokens__balanceWrapper--total">
<div class="m-walletBalance--tokens__balanceTitle">Token Balance</div>
<div class="m-walletBalance--tokens__balanceValWrapper">
<span class="m-walletBalance--tokens__balanceVal--int">{{
tokenBalance.int | number
}}</span
><span
class="m-walletBalance--tokens__balanceVal--frac"
*ngIf="tokenBalance.frac"
>.{{ tokenBalance.frac | token: 15 | number: '3.0-0' }}</span
>
</div>
</div>
<!-- <ng-container *ngTemplateOutlet="buyTokens"></ng-container> -->
<a class="m-walletBalance--tokens__buyButtonWrapper" routerLink="/tokens"
><m-shadowboxSubmitButton
[disabled]="!session.getLoggedInUser().rewards"
>Buy tokens</m-shadowboxSubmitButton
></a
>
</div>
<div class="m-walletBalance--tokens__equationSymbol">=</div>
<div class="m-walletBalance--tokens__balanceWrapper--subtotal">
<div class="m-walletBalance--tokens__balanceTitle">
Off-Chain<m-tooltip icon="help"
>Store tokens on our servers for quicker transaction times and no
fees</m-tooltip
>
</div>
<div class="m-walletBalance--tokens__balanceValWrapper">
<span class="m-walletBalance--tokens__balanceVal--int">{{
offchainBalance.int | number
}}</span
><span
class="m-walletBalance--tokens__balanceVal--frac"
*ngIf="offchainBalance.frac"
>.{{ offchainBalance.frac | token: 15 | number: '3.0-0' }}</span
>
tokens
</div>
</div>
<div class="m-walletBalance--tokens__equationSymbol">+</div>
<div class="m-walletBalance--tokens__balanceWrapper--subtotal">
<div class="m-walletBalance--tokens__balanceTitle">
On-Chain<m-tooltip icon="help"
>Store tokens on your device instead of our servers for more control
and portability</m-tooltip
>
</div>
<div class="m-walletBalance--tokens__balanceValWrapper">
<span class="m-walletBalance--tokens__balanceVal--int">{{
onchainBalance.int | number
}}</span
><span
class="m-walletBalance--tokens__balanceVal--frac"
*ngIf="onchainBalance.frac"
>.{{ onchainBalance.frac | token: 15 | number: '3.0-0' }}</span
>
tokens
</div>
<a *ngIf="session.getLoggedInUser().rewards">Transfer to On-Chain</a>
</div>
</div>
<div class="m-walletBalance--tokens__learnMore">
<a routerLink="/tokens">Learn more</a> about tokens.
</div>
<div class="m-walletBalance--tokens__payout">
Today's estimated payout
<span class="m-walletBalance--tokens__payoutEstimate">{{
estimatedTokenPayout | token: 18 | number: '1.0-3'
}}</span>
tokens. Next payout in
<span>{{ nextPayout | timediff }}</span> (Daily at 2:00am UTC)
</div>
</ng-container>
<!-- <ng-template #buyTokens>
<a class="m-walletBalance--tokens__buyButtonWrapper" routerLink="/tokens"
><m-shadowboxSubmitButton [disabled]="!session.getLoggedInUser().rewards"
>Buy tokens</m-shadowboxSubmitButton
></a
>
</ng-template> -->
<ng-template #loading>
<h2>...</h2>
</ng-template>
m-walletBalance--tokens {
display: block;
> * {
font-weight: 300;
font-size: 15px;
line-height: 20px;
@include m-theme() {
color: themed($m-grey-300);
}
}
.m-walletBalance--tokens__equationWrapper {
display: flex;
justify-content: space-between;
}
.m-walletBalance--tokens__equationLeft {
display: flex;
flex-flow: row wrap;
}
.m-walletBalance--tokens__buyButtonWrapper {
margin-left: 36px;
cursor: default;
min-width: 105px;
}
.m-walletBalance--tokens__balanceTitle {
position: relative;
m-tooltip {
position: relative;
margin-left: 4px;
.m-tooltip {
margin: 0;
}
}
.m-tooltip--bubble {
bottom: 18px;
margin-left: 12px;
min-width: 100px;
}
}
.m-walletBalance--tokens__balanceWrapper--subtotal:last-child {
.m-walletBalance--tokens__balanceTitle {
.m-tooltip--bubble {
position: absolute;
right: -24px;
}
}
}
.m-walletBalance--tokens__balanceWrapper--total {
.m-walletBalance--tokens__balanceTitle {
font-size: 16px;
line-height: 21px;
}
.m-walletBalance--tokens__balanceVal--int {
font-size: 24px;
line-height: 32px;
}
.m-walletBalance--tokens__balanceVal--frac {
font-size: 17px;
line-height: 23px;
}
}
.m-walletBalance--tokens__balanceWrapper--subtotal {
.m-walletBalance--tokens__balanceTitle {
min-width: 78px;
}
.m-walletBalance--tokens__balanceValWrapper {
font-size: 13px;
line-height: 18px;
}
.m-walletBalance--tokens__balanceVal--int {
font-size: 16px;
line-height: 21px;
}
.m-walletBalance--tokens__balanceVal--frac {
font-size: 13px;
line-height: 18px;
}
a {
display: inline-block;
margin-top: 14px;
font-size: 14px;
line-height: 19px;
}
}
.m-walletBalance--tokens__balanceValWrapper {
font-weight: 500;
margin-top: 8px;
}
.m-walletBalance--tokens__balanceVal--int {
@include m-theme() {
color: themed($m-grey-800);
}
}
.m-walletBalance--tokens__equationSymbol {
align-self: center;
margin-bottom: 36px;
font-size: 20px;
line-height: 23px;
}
a:not(.m-walletBalance--tokens__buyButtonWrapper) {
font-weight: 300;
text-decoration: underline;
cursor: pointer;
}
.m-walletBalance--tokens__learnMore {
font-size: 14px;
line-height: 19px;
margin-top: 38px;
}
.m-walletBalance--tokens__payout {
font-size: 12px;
line-height: 16px;
margin-top: 10px;
}
.m-walletBalance--tokens__payoutEstimate {
font-weight: 500;
@include m-theme() {
color: themed($m-grey-500);
}
}
@media screen and (max-width: 800px) {
.m-walletBalance--tokens__equationLeft {
flex-direction: column;
}
.m-walletBalance--tokens__buyButtonWrapper {
margin-left: 0;
margin-top: 22px;
}
}
@media screen and (max-width: $min-tablet) {
}
@media screen and (max-width: $max-mobile) {
.m-walletBalance--tokens__payout {
display: none;
}
}
}
import {
Component,
OnInit,
OnDestroy,
ChangeDetectionStrategy,
ChangeDetectorRef,
Input,
} from '@angular/core';
import { Client } from '../../../../services/api/client';
import { Subscription } from 'rxjs';
import { Session } from '../../../../services/session';
import { WalletDashboardService } from './../dashboard.service';
import * as BN from 'bn.js';
@Component({
selector: 'm-walletBalance--tokens',
templateUrl: './balance-tokens.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WalletBalanceTokensV2Component implements OnInit, OnDestroy {
@Input() wallet;
constructor(
protected client: Client,
protected cd: ChangeDetectorRef,
protected session: Session,
protected walletService: WalletDashboardService
) {}
tokenBalance;
offchainBalance;
onchainBalance;
inProgress = true;
protected updateTimer$;
nextPayout;
estimatedTokenPayout;
payoutSubscription: Subscription;
ngOnInit() {
this.tokenBalance = this.formatBalance(this.wallet.tokens.balance);
this.offchainBalance = this.formatBalance(this.wallet.offchain.balance);
this.onchainBalance = this.formatBalance(this.wallet.onchain.balance);
this.getPayout();
this.inProgress = false;
this.updateTimer$ = setInterval(this.updateNextPayout.bind(this), 60000);
this.detectChanges();
}
ngOnDestroy() {
clearInterval(this.updateTimer$);
if (this.payoutSubscription) {
this.payoutSubscription.unsubscribe();
}
}
async getPayout() {
try {
const result: any = await this.client.get(
`api/v2/blockchain/contributions/overview`
);
this.nextPayout = result.nextPayout;
this.estimatedTokenPayout = result.currentReward;
this.detectChanges();
} catch (e) {
console.error(e);
}
}
updateNextPayout() {
if (this.nextPayout) {
this.nextPayout--;
this.detectChanges();
}
}
formatBalance(balance) {
const formattedBalance = {
total: balance,
int: 0,
frac: null,
};
if (balance <= 0) {
return formattedBalance;
}
if (balance.length > 18) {
formattedBalance.int = balance.slice(0, -18);
}
const frac = balance.slice(-18);
if (!new BN(frac).isZero() || frac.slice(0, 3) !== '000') {
formattedBalance.frac = frac;
}
return formattedBalance;
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
}
<p>
TODO: m-walletBalance
</p>
m-walletBalance {
display: block;
margin: 50px 57px;
}
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'm-walletBalance',
templateUrl: './balance.component.html',
})
export class WalletBalanceComponent implements OnInit {
constructor() {}
ngOnInit() {}
}
......@@ -42,7 +42,7 @@ export class WalletChartComponent implements OnInit {
ngOnInit() {
this.activeTimespan = this.timespans[0];
this.data['visualisation'] = this.walletService.getTokenChartData(
this.data['visualisation'] = this.walletService.getTokenChart(
this.activeTimespan
);
}
......@@ -51,6 +51,6 @@ export class WalletChartComponent implements OnInit {
this.activeTimespan = this.timespans.find(
ts => ts.id === $event.timespanId
);
this.data = this.walletService.getTokenChartData(this.activeTimespan);
this.data = this.walletService.getTokenChart(this.activeTimespan);
}
}
......@@ -19,7 +19,13 @@
></m-shadowboxHeader__tabs>
<div class="m-shadowboxLayout__body">
<m-walletBalance class="m-shadowboxLayout__body"></m-walletBalance>
<div class="m-walletDashboardBalances__wrapper">
<m-walletBalance--tokens
[wallet]="wallet"
class="m-shadowboxLayout__body"
*ngIf="activeCurrencyId === 'tokens'"
></m-walletBalance--tokens>
</div>
<div class="m-walletDashboardViews__wrapper">
<div class="m-walletDashboardViews__tabsContainer">
<div
......
......@@ -2,6 +2,7 @@ m-walletDashboard {
.m-shadowboxHeaderTab {
line-height: 21px;
.m-shadowboxHeaderTab__label {
margin-top: 10px;
font-size: 18px;
@include m-theme() {
color: themed($m-grey-800);
......@@ -19,7 +20,6 @@ m-walletDashboard {
box-sizing: border-box;
display: flex;
flex-flow: row nowrap;
margin: 0 40px;
@include m-theme() {
border-bottom: 1px solid themed($m-grey-100);
}
......@@ -50,7 +50,38 @@ m-walletDashboard {
}
.m-walletDashboardViews__view {
display: block;
margin: 50px 57px 0 57px;
padding-bottom: 50px;
}
m-shadowboxSubmitButton {
.m-shadowboxSubmitButton {
max-height: 35px;
min-width: 0;
min-height: 0;
font-weight: 300;
padding: 7px 15px;
font-size: 15px;
line-height: 20px;
}
}
.m-walletDashboardBalances__wrapper {
margin: 50px 40px 34px 40px;
}
.m-walletDashboardViews__tabsContainer {
margin: 0 40px;
}
.m-walletDashboardViews__view {
margin: 50px 57px 0 57px;
}
@media screen and (max-width: $min-tablet) {
.m-walletDashboardBalances__wrapper {
margin: 50px 24px 34px 24px;
}
.m-walletDashboardViews__tabsContainer,
.m-walletDashboardViews__view {
margin-left: 16px;
margin-right: 16px;
}
}
}
......@@ -22,8 +22,8 @@ import { ShadowboxHeaderTab } from '../../../interfaces/dashboard';
export class WalletDashboardComponent implements OnInit, OnDestroy {
menu: Menu = sidebarMenu;
paramsSubscription: Subscription;
wallet;
currencies: ShadowboxHeaderTab[];
activeCurrencyId: string;
activeViewId: string;
......@@ -41,6 +41,8 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
btc: [{ id: 'settings', label: 'Settings' }],
};
currencies: ShadowboxHeaderTab[] = [];
constructor(
protected walletService: WalletDashboardService,
protected session: Session,
......@@ -57,7 +59,7 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
}
this.title.setTitle('Wallet');
this.currencies = this.walletService.getCurrencySubtotals();
this.wallet = this.walletService.getWallet();
this.route.paramMap.subscribe((params: ParamMap) => {
this.activeCurrencyId = params.get('currency');
......@@ -74,6 +76,23 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
this.detectChanges();
});
this.setCurrencies();
this.detectChanges();
}
setCurrencies() {
const headerCurrencies = ['tokens', 'usd', 'eth', 'btc'];
headerCurrencies.forEach(currency => {
const headerTab: ShadowboxHeaderTab = {
id: currency,
label: this.wallet[currency].label,
unit: this.wallet[currency].unit,
};
if (currency !== 'btc') {
headerTab.value = this.wallet[currency].balance;
}
this.currencies.push(headerTab);
});
}
ngOnDestroy() {
......
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs';
import {
map,
distinctUntilChanged,
switchMap,
tap,
catchError,
} from 'rxjs/operators';
import { MindsHttpClient } from '../../../common/api/client.service';
import { Client } from '../../../common/api/client.service';
import { Session } from '../../../services/session';
import { Web3WalletService } from '../../blockchain/web3-wallet.service';
import { TokenContractService } from '../../blockchain/contracts/token-contract.service';
import { BehaviorSubject, Observable } from 'rxjs';
import * as BN from 'bn.js';
import fakeData from './fake-data';
import {
Response,
UserState,
ShadowboxHeaderTab,
} from '../../../interfaces/dashboard';
@Injectable()
export class WalletDashboardService {
constructor(private http: MindsHttpClient) {
// this.loadFromRemote();
walletLoaded = false;
totalTokens = 0;
wallet: any = {
tokens: {
label: 'Tokens',
unit: 'tokens',
balance: 0,
address: null,
},
offchain: {
label: 'Off-chain',
unit: 'tokens',
balance: 0,
address: 'offchain',
},
onchain: {
label: 'On-chain',
unit: 'tokens',
balance: 0,
address: null,
},
receiver: {
label: 'Receiver',
unit: 'tokens',
balance: 0,
address: null,
},
usd: {
label: 'USD',
unit: 'usd',
balance: 0,
address: null,
},
eth: {
label: 'Ether',
unit: 'eth',
balance: 0,
address: null,
},
btc: {
label: 'Bitcoin',
unit: 'btc',
balance: 0,
address: null,
},
};
constructor(
private client: Client,
protected web3Wallet: Web3WalletService,
protected tokenContract: TokenContractService,
protected session: Session
) {}
getWallet() {
this.getTokenAccounts();
this.getEthAccount();
this.getStripeAccount();
// TODOOJM toggle me
// this.wallet = fakeData.wallet;
this.walletLoaded = true;
return this.wallet;
}
getTokenChartData(activeTimespan) {
return fakeData.visualisation;
async getTokenAccounts() {
await this.loadOffchainAndReceiver();
await this.loadOnchain();
}
getCurrencySubtotals() {
const currencySubtotals: ShadowboxHeaderTab[] = [
{
id: 'tokens',
label: 'Tokens',
unit: 'tokens',
},
{
id: 'usd',
label: 'USD',
unit: 'usd',
},
{
id: 'eth',
label: 'Ether',
unit: 'eth',
},
{
id: 'btc',
label: 'Bitcoin',
},
];
currencySubtotals[0].value = this.getTokenSubtotal();
currencySubtotals[1].value = this.getUsdSubtotal();
currencySubtotals[2].value = this.getEthSubtotal();
return currencySubtotals;
async loadOffchainAndReceiver() {
try {
const response: any = await this.client.get(
`api/v2/blockchain/wallet/balance`
);
if (response && response.addresses) {
this.totalTokens = response.balance;
response.addresses.forEach(address => {
if (address.label === 'Offchain') {
this.wallet.offchain.balance = address.balance;
} else if (address.label === 'Receiver') {
this.wallet.onchain.balance = address.balance;
this.wallet.receiver.balance = address.balance;
this.wallet.receiver.address = address.address;
}
});
} else {
console.error('No data');
}
} catch (e) {
console.error(e);
}
}
private getTokenSubtotal() {
// see WalletBalanceTokensComponent loadLocal(), loadRemote()
return 2167.457;
async loadOnchain() {
try {
const address = await this.web3Wallet.getCurrentWallet();
if (!address) {
return;
}
this.wallet.onchain.address = address;
if (this.wallet.receiver.address === address) {
return; // don't re-add onchain balance to totalTokens
}
const onchainBalance = await this.tokenContract.balanceOf(address);
this.wallet.onchain.balance = onchainBalance[0].toString();
this.totalTokens = new BN(this.totalTokens).add(onchainBalance[0]);
} catch (e) {
console.log(e);
}
}
private getUsdSubtotal() {
// get from Mark after Stripe update
return 13577;
async getEthAccount() {
const address = await this.web3Wallet.getCurrentWallet();
if (!address) {
return;
}
this.wallet.eth.address = address;
const ethBalance = await this.web3Wallet.getBalance(address);
if (ethBalance) {
this.wallet.eth.balance = ethBalance;
}
}
async getStripeAccount() {
const merchant = this.session.getLoggedInUser().merchant;
if (merchant && merchant.service === 'stripe') {
try {
const stripeAccount = <any>(
await this.client.get('api/v2/payments/stripe/connect')
);
if (stripeAccount && stripeAccount.totalBalance) {
this.wallet.usd.value =
stripeAccount.totalBalance.amount +
stripeAccount.pendingBalance.amount;
}
return stripeAccount;
} catch (e) {
console.error(e);
}
} else {
return;
}
}
async getStripeTransactions() {
try {
const { transactions } = <any>(
await this.client.get('api/v2/payments/stripe/transactions')
);
return transactions;
} catch (e) {
console.error(e);
}
}
async hasMetamask(): Promise<boolean> {
const isLocal: any = await this.web3Wallet.isLocal();
return Boolean(isLocal);
}
// TODOOJM bucket endpoint needed
getTokenChart(activeTimespan) {
return fakeData.visualisation;
}
private getEthSubtotal() {
// see WalletBalanceTokensComponent loadEth()
return 15.3570957;
// TODOOJM tx/contribution endpoint needed
getTokenTransactionTable() {
return fakeData.token_transactions;
}
}
const fakeData = {
wallet: {
tokens: {
label: 'Tokens',
unit: 'tokens',
balance: '777123456789987654321',
address: null,
},
offchain: {
label: 'Off-chain',
unit: 'tokens',
balance: '222000000000000000000',
address: 'offchain',
},
onchain: {
label: 'On-chain',
unit: 'tokens',
balance: '333123956789987654321',
address: '0x7aA1A2a94c799f0124B6Bf8481D529BDa844498D',
},
receiver: {
label: 'Receiver',
unit: 'tokens',
balance: '000123456789987654321',
address: '0x8aA1A2a94c799f0124B6Bf8481D529BDa844498D',
},
usd: {
label: 'USD',
unit: 'usd',
balance: 2550,
address: null,
},
eth: {
label: 'Ether',
unit: 'eth',
balance: '1111595995595595595595',
address: '0x7aA1A2a94c799f0124B6Bf8481D529BDa844498D',
},
btc: {
label: 'Bitcoin',
unit: 'btc',
balance: 0,
address: null,
},
},
payout: {
contributionValues: {
checkin: 0,
comments: 0,
reminds: 0,
votes: 0,
subscribers: 0,
jury_duty: 0,
onchain_tx: 0,
referrals: 0,
referrals_welcome: 0,
},
currentReward: '0',
nextPayout: 0,
totalNetworkContribution: 78507,
yourContribution: 0,
yourRewardFactor: 0,
yourShare: 0,
status: 'success',
},
// balances: {
// tokens: '777123456789987654321',
// offchain: '222123456789987654321',
// onchain: '333123456789987654321',
// receiver: '000123456789987654321',
// eth: '111123456789987654321',
// usd: 250,
// },
// addresses: {
// receiver: '0x8aA1A2a94c799f0124B6Bf8481D529BDa844498D',
// onchain: '0x7aA1A2a94c799f0124B6Bf8481D529BDa844498D',
// eth: '0x7aA1A2a94c799f0124B6Bf8481D529BDa844498D',
// },
visualisation: {
type: 'chart',
unit: 'tokens',
......@@ -70,7 +147,6 @@ const fakeData = {
],
},
token_transactions: {
current_total: 25.0,
filters: [
{
id: 'transaction_types',
......
......@@ -5,11 +5,6 @@ const sidebarMenu = {
permissions: ['admin', 'user'],
},
links: [
{
id: 'wallet',
label: 'Wallet',
permissions: ['admin', 'user'],
},
{
id: 'earnings',
label: 'Earnings',
......
......@@ -50,7 +50,7 @@ import { ReferralsModule } from './tokens/referrals/referrals.module';
import { ReferralsComponent } from './tokens/referrals/referrals.component';
import { WalletUSDBalanceComponent } from './usd/balance.component';
import { WalletDashboardComponent } from './v2/dashboard.component';
import { WalletBalanceComponent } from './v2/balance/balance.component';
import { WalletBalanceTokensV2Component } from './v2/balance-tokens/balance-tokens.component';
import { WalletChartComponent } from './v2/chart/chart.component';
import { WalletTransactionsTableComponent } from './v2/transactions-table/transactions-table.component';
import { WalletActionButtonComponent } from './v2/action-button/action-button.component';
......@@ -172,7 +172,7 @@ const walletRoutes: Routes = [
WalletTokenTestnetComponent,
WalletUSDBalanceComponent,
WalletDashboardComponent,
WalletBalanceComponent,
WalletBalanceTokensV2Component,
WalletChartComponent,
WalletActionButtonComponent,
WalletRewardsPopupComponent,
......