Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallet - External Node Tester #3721

Closed
wants to merge 4 commits into from
Closed
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
8 changes: 8 additions & 0 deletions nym-wallet/.storybook/mocks/tauri/shell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* This is a mock for Tauri's API package (@tauri-apps/api/shell), to prevent stories from being excluded, because they either use
* or import dependencies that use Tauri.
*/

module.exports = {
open: () => undefined,
};
29 changes: 22 additions & 7 deletions nym-wallet/src/components/Bonding/NodeStats.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import React, { useContext } from 'react';
import { Stack, Typography, Box, useTheme, Grid, LinearProgress, LinearProgressProps, Button } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { TBondedMixnode } from 'src/context';
import { Cell, Pie, PieChart, Legend, ResponsiveContainer } from 'recharts';
import { open as openLink } from '@tauri-apps/api/shell';
import { SelectionChance } from '@nymproject/types';
import { AppContext, TBondedMixnode } from 'src/context';
import { validatorApiFromNetwork } from 'src/constants';
import { Cell, Pie, PieChart, Legend, ResponsiveContainer } from 'recharts';
import { NymCard } from '../NymCard';
import { InfoTooltip } from '../InfoToolTip';

Expand Down Expand Up @@ -50,7 +51,7 @@ const StatRow = ({
export const NodeStats = ({ mixnode }: { mixnode: TBondedMixnode }) => {
const { activeSetProbability, routingScore } = mixnode;
const theme = useTheme();
const navigate = useNavigate();
const { network } = useContext(AppContext);

// clamp routing score to [0-100]
const score = Math.min(Math.max(routingScore, 0), 100);
Expand All @@ -74,8 +75,22 @@ export const NodeStats = ({ mixnode }: { mixnode: TBondedMixnode }) => {
}
};

const handleGoToTestNode = () => {
navigate('/bonding/node-settings', { state: 'test-node' });
const handleGoToTestNode = async () => {
// TODO Change URL to the deployed node-tester (once deployed)
const url = new window.URL('http://localhost:1234');

if (network) {
const validatorUrl = validatorApiFromNetwork(network);

const urlParams = {
'validator-address': validatorUrl,
'mixnode-identity': mixnode.identityKey,
};

Object.entries(urlParams).forEach(([key, value]) => url.searchParams.append(key, value));

openLink(url.toString());
}
};

const renderLegend = () => (
Expand Down
26 changes: 24 additions & 2 deletions nym-wallet/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
import { Network } from './types';

const QA_VALIDATOR_URL = 'https://qa-nym-api.qa.nymte.ch/api';
const QWERTY_VALIDATOR_URL = 'https://qwerty-validator-api.qa.nymte.ch/api';
const MAINNET_VALIDATOR_URL = 'https://validator.nymtech.net/api/';
const SANDBOX_VALIDATOR_URL = 'https://sandbox-nym-api1.nymtech.net/api';
const MAINNET_VALIDATOR_URL = 'https://validator.nymtech.net/api';

const validatorApiFromNetwork = (network: Network) => {
switch (network) {
case 'QA':
return QA_VALIDATOR_URL;
case 'SANDBOX':
return SANDBOX_VALIDATOR_URL;
case 'MAINNET':
return MAINNET_VALIDATOR_URL;
default:
throw new Error(`Unknown network: ${network}`);
}
};

export { QA_VALIDATOR_URL, QWERTY_VALIDATOR_URL, MAINNET_VALIDATOR_URL };
export {
QA_VALIDATOR_URL,
QWERTY_VALIDATOR_URL,
MAINNET_VALIDATOR_URL,
SANDBOX_VALIDATOR_URL,
validatorApiFromNetwork,
};
32 changes: 29 additions & 3 deletions sdk/typescript/examples/node-tester/react/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import {
Alert,
Button,
Card,
CardActions,
Expand All @@ -21,8 +22,8 @@ import { TestStatusLabel } from 'src/components/TestStatusLabel';
import Icon from '../../../../../../assets/appicon/appicon.png';

export const App = () => {
const { testState, error, testNode, disconnectFromGateway, reconnectToGateway } = useNodeTesterClient();
const [mixnodeIdentity, setMixnodeIdentity] = useState<string>('');
const { createClient, testState, error, testNode, disconnectFromGateway, reconnectToGateway } = useNodeTesterClient();
const [mixnodeIdentity, setMixnodeIdentity] = useState('');
const [results, setResults] = React.useState<NodeTestResultResponse>();

console.log({ testState, error, testNode });
Expand All @@ -37,6 +38,26 @@ export const App = () => {
}
};

const getParams = () => {
const urlParams = new URLSearchParams(window.location.search);
return {
mixnodeIdentity: urlParams.get('mixnode-identity'),
validatorAddress: urlParams.get('validator-address'),
};
};

const initApp = async () => {
const { mixnodeIdentity, validatorAddress } = getParams();
if (mixnodeIdentity) {
setMixnodeIdentity(mixnodeIdentity);
}
await createClient(validatorAddress || 'https://validator.nymtech.net/api');
};

useEffect(() => {
initApp();
}, []);

return (
<BasicPageLayout>
<Card variant="outlined" sx={{ mt: 15, p: 4 }}>
Expand Down Expand Up @@ -66,6 +87,11 @@ export const App = () => {
</ListItem>
</List>
</Grid>
{error && (
<Grid item xs={12}>
<Alert severity="error">{error}</Alert>
</Grid>
)}
</Grid>
</CardContent>
<CardActions>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState } from 'react';
import { createNodeTesterClient, NodeTester } from '@nymproject/sdk';

export type TestState = 'Ready' | 'Connecting' | 'Disconnected' | 'Disconnecting' | 'Error' | 'Testing' | 'Stopped';
Expand All @@ -8,26 +8,21 @@ export const useNodeTesterClient = () => {
const [error, setError] = useState<string>();
const [testState, setTestState] = useState<TestState>('Disconnected');

const createClient = async () => {
const createClient = async (validator: string) => {
setTestState('Connecting');
try {
const validator = 'https://validator.nymtech.net/api';
const nodeTesterClient = await createNodeTesterClient();

await nodeTesterClient.tester.init(validator);
await nodeTesterClient.tester.init(validator, validator);
setClient(nodeTesterClient);
setTestState('Ready');
} catch (e) {
console.log(e);
setError('Failed to load node tester client, please try again');
} finally {
setTestState('Ready');
setError('Failed to load node tester client, please try again. Error: ' + e.message);
setTestState('Error');
}
};

useEffect(() => {
createClient();
}, []);

const testNode = !client
? undefined
: async (mixnodeIdentity: string) => {
Expand All @@ -38,7 +33,7 @@ export const useNodeTesterClient = () => {
return result;
} catch (e) {
console.log(e);
setError('Failed to test node, please try again');
setError('Failed to test node, please try again. Error: ' + e.message);
setTestState('Error');
}
};
Expand Down Expand Up @@ -67,5 +62,5 @@ export const useNodeTesterClient = () => {
setTestState('Disconnected');
};

return { testNode, disconnectFromGateway, reconnectToGateway, terminateWorker, testState, error };
return { createClient, testNode, disconnectFromGateway, reconnectToGateway, terminateWorker, testState, error };
};