Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0d5cc11
payment redesign
andreip136 Dec 8, 2025
c29b939
auto loading button
andreip136 Dec 9, 2025
c91dff9
update loading
andreip136 Dec 9, 2025
0d95786
payment loading
andreip136 Dec 9, 2025
12cdd59
update loading
andreip136 Dec 9, 2025
8e41082
sign and open vscode
andreip136 Dec 9, 2025
13c9d77
fix build
andreip136 Dec 9, 2025
e3ae82f
alchemy integration
andreip136 Dec 10, 2025
e834747
hide wallet button
andreip136 Dec 10, 2025
8391cff
open editor
andreip136 Dec 10, 2025
f68816a
update vscode icon
andreip136 Dec 10, 2025
d14b1d6
fix build
andreip136 Dec 10, 2025
4d1b7e7
fetch token symbol
andreip136 Dec 10, 2025
eb501db
update token symbol logic
andreip136 Dec 10, 2025
89241d0
Merge branch 'feat/196-payment-redesign' into feat/123-transfer-funds…
ndrpp Dec 11, 2025
f384755
feat: add basic "send gas fees" functionality
ndrpp Dec 11, 2025
4be0453
Merge branch 'feat/redesign' into feat/123-transfer-funds-node-details
ndrpp Dec 12, 2025
331a4bf
feat: start base for withdraw
ndrpp Dec 12, 2025
585c87d
fix: improve withdraw modal styling
ndrpp Dec 15, 2025
d4499a6
feat: extend alchemy session time to 1 day | cleanup balance.tsx
ndrpp Dec 15, 2025
6f37633
feat: add fetch & push config functions in p2p context
ndrpp Dec 15, 2025
41ddd4c
feat: enable unban requests calls temporarily
ndrpp Dec 16, 2025
e38e44d
feat: update admin requests
ndrpp Dec 17, 2025
0fe1cce
chore: cleanup
ndrpp Dec 17, 2025
0a01ef0
Merge branch 'feat/redesign' into feat/127-get-push-node-config-node-…
ndrpp Dec 17, 2025
841eb53
Merge branch 'feat/redesign' into feat/123-transfer-funds-node-details
ndrpp Dec 17, 2025
ccb8f5d
feat: install json editor
ndrpp Dec 17, 2025
cec38d6
feat: improve modal with json editor & flows
ndrpp Dec 18, 2025
c974eec
Merge branch 'feat/redesign' into feat/123-transfer-funds-node-details
ndrpp Dec 18, 2025
02a9434
fix: type issue
ndrpp Dec 18, 2025
faebbf0
Merge branch 'feat/123-transfer-funds-node-details' into feat/127-get…
ndrpp Dec 18, 2025
aabf659
fix: modal window centering
ndrpp Dec 18, 2025
d0cec39
feat: switch to Dialog from material UI
ndrpp Dec 18, 2025
2539b27
chore: remove console.log
ndrpp Dec 19, 2025
114ac07
Merge branch 'feat/redesign' into feat/127-get-push-node-config-node-…
ndrpp Jan 7, 2026
2872cc8
chore: cleanup
ndrpp Jan 7, 2026
640c6fd
fix scroll
andreip136 Jan 7, 2026
70642f0
bump mui version
andreip136 Jan 7, 2026
e3dcaa0
fix: code review
ndrpp Jan 8, 2026
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
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@
"**/.next": true,
"**/out": true
},
"typescript.preferences.importModuleSpecifier": "non-relative"
"typescript.preferences.importModuleSpecifier": "non-relative",
"files.watcherExclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/.git/**": true
}
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"@libp2p/peer-id": "^4.1.4",
"@libp2p/ping": "^1.1.1",
"@libp2p/websockets": "^8.1.1",
"@mui/icons-material": "^7.3.4",
"@mui/material": "^7.3.4",
"@mui/icons-material": "^7.3.6",
"@mui/material": "^7.3.6",
"@mui/x-data-grid": "^8.14.1",
"@multiformats/multiaddr": "^12",
"@oceanprotocol/contracts": "2.5.0",
Expand All @@ -40,6 +40,7 @@
"formik": "^2.4.9",
"gsap": "3.13.0",
"it-pipe": "^3.0.1",
"json-edit-react": "^1.29.0",
"libp2p": "^1.8.0",
"myetherwallet-blockies": "^0.1.1",
"next": "^15.4.8",
Expand All @@ -65,7 +66,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-promise": "^6.6.0",
"prettier": "^3.3.3",
"prettier": "^3.7.4",
"prettier-plugin-organize-imports": "^4.3.0",
"typescript": "^5"
},
Expand Down
10 changes: 5 additions & 5 deletions src/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions src/components/node-details/config-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Button from '@/components/button/button';
import Modal from '@/components/modal/modal';
import { JsonEditor } from 'json-edit-react';
import { Dispatch, SetStateAction } from 'react';
import styles from './node-info.module.css';

