Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/cypress/e2e/dashboard/ledgers.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe('DASHBOARD LEDGERS', () => {
cy.get('mina-dashboard-ledger > div:first-child > div.h-minus-xl > .group:nth-child(3) div.primary')
.then((el: any) => {
let progress;
progress = state.rpcStats.rootLedger?.fetched / state.rpcStats.rootLedger?.estimation * 100 || 0;
progress = state.rpcStats.snarkedRootLedger?.fetched / state.rpcStats.snarkedRootLedger?.estimation * 100 || 0;
progress = Math.round(progress);

if (state.nodes[0].ledgers.rootSnarked.state === 'success') {
Expand Down
12 changes: 6 additions & 6 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "1.0.21",
"version": "1.0.44",
"scripts": {
"install:deps": "npm install",
"start": "npm install && ng serve --configuration local --open",
Expand Down Expand Up @@ -42,7 +42,7 @@
"@ngrx/router-store": "^17.2.0",
"@ngrx/store": "^17.2.0",
"@nguniversal/express-engine": "^7.0.2",
"@openmina/shared": "^0.116.0",
"@openmina/shared": "^0.117.0",
"@sentry/angular": "^8.35.0",
"@sentry/cli": "^2.38.2",
"@sentry/tracing": "^7.114.0",
Expand Down Expand Up @@ -86,4 +86,4 @@
"webpack": "^5.88.2",
"webpack-bundle-analyzer": "^4.9.0"
}
}
}
5 changes: 5 additions & 0 deletions frontend/src/app/app.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MinaNode } from '@shared/types/core/environment/mina-env.type';
import { createType } from '@shared/constants/store-functions';
import { createAction, props } from '@ngrx/store';
import { AppNodeDetails } from '@shared/types/app/app-node-details.type';
import { AppEnvBuild } from '@shared/types/app/app-env-build.type';

export const APP_KEY = 'app';
export const APP_PREFIX = 'App';
Expand All @@ -14,6 +15,8 @@ const initSuccess = createAction(type('Init Success'), props<{ activeNode: MinaN
const changeActiveNode = createAction(type('Change Active Node'), props<{ node: MinaNode }>());
const getNodeDetails = createAction(type('Get Node Details'));
const getNodeDetailsSuccess = createAction(type('Get Node Details Success'), props<{ details: AppNodeDetails }>());
const getNodeEnvBuild = createAction(type('Get Node Env Build'));
const getNodeEnvBuildSuccess = createAction(type('Get Node Env Build Success'), props<{ envBuild: AppEnvBuild }>());
const deleteNode = createAction(type('Delete Node'), props<{ node: MinaNode }>());
const addNode = createAction(type('Add Node'), props<{ node: MinaNode }>());

Expand All @@ -28,6 +31,8 @@ export const AppActions = {
changeActiveNode,
getNodeDetails,
getNodeDetailsSuccess,
getNodeEnvBuild,
getNodeEnvBuildSuccess,
deleteNode,
addNode,
changeMenuCollapsing,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@if (!hideToolbar) {
<mina-toolbar></mina-toolbar>
}
<div class="mina-content"
<div id="mina-content"
[class.no-toolbar]="hideToolbar"
[class.no-submenus]="subMenusLength < 2"
[class.mobile]="menu.isMobile">
Expand Down
8 changes: 2 additions & 6 deletions frontend/src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,10 @@ mat-sidenav-content {
mat-sidenav-container,
mat-sidenav-content {
color: inherit;
background-color: $base-surface;

@media (max-width: 767px) {
background-color: $base-background;
}
background-color: $base-background;
}

.mina-content {
#mina-content {
$toolbar: 40px;
height: calc(100% - #{$toolbar});
border-top-left-radius: 6px;
Expand Down
29 changes: 19 additions & 10 deletions frontend/src/app/app.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core';
import { MinaState, selectMinaState } from '@app/app.setup';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { createNonDispatchableEffect, Effect, NonDispatchableEffect, removeParamsFromURL } from '@openmina/shared';
import { filter, from, map, switchMap, tap } from 'rxjs';
import { createNonDispatchableEffect, Effect, removeParamsFromURL } from '@openmina/shared';
import { filter, map, mergeMap, of, switchMap, tap } from 'rxjs';
import { AppActions } from '@app/app.actions';
import { Router } from '@angular/router';
import { FeatureType, MinaNode } from '@shared/types/core/environment/mina-env.type';
Expand All @@ -22,9 +22,10 @@ import { AppNodeStatus } from '@shared/types/app/app-node-details.type';
export class AppEffects extends BaseEffect {

readonly init$: Effect;
readonly initSuccess$: NonDispatchableEffect;
readonly initSuccess$: Effect;
readonly onNodeChange$: Effect;
readonly getNodeDetails$: Effect;
readonly getNodeEnvBuild$: Effect;

private requestInProgress: boolean = false;

Expand All @@ -46,7 +47,7 @@ export class AppEffects extends BaseEffect {
map((payload: { activeNode: MinaNode, nodes: MinaNode[] }) => AppActions.initSuccess(payload)),
));

this.initSuccess$ = createNonDispatchableEffect(() => this.actions$.pipe(
this.initSuccess$ = createEffect(() => this.actions$.pipe(
ofType(AppActions.initSuccess),
this.latestActionState(),
switchMap(({ state }) => {
Expand All @@ -55,8 +56,9 @@ export class AppEffects extends BaseEffect {
switchMap(() => this.webNodeService.startWasm$()),
);
}
return from([]);
return of({});
}),
map(() => AppActions.getNodeEnvBuild()),
));

this.onNodeChange$ = createNonDispatchableEffect(() => this.actions$.pipe(
Expand All @@ -79,9 +81,16 @@ export class AppEffects extends BaseEffect {
switchMap(() => this.webNodeService.startWasm$()),
);
}
return from([]);
return of({});
}),
map(() => AppActions.getNodeDetails()),
switchMap(() => [AppActions.getNodeDetails(), AppActions.getNodeEnvBuild()]),
));

this.getNodeEnvBuild$ = createEffect(() => this.actions$.pipe(
ofType(AppActions.getNodeEnvBuild),
mergeMap(() => this.appService.getEnvBuild()),
map(envBuild => AppActions.getNodeEnvBuildSuccess({ envBuild })),
catchErrorAndRepeat2(MinaErrorType.RUST, AppActions.getNodeEnvBuildSuccess({ envBuild: undefined })),
));

this.getNodeDetails$ = createEffect(() => this.actions$.pipe(
Expand All @@ -95,9 +104,9 @@ export class AppEffects extends BaseEffect {
status: AppNodeStatus.OFFLINE,
blockHeight: null,
blockTime: null,
peers: 0,
download: 0,
upload: 0,
peersConnected: 0,
peersDisconnected: 0,
peersConnecting: 0,
transactions: 0,
snarks: 0,
producingBlockAt: null,
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/app/app.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ const initialState: AppState = {
status: AppNodeStatus.PENDING,
blockHeight: null,
blockTime: null,
peers: 0,
download: 0,
upload: 0,
peersConnected: 0,
peersDisconnected: 0,
peersConnecting: 0,
transactions: 0,
snarks: 0,
producingBlockAt: null,
producingBlockGlobalSlot: null,
producingBlockStatus: null,
},
envBuild: undefined,
};

export const appReducer = createReducer(
Expand Down Expand Up @@ -53,4 +54,5 @@ export const appReducer = createReducer(
const nodes = state.nodes.filter(n => n.name !== node.name);
return { ...state, nodes, activeNode: state.activeNode?.name === node.name ? nodes[0] : state.activeNode };
}),
on(AppActions.getNodeEnvBuildSuccess, (state, { envBuild }) => ({ ...state, envBuild })),
);
11 changes: 8 additions & 3 deletions frontend/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppNodeDetails, AppNodeStatus } from '@shared/types/app/app-node-detail
import { getNetwork } from '@shared/helpers/mina.helper';
import { getLocalStorage, ONE_MILLION } from '@openmina/shared';
import { BlockProductionWonSlotsStatus } from '@shared/types/block-production/won-slots/block-production-won-slots-slot.type';
import { AppEnvBuild } from '@shared/types/app/app-env-build.type';

@Injectable({
providedIn: 'root',
Expand All @@ -29,16 +30,20 @@ export class AppService {
]);
}

getEnvBuild(): Observable<AppEnvBuild> {
return this.rust.get<AppEnvBuild>('/build_env');
}

getActiveNodeDetails(): Observable<AppNodeDetails> {
return this.rust.get<NodeDetailsResponse>('/status')
.pipe(
map((data: NodeDetailsResponse): AppNodeDetails => ({
status: this.getStatus(data),
blockHeight: data.transition_frontier.best_tip?.height,
blockTime: data.transition_frontier.sync.time,
peers: data.peers.filter(p => p.connection_status === 'Connected').length,
download: 0,
upload: 0,
peersConnected: data.peers.filter(p => p.connection_status === 'Connected').length,
peersDisconnected: data.peers.filter(p => p.connection_status === 'Disconnected').length,
peersConnecting: data.peers.filter(p => p.connection_status === 'Connecting').length,
snarks: data.snark_pool.snarks,
transactions: data.transaction_pool.transactions,
chainId: data.chain_id,
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/app.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { AppMenu } from '@shared/types/app/app-menu.type';
import { createSelector, MemoizedSelector } from '@ngrx/store';
import { MinaNode } from '@shared/types/core/environment/mina-env.type';
import { AppNodeDetails } from '@shared/types/app/app-node-details.type';
import { AppEnvBuild } from '@shared/types/app/app-env-build.type';

export interface AppState {
menu: AppMenu;
nodes: MinaNode[];
activeNode: MinaNode;
activeNodeDetails: AppNodeDetails;
envBuild: AppEnvBuild | undefined;
}

const select = <T>(selector: (state: AppState) => T): MemoizedSelector<MinaState, T> => createSelector(
Expand All @@ -20,10 +22,12 @@ const menu = select(state => state.menu);
const nodes = select(state => state.nodes);
const activeNode = select(state => state.activeNode);
const activeNodeDetails = select(state => state.activeNodeDetails);
const envBuild = select(state => state.envBuild);

export const AppSelectors = {
menu,
nodes,
activeNode,
activeNodeDetails,
envBuild,
};
2 changes: 2 additions & 0 deletions frontend/src/app/core/services/rust.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export class RustService {
return this.webNodeService.accounts$;
case '/best-chain-user-commands':
return this.webNodeService.bestChainUserCommands$;
case '/build_env':
return this.webNodeService.envBuildDetails$;
default:
throw new Error(`Web node doesn't support "${path}" path!`);
}
Expand Down
24 changes: 19 additions & 5 deletions frontend/src/app/core/services/web-node.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CONFIG } from '@shared/constants/config';
export class WebNodeService {

private readonly webnode$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private readonly wasm$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private webNodeKeyPair: { publicKey: string, privateKey: string };
private webNodeNetwork: String;
private webNodeStartTime: number;
Expand All @@ -27,7 +28,7 @@ export class WebNodeService {
FileProgressHelper.initDownloadProgress();
const basex = base('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
safelyExecuteInBrowser(() => {
any(window)['bs58btc'] = {
any(window).bs58btc = {
encode: (buffer: Uint8Array | number[]) => 'z' + basex.encode(buffer),
decode: (string: string) => basex.decode(string.substring(1)),
};
Expand All @@ -47,6 +48,7 @@ export class WebNodeService {

loadWasm$(): Observable<void> {
this.webNodeStartTime = Date.now();

if (isBrowser()) {
const args = (() => {
const raw = localStorage.getItem('webnodeArgs');
Expand Down Expand Up @@ -88,7 +90,11 @@ export class WebNodeService {
if (isBrowser()) {
return of(any(window).webnode)
.pipe(
switchMap((wasm: any) => from(wasm.default(undefined, new WebAssembly.Memory(this.memory))).pipe(map(() => wasm))),
switchMap((wasm: any) => {
this.wasm$.next(wasm);
return from(wasm.default(undefined, new WebAssembly.Memory(this.memory)))
.pipe(map(() => wasm));
}),
switchMap((wasm) => {
this.webnodeProgress$.next('Loaded');
const urls = (() => {
Expand All @@ -99,14 +105,16 @@ export class WebNodeService {
genesisConfig: url + 'genesis/config',
};
} else {
return {};
return {
seeds: 'https://bootnodes.minaprotocol.com/networks/devnet-webrtc.txt',
};
}
})();
console.log('webnode config:', !!this.webNodeKeyPair.privateKey, this.webNodeNetwork, urls);
return from(wasm.run(this.webNodeKeyPair.privateKey, urls.seeds, urls.genesisConfig));
}),
tap((webnode: any) => {
any(window)['webnode'] = webnode;
any(window).webnode = webnode;
this.webnode$.next(webnode);
this.webnodeProgress$.next('Started');
}),
Expand All @@ -115,7 +123,6 @@ export class WebNodeService {
return throwError(() => new Error(error.message));
}),
switchMap(() => this.webnode$.asObservable()),
filter(Boolean),
);
}
return EMPTY;
Expand Down Expand Up @@ -198,4 +205,11 @@ export class WebNodeService {
switchMap(handle => from(any(handle).transaction_pool().get())),
);
}

get envBuildDetails$(): Observable<any> {
return this.wasm$.asObservable().pipe(
filter(Boolean),
map(handle => handle.build_env()),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import { ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit } fro
import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class';
import { BlockProductionOverviewActions } from '@block-production/overview/block-production-overview.actions';
import { getMergedRoute, isDesktop, MergedRoute, safelyExecuteInBrowser } from '@openmina/shared';
import { debounceTime, filter, fromEvent, skip, take } from 'rxjs';
import { debounceTime, filter, fromEvent, take } from 'rxjs';
import { isNaN } from 'mathjs';
import { untilDestroyed } from '@ngneat/until-destroy';
import { BlockProductionOverviewSelectors } from '@block-production/overview/block-production-overview.state';
import { SLOTS_PER_EPOCH } from '@shared/constants/mina';
import {
BlockProductionOverviewEpoch,
} from '@shared/types/block-production/overview/block-production-overview-epoch.type';
import { BlockProductionOverviewEpoch } from '@shared/types/block-production/overview/block-production-overview-epoch.type';
import { AppSelectors } from '@app/app.state';
import { MinaNode } from '@shared/types/core/environment/mina-env.type';

@Component({
selector: 'mina-block-production-overview',
Expand Down
Loading
Loading