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
6 changes: 3 additions & 3 deletions frontend/src/app/app.routing.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { getFirstFeature } from '@shared/constants/config';
import { NoPreloading, PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { CONFIG, getFirstFeature } from '@shared/constants/config';

const APP_TITLE: string = 'Open Mina';

Expand Down Expand Up @@ -79,7 +79,7 @@ const routes: Routes = [
imports: [
RouterModule.forRoot(routes, {
// enableTracing: true,
preloadingStrategy: PreloadAllModules,
preloadingStrategy: CONFIG.configs.some(c => c.isWebNode) ? NoPreloading : PreloadAllModules,
onSameUrlNavigation: 'ignore',
initialNavigation: 'enabledNonBlocking',
}),
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/app/core/services/rust.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class RustService {
}

post<T, B = string | object>(path: string, body: B): Observable<T> {
if (this.node.isWebNode) {
return this.postToWebNode(path, body).pipe(map((response: any) => {
// console.log(path, response);
return response;
}));
}
return this.http.post<T>(this.URL + path, body);
}

Expand All @@ -56,6 +62,21 @@ export class RustService {
return this.webNodeService.sync$;
case '/stats/block_producer':
return this.webNodeService.blockProducerStats$;
case '/transaction-pool':
return this.webNodeService.transactionPool$;
case '/accounts':
return this.webNodeService.accounts$;
case '/best-chain-user-commands':
return this.webNodeService.bestChainUserCommands$;
default:
throw new Error(`Web node doesn't support "${path}" path!`);
}
}

private postToWebNode<T, B>(path: string, body: B): Observable<T> {
switch (path) {
case '/send-payment':
return this.webNodeService.sendPayment$(body);
default:
throw new Error(`Web node doesn't support "${path}" path!`);
}
Expand Down
66 changes: 57 additions & 9 deletions frontend/src/app/core/services/web-node.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, filter, from, fromEvent, map, Observable, of, switchMap, tap } from 'rxjs';
import { BehaviorSubject, filter, from, fromEvent, map, merge, Observable, of, switchMap, tap } from 'rxjs';
import base from 'base-x';
import { any, log } from '@openmina/shared';
import { CONFIG } from '@shared/constants/config';
import { HttpClient } from '@angular/common/http';

@Injectable({
providedIn: 'root',
Expand All @@ -11,9 +11,10 @@ export class WebNodeService {

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

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

loadWasm$(): Observable<void> {
if ((window as any).webnode) {
return of(void 0);
}
return fromEvent(window, 'webNodeLoaded').pipe(map(() => void 0));
console.log('---LOADING WASM');
return merge(
of(any(window).webnode).pipe(filter(Boolean)),
fromEvent(window, 'webNodeLoaded'),
).pipe(
switchMap(() => this.http.get<{ publicKey: string, privateKey: string }>('assets/webnode/web-node-secrets.json')),
tap(data => this.webNodeKeyPair = data),
map(() => void 0),
);
}

startWasm$(): Observable<any> {
return of((window as any).webnode)
console.log('---STARTING WASM');
return of(any(window).webnode)
.pipe(
switchMap((wasm: any) => from(wasm.default('assets/webnode/pkg/openmina_node_web_bg.wasm')).pipe(map(() => wasm))),
switchMap((wasm) => {
console.log(wasm);
return from(wasm.run(CONFIG.webNodeKey));
return from(wasm.run(this.webNodeKeyPair.privateKey));
}),
tap((jsHandle: any) => {
this.backend = jsHandle;
Expand All @@ -47,10 +54,15 @@ export class WebNodeService {
);
}

get webNodeKeys(): { publicKey: string, privateKey: string } {
return this.webNodeKeyPair;
}

get status$(): Observable<any> {
return this.backendSubject$.asObservable().pipe(
filter(Boolean),
switchMap(handle => from((handle as any).status())),
log(),
);
}

Expand Down Expand Up @@ -81,4 +93,40 @@ export class WebNodeService {
switchMap(handle => from((handle as any).stats().sync())),
);
}

get accounts$(): Observable<any> {
return this.backendSubject$.asObservable().pipe(
filter(Boolean),
switchMap(handle => from((handle as any).ledger().latest().accounts().all())),
);
}

get bestChainUserCommands$(): Observable<any> {
console.log('---GETTING BEST CHAIN USER COMMANDS');
return this.backendSubject$.asObservable().pipe(
filter(Boolean),
switchMap(handle => from((handle as any).transition_frontier().best_chain().user_commands())),
tap((r) => {
console.log('response from GETTING BEST CHAIN USER COMMANDS', r);
}),
);
}

sendPayment$(payment: any): Observable<any> {
return this.backendSubject$.asObservable().pipe(
filter(Boolean),
switchMap(handle => from((handle as any).transaction_pool().inject().payment(payment))),
);
}

get transactionPool$(): Observable<any> {
console.log('---GETTING TRANSACTION POOL');
return this.backendSubject$.asObservable().pipe(
filter(Boolean),
switchMap(handle => from((handle as any).transaction_pool().get())),
tap((r) => {
console.log('response from GETTING TRANSACTION POOL', r);
}),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export class BenchmarksWalletsZkService {

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


loadO1js(): void {
this.loadScript();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<mina-benchmarks-wallets-toolbar></mina-benchmarks-wallets-toolbar>
<div class="h-minus-xl flex-column">
<mina-benchmarks-wallets-zkapp-toolbar></mina-benchmarks-wallets-zkapp-toolbar>
<div class="h-minus-xl flex-column">
<mina-benchmarks-wallets-zkapp-toolbar *ngIf="!isWebNode"></mina-benchmarks-wallets-zkapp-toolbar>
<div [class.h-minus-xl]="!isWebNode"
class="flex-column">
<mina-benchmarks-wallets-table></mina-benchmarks-wallets-table>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class';
import { AppSelectors } from '@app/app.state';
import { filter, skip } from 'rxjs';
import { BenchmarksWalletsZkService } from '@benchmarks/wallets/benchmarks-wallets-zk.service';
import { MinaNode } from '@shared/types/core/environment/mina-env.type';

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

constructor(private zkService: BenchmarksWalletsZkService) {super();}
isWebNode: boolean = false;

constructor(private zkService: BenchmarksWalletsZkService) { super(); }

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

private listenToActiveNodeChange(): void {
this.select(AppSelectors.activeNode, (node: MinaNode) => {
this.isWebNode = node.isWebNode;
this.detect();
}, filter(Boolean));
this.select(AppSelectors.activeNode, () => {
this.dispatch(BenchmarksWalletsGetWallets, { initialRequest: true });
}, filter(Boolean), skip(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ export interface MinaEnv {
production: boolean;
configs: MinaNode[];
identifier?: string;
webNodeKey?: string;
hideToolbar?: boolean;
hideNodeStats?: boolean;
globalConfig?: {
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/assets/environments/webnode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default {
production: true,
globalConfig: {
features: {
'dashboard': [],
'block-production': ['won-slots'],
'nodes': ['overview', 'live', 'bootstrap'],
'mempool': [],
'benchmarks': ['wallets'],
},
canAddNodes: false,
},
configs: [
{
name: 'Web Node',
isWebNode: true,
},
],
};
1 change: 1 addition & 0 deletions frontend/src/assets/webnode/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#.gitignore
circuit-blobs
pkg
web-node-secrets.json
2 changes: 0 additions & 2 deletions frontend/src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import { MinaEnv } from '@shared/types/core/environment/mina-env.type';
export const environment: Readonly<MinaEnv> = {
production: false,
identifier: 'Dev FE',
webNodeKey: '',
globalConfig: {
features: {
dashboard: [],
nodes: ['overview', 'live', 'bootstrap'],
state: ['actions'],
network: ['messages', 'connections', 'blocks', 'topology', 'node-dht', 'graph-overview', 'bootstrap-stats'],
snarks: ['scan-state', 'work-pool'],
'testing-tool': ['scenarios'],
resources: ['memory'],
'block-production': ['won-slots'],
mempool: [],
Expand Down
12 changes: 3 additions & 9 deletions frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,11 @@

<body class="f-base">
<script type="module">
function webNodeLoaded() {
import('./assets/webnode/pkg/openmina_node_web.js').then((v) => {
window.webnode = v;
const event = new CustomEvent('webNodeLoaded');
window.dispatchEvent(event);
}

if (window.env?.webNodeKey) {
import('./assets/webnode/pkg/openmina_node_web.js').then((v) => {
window.webnode = v;
webNodeLoaded();
});
}
});
</script>
<app-root class="h-100"></app-root>
</body>
Expand Down
Loading