type ConfigModalProps = {
isOpen: boolean;
fetchingConfig: boolean;
pushingConfig: boolean;
config: Record<string, any>;
editedConfig: Record<string, any>;
setEditedConfig: Dispatch<SetStateAction<Record<string, any>>>;
handlePushConfig: (config: Record<string, any>) => Promise<void>;
onClose: () => void;
};

const ConfigModal = ({
isOpen,
fetchingConfig,
pushingConfig,
config,
editedConfig,
setEditedConfig,
handlePushConfig,
onClose,
}: ConfigModalProps) => {
return (
<Modal isOpen={isOpen} onClose={onClose} title="Edit node config" width="xs">
<div className={styles.modalContent}>
{fetchingConfig && (!config || Object.keys(config).length === 0) ? (
<div className={styles.fetching}>Fetching config...</div>
) : (
<div className="flex flex-col" style={{ gap: '24px' }}>
<JsonEditor
data={editedConfig}
onUpdate={({ newData }) => setEditedConfig(newData as Record<string, any>)}
collapse={({ value }) => typeof value === 'object' && value !== null && Object.keys(value).length === 0}
/>
<Button
autoLoading
color="accent1"
loading={pushingConfig}
onClick={() => handlePushConfig(editedConfig)}
variant="filled"
>
Push config
</Button>
</div>
)}
</div>
</Modal>
);
};

export default ConfigModal;
8 changes: 5 additions & 3 deletions src/components/node-details/environments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EnvNodeInfo } from '@/types/environments';
import styles from './environments.module.css';

type EnvironmentsProps = {
nodeInfo: EnvNodeInfo;
nodeInfo: EnvNodeInfo;
};

