Skip to content

Commit 1c10258

Browse files
authored
Frontend - WebNode Updates (#795)
1 parent 80f96bc commit 1c10258

File tree

11 files changed

+115
-28
lines changed

11 files changed

+115
-28
lines changed

frontend/src/app/app.routing.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NgModule } from '@angular/core';
2-
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
3-
import { getFirstFeature } from '@shared/constants/config';
2+
import { NoPreloading, PreloadAllModules, RouterModule, Routes } from '@angular/router';
3+
import { CONFIG, getFirstFeature } from '@shared/constants/config';
44

55
const APP_TITLE: string = 'Open Mina';
66

@@ -79,7 +79,7 @@ const routes: Routes = [
7979
imports: [
8080
RouterModule.forRoot(routes, {
8181
// enableTracing: true,
82-
preloadingStrategy: PreloadAllModules,
82+
preloadingStrategy: CONFIG.configs.some(c => c.isWebNode) ? NoPreloading : PreloadAllModules,
8383
onSameUrlNavigation: 'ignore',
8484
initialNavigation: 'enabledNonBlocking',
8585
}),

frontend/src/app/core/services/rust.service.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ export class RustService {
3737
}
3838

3939
post<T, B = string | object>(path: string, body: B): Observable<T> {
40+
if (this.node.isWebNode) {
41+
return this.postToWebNode(path, body).pipe(map((response: any) => {
42+
// console.log(path, response);
43+
return response;
44+
}));
45+
}
4046
return this.http.post<T>(this.URL + path, body);
4147
}
4248

@@ -56,6 +62,21 @@ export class RustService {
5662
return this.webNodeService.sync$;
5763
case '/stats/block_producer':
5864
return this.webNodeService.blockProducerStats$;
65+
case '/transaction-pool':
66+
return this.webNodeService.transactionPool$;
67+
case '/accounts':
68+
return this.webNodeService.accounts$;
69+
case '/best-chain-user-commands':
70+
return this.webNodeService.bestChainUserCommands$;
71+
default:
72+
throw new Error(`Web node doesn't support "${path}" path!`);
73+
}
74+
}
75+
76+
private postToWebNode<T, B>(path: string, body: B): Observable<T> {
77+
switch (path) {
78+
case '/send-payment':
79+
return this.webNodeService.sendPayment$(body);
5980
default:
6081
throw new Error(`Web node doesn't support "${path}" path!`);
6182
}

frontend/src/app/core/services/web-node.service.ts

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Injectable } from '@angular/core';
2-
import { BehaviorSubject, filter, from, fromEvent, map, Observable, of, switchMap, tap } from 'rxjs';
2+
import { BehaviorSubject, filter, from, fromEvent, map, merge, Observable, of, switchMap, tap } from 'rxjs';
33
import base from 'base-x';
44
import { any, log } from '@openmina/shared';
5-
import { CONFIG } from '@shared/constants/config';
5+
import { HttpClient } from '@angular/common/http';
66

77
@Injectable({
88
providedIn: 'root',
@@ -11,9 +11,10 @@ export class WebNodeService {
1111

1212
private readonly backendSubject$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
1313
private backend: any;
14+
private webNodeKeyPair: { publicKey: string, privateKey: string };
1415
webNodeState: string = 'notLoaded';
1516

16-
constructor() {
17+
constructor(private http: HttpClient) {
1718
const basex = base('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
1819
any(window)['bs58btc'] = {
1920
encode: (buffer: Uint8Array | number[]) => 'z' + basex.encode(buffer),
@@ -22,19 +23,25 @@ export class WebNodeService {
2223
}
2324

2425
loadWasm$(): Observable<void> {
25-
if ((window as any).webnode) {
26-
return of(void 0);
27-
}
28-
return fromEvent(window, 'webNodeLoaded').pipe(map(() => void 0));
26+
console.log('---LOADING WASM');
27+
return merge(
28+
of(any(window).webnode).pipe(filter(Boolean)),
29+
fromEvent(window, 'webNodeLoaded'),
30+
).pipe(
31+
switchMap(() => this.http.get<{ publicKey: string, privateKey: string }>('assets/webnode/web-node-secrets.json')),
32+
tap(data => this.webNodeKeyPair = data),
33+
map(() => void 0),
34+
);
2935
}
3036

3137
startWasm$(): Observable<any> {
32-
return of((window as any).webnode)
38+
console.log('---STARTING WASM');
39+
return of(any(window).webnode)
3340
.pipe(
3441
switchMap((wasm: any) => from(wasm.default('assets/webnode/pkg/openmina_node_web_bg.wasm')).pipe(map(() => wasm))),
3542
switchMap((wasm) => {
3643
console.log(wasm);
37-
return from(wasm.run(CONFIG.webNodeKey));
44+
return from(wasm.run(this.webNodeKeyPair.privateKey));
3845
}),
3946
tap((jsHandle: any) => {
4047
this.backend = jsHandle;
@@ -47,10 +54,15 @@ export class WebNodeService {
4754
);
4855
}
4956

57+
get webNodeKeys(): { publicKey: string, privateKey: string } {
58+
return this.webNodeKeyPair;
59+
}
60+
5061
get status$(): Observable<any> {
5162
return this.backendSubject$.asObservable().pipe(
5263
filter(Boolean),
5364
switchMap(handle => from((handle as any).status())),
65+
log(),
5466
);
5567
}
5668

@@ -81,4 +93,40 @@ export class WebNodeService {
8193
switchMap(handle => from((handle as any).stats().sync())),
8294
);
8395
}
96+
97+
get accounts$(): Observable<any> {
98+
return this.backendSubject$.asObservable().pipe(
99+
filter(Boolean),
100+
switchMap(handle => from((handle as any).ledger().latest().accounts().all())),
101+
);
102+
}
103+
104+
get bestChainUserCommands$(): Observable<any> {
105+
console.log('---GETTING BEST CHAIN USER COMMANDS');
106+
return this.backendSubject$.asObservable().pipe(
107+
filter(Boolean),
108+
switchMap(handle => from((handle as any).transition_frontier().best_chain().user_commands())),
109+
tap((r) => {
110+
console.log('response from GETTING BEST CHAIN USER COMMANDS', r);
111+
}),
112+
);
113+
}
114+
115+
sendPayment$(payment: any): Observable<any> {
116+
return this.backendSubject$.asObservable().pipe(
117+
filter(Boolean),
118+
switchMap(handle => from((handle as any).transaction_pool().inject().payment(payment))),
119+
);
120+
}
121+
122+
get transactionPool$(): Observable<any> {
123+
console.log('---GETTING TRANSACTION POOL');
124+
return this.backendSubject$.asObservable().pipe(
125+
filter(Boolean),
126+
switchMap(handle => from((handle as any).transaction_pool().get())),
127+
tap((r) => {
128+
console.log('response from GETTING TRANSACTION POOL', r);
129+
}),
130+
);
131+
}
84132
}

frontend/src/app/features/benchmarks/wallets/benchmarks-wallets-zk.service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export class BenchmarksWalletsZkService {
1515

1616
readonly updates$ = this.updates.asObservable();
1717

18-
1918
loadO1js(): void {
2019
this.loadScript();
2120
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<mina-benchmarks-wallets-toolbar></mina-benchmarks-wallets-toolbar>
22
<div class="h-minus-xl flex-column">
3-
<mina-benchmarks-wallets-zkapp-toolbar></mina-benchmarks-wallets-zkapp-toolbar>
4-
<div class="h-minus-xl flex-column">
3+
<mina-benchmarks-wallets-zkapp-toolbar *ngIf="!isWebNode"></mina-benchmarks-wallets-zkapp-toolbar>
4+
<div [class.h-minus-xl]="!isWebNode"
5+
class="flex-column">
56
<mina-benchmarks-wallets-table></mina-benchmarks-wallets-table>
67
</div>
78
</div>

frontend/src/app/features/benchmarks/wallets/benchmarks-wallets.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class';
44
import { AppSelectors } from '@app/app.state';
55
import { filter, skip } from 'rxjs';
66
import { BenchmarksWalletsZkService } from '@benchmarks/wallets/benchmarks-wallets-zk.service';
7+
import { MinaNode } from '@shared/types/core/environment/mina-env.type';
78

89
@Component({
910
selector: 'mina-benchmarks-wallets',
@@ -14,7 +15,9 @@ import { BenchmarksWalletsZkService } from '@benchmarks/wallets/benchmarks-walle
1415
})
1516
export class BenchmarksWalletsComponent extends StoreDispatcher implements OnInit, OnDestroy {
1617

17-
constructor(private zkService: BenchmarksWalletsZkService) {super();}
18+
isWebNode: boolean = false;
19+
20+
constructor(private zkService: BenchmarksWalletsZkService) { super(); }
1821

1922
ngOnInit(): void {
2023
this.zkService.loadO1js();
@@ -23,6 +26,10 @@ export class BenchmarksWalletsComponent extends StoreDispatcher implements OnIni
2326
}
2427

2528
private listenToActiveNodeChange(): void {
29+
this.select(AppSelectors.activeNode, (node: MinaNode) => {
30+
this.isWebNode = node.isWebNode;
31+
this.detect();
32+
}, filter(Boolean));
2633
this.select(AppSelectors.activeNode, () => {
2734
this.dispatch(BenchmarksWalletsGetWallets, { initialRequest: true });
2835
}, filter(Boolean), skip(1));

frontend/src/app/shared/types/core/environment/mina-env.type.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export interface MinaEnv {
22
production: boolean;
33
configs: MinaNode[];
44
identifier?: string;
5-
webNodeKey?: string;
65
hideToolbar?: boolean;
76
hideNodeStats?: boolean;
87
globalConfig?: {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export default {
2+
production: true,
3+
globalConfig: {
4+
features: {
5+
'dashboard': [],
6+
'block-production': ['won-slots'],
7+
'nodes': ['overview', 'live', 'bootstrap'],
8+
'mempool': [],
9+
'benchmarks': ['wallets'],
10+
},
11+
canAddNodes: false,
12+
},
13+
configs: [
14+
{
15+
name: 'Web Node',
16+
isWebNode: true,
17+
},
18+
],
19+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
#.gitignore
22
circuit-blobs
33
pkg
4+
web-node-secrets.json

frontend/src/environments/environment.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ import { MinaEnv } from '@shared/types/core/environment/mina-env.type';
33
export const environment: Readonly<MinaEnv> = {
44
production: false,
55
identifier: 'Dev FE',
6-
webNodeKey: '',
76
globalConfig: {
87
features: {
98
dashboard: [],
109
nodes: ['overview', 'live', 'bootstrap'],
1110
state: ['actions'],
1211
network: ['messages', 'connections', 'blocks', 'topology', 'node-dht', 'graph-overview', 'bootstrap-stats'],
1312
snarks: ['scan-state', 'work-pool'],
14-
'testing-tool': ['scenarios'],
1513
resources: ['memory'],
1614
'block-production': ['won-slots'],
1715
mempool: [],

0 commit comments

Comments
 (0)