const Environments = ({ nodeInfo }: EnvironmentsProps) => {
Expand All @@ -15,8 +15,10 @@ const Environments = ({ nodeInfo }: EnvironmentsProps) => {
<Card direction="column" padding="md" radius="lg" spacing="md" variant="glass-shaded">
<h3>Environments</h3>
<div className={styles.list}>
{!isReady ? <div>Fetching data...</div> : envs.map((env) =>
<EnvironmentCard key={env.id} environment={env} nodeInfo={nodeInfo} />
{!isReady ? (
<div>Fetching data...</div>
) : (
envs.map((env) => <EnvironmentCard key={env.id} environment={env} nodeInfo={nodeInfo} />)
)}
</div>
</Card>
Expand Down
22 changes: 22 additions & 0 deletions src/components/node-details/node-info.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@
display: flex;
gap: 8px;
}

.modalContent {
display: flex;
flex-direction: column;
gap: 24px;

.modalActions {
display: flex;
justify-content: flex-end;
padding-top: 16px;
border-top: 1px solid var(--border-glass);
}
}

.fetching {
display: flex;
justify-content: center;
align-items: center;
padding: 40px;
color: var(--text-secondary);
font-style: italic;
}
}

.infoFooter {
Expand Down
107 changes: 103 additions & 4 deletions src/components/node-details/node-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,109 @@ import Button from '@/components/button/button';
import Card from '@/components/card/card';
import { Balance } from '@/components/node-details/balance';
import Eligibility from '@/components/node-details/eligibility';
import { useP2P } from '@/contexts/P2PContext';
import { useOceanAccount } from '@/lib/use-ocean-account';
import { Node, NodeEligibility } from '@/types/nodes';
import { useAuthModal, useSignMessage, useSmartAccountClient } from '@account-kit/react';
import DnsIcon from '@mui/icons-material/Dns';
import DownloadIcon from '@mui/icons-material/Download';
import LocationPinIcon from '@mui/icons-material/LocationPin';
import PublicIcon from '@mui/icons-material/Public';
import UploadIcon from '@mui/icons-material/Upload';
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import ConfigModal from './config-modal';
import styles from './node-info.module.css';

type NodeInfoProps = {
node: Node;
};

const NodeInfo = ({ node }: NodeInfoProps) => {
const { client } = useSmartAccountClient({ type: 'LightAccount' });
const { signMessageAsync } = useSignMessage({
client,
});
const { openAuthModal } = useAuthModal();
const { account, ocean } = useOceanAccount();
const { config, fetchConfig, pushConfig } = useP2P();

const [fetchingConfig, setFetchingConfig] = useState<boolean>(false);
const [pushingConfig, setPushingConfig] = useState<boolean>(false);
const [isEditConfigDialogOpen, setIsEditConfigDialogOpen] = useState<boolean>(false);
const [editedConfig, setEditedConfig] = useState<Record<string, any>>({});

useEffect(() => {
if (config) {
setEditedConfig(config);
}
}, [config]);

async function handleFetchConfig() {
if (!account.isConnected) {
openAuthModal();
return;
}
if (!ocean || !node?.id) {
return;
}
const timestamp = Date.now() + 5 * 60 * 1000; // 5 minutes expiry
const signedMessage = await signMessageAsync({
message: timestamp.toString(),
});

setFetchingConfig(true);
try {
await fetchConfig(node.id, signedMessage, timestamp, account.address as string);
} catch (error) {
console.error('Error fetching node config :', error);
} finally {
setFetchingConfig(false);
}
}

async function handlePushConfig(config: Record<string, any>) {
let success = false;
if (!account.isConnected) {
openAuthModal();
return;
}
if (!ocean || !node?.id) {
return;
}
const timestamp = Date.now() + 5 * 60 * 1000; // 5 minutes expiry
const signedMessage = await signMessageAsync({
message: timestamp.toString(),
});

setPushingConfig(true);
try {
await pushConfig(node.id, signedMessage, timestamp, config, account.address as string);
success = true;
} catch (error) {
console.error('Error pushing node config :', error);
} finally {
setPushingConfig(false);
if (success) {
toast.success('Successfully pushed new config!');
setIsEditConfigDialogOpen(false);
} else {
toast.error('Failed to push new config');
}
}
}

function handleOpenEditConfigModal() {
if (!config || Object.keys(config).length === 0) {
handleFetchConfig();
}

setIsEditConfigDialogOpen(true);
}

function handleCloseModal() {
setIsEditConfigDialogOpen(false);
}

return (
<Card className={styles.root} padding="md" radius="lg" variant="glass-shaded">
<div className={styles.infoWrapper}>
Expand All @@ -39,10 +129,19 @@ const NodeInfo = ({ node }: NodeInfoProps) => {
</div>
</div>
<div className={styles.buttons}>
<Button contentBefore={<DownloadIcon />} variant="outlined">
Get node config
<ConfigModal
isOpen={isEditConfigDialogOpen}
fetchingConfig={fetchingConfig}
pushingConfig={pushingConfig}
config={config}
editedConfig={editedConfig}
setEditedConfig={setEditedConfig}
handlePushConfig={handlePushConfig}
onClose={handleCloseModal}
/>
<Button contentBefore={<UploadIcon />} onClick={handleOpenEditConfigModal} variant="outlined">
Edit node config
</Button>
<Button contentBefore={<UploadIcon />}>Set node config</Button>
</div>
</div>
<div className={styles.infoFooter}>
Expand Down
5 changes: 3 additions & 2 deletions src/components/node-details/unban-requests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ const UnbanRequests = ({ node }: UnbanRequestsProps) => {
}
setLoading(true);
try {
const timestamp = Date.now();
const timestamp = Date.now() + 5 * 60 * 1000; // 5 minutes expiry
const signedMessage = await signMessageAsync({
message: timestamp.toString(),
});
await requestNodeUnban(node.id, signedMessage, timestamp);

await requestNodeUnban(node.id, signedMessage as string, timestamp, account.address as string);
await fetchUnbanRequests(node.id);
} catch (error) {
console.error('Error requesting unban:', error);
Expand Down
26 changes: 15 additions & 11 deletions src/context/unban-requests-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type UnbanRequestsContextType = {
unbanRequests: UnbanRequest[];

fetchUnbanRequests: (nodeId: string) => Promise<void>;
requestNodeUnban: (nodeId: string, signature: string, expiryTimestamp: number) => Promise<void>;
requestNodeUnban: (nodeId: string, signature: string, expiryTimestamp: number, address: string) => Promise<void>;
};

const UnbanRequestsContext = createContext<UnbanRequestsContextType | undefined>(undefined);
Expand All @@ -29,16 +29,20 @@ export const UnbanRequestsProvider = ({ children }: { children: ReactNode }) =>
}
}, []);

const requestNodeUnban = useCallback(async (nodeId: string, signature: string, expiryTimestamp: number) => {
try {
await axios.post(`${getApiRoute('nodeUnbanRequests')}/${nodeId}/unban`, {
signature,
expiryTimestamp,
});
} catch (error) {
console.error('Error requesting node unban: ', error);
}
}, []);
const requestNodeUnban = useCallback(
async (nodeId: string, signature: string, expiryTimestamp: number, address: string) => {
try {
await axios.post(`${getApiRoute('nodeUnbanRequests')}/${nodeId}/unban`, {
signature,
expiryTimestamp,
address,
});
} catch (error) {
console.error('Error requesting node unban: ', error);
}
},
[]
);

return (
<UnbanRequestsContext.Provider
Expand Down
Loading
Loading