Skip to content

Commit 8c04fd6

Browse files
committed
feat: implement node activation system with 1 wallet = 1 node rule
- Add complete node activation flow with burn confirmation and success/error modals - Implement activation code generation in QNET-XXXXXX-XXXXXX-XXXXXX format (26 chars) - Add encryption for activation codes (same as seed phrase security) - Enforce strict 1 wallet = 1 node rule with multiple validation layers - Add protection against script-based bypasses and race conditions - Implement Export Activation Code feature in settings - Add visual feedback for active nodes (disabled options, status display) - Fix UI/UX issues with modals fitting in section without scrolling - Remove red warning colors, use consistent blue theme - Add detailed error messages for better user experience
1 parent a24cdc2 commit 8c04fd6

11 files changed

Lines changed: 526 additions & 342 deletions

File tree

.gitignore

101 Bytes
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"4njhgVBnkMFUFXnVvhE4zFfrfpG8qTccwqWXf2ArrGJP": 1759681837172
3+
}

applications/qnet-explorer/frontend/src/components/wallet/WalletConnection.tsx

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ interface QNetWallet {
77
isQNet?: boolean;
88
connect: () => Promise<string[]>;
99
disconnect: () => Promise<void>;
10-
getBalance: () => Promise<number>;
11-
getNetwork: () => Promise<string>;
12-
switchNetwork: (network: string) => Promise<void>;
13-
signTransaction: (tx: any) => Promise<string>;
14-
on: (event: string, callback: Function) => void;
15-
removeListener: (event: string, callback: Function) => void;
10+
getBalance?: () => Promise<number>;
11+
getNetwork?: () => Promise<string>;
12+
switchNetwork?: (network: string) => Promise<void>;
13+
signTransaction?: (tx: any) => Promise<string>;
14+
on?: (event: string, callback: Function) => void;
15+
removeListener?: (event: string, callback: Function) => void;
16+
request?: (args: { method: string; params?: any[] }) => Promise<any>;
17+
isConnected?: () => boolean;
18+
connected?: boolean;
19+
selectedAddress?: string | null;
20+
networkVersion?: string;
21+
version?: string;
1622
}
1723

24+
// Don't redeclare window.qnet since it's already declared in AppContext.tsx
25+
// Just extend the Window interface for ethereum
1826
declare global {
1927
interface Window {
20-
qnet?: QNetWallet;
2128
ethereum?: any;
2229
}
2330
}
@@ -74,8 +81,8 @@ export default function WalletConnection() {
7481
setWalletType('qnet');
7582

7683
// Get additional info
77-
const balance = await window.qnet.getBalance();
78-
const network = await window.qnet.getNetwork();
84+
const balance = window.qnet.getBalance ? await window.qnet.getBalance() : 0;
85+
const network = window.qnet.getNetwork ? await window.qnet.getNetwork() : 'qnet';
7986

8087
setBalance(balance);
8188
setNetwork(network);
@@ -111,15 +118,15 @@ export default function WalletConnection() {
111118
*/
112119
const setupWalletListeners = () => {
113120
// QNet Wallet listeners
114-
if (window.qnet) {
121+
if (window.qnet && window.qnet.on) {
115122
window.qnet.on('accountsChanged', handleAccountsChanged);
116123
window.qnet.on('networkChanged', handleNetworkChanged);
117124
window.qnet.on('disconnect', handleDisconnect);
118125
}
119126

120127
// Phantom listeners
121128
const phantom = (window as any).solana;
122-
if (phantom) {
129+
if (phantom && phantom.on) {
123130
phantom.on('accountChanged', handleAccountsChanged);
124131
phantom.on('disconnect', handleDisconnect);
125132
}
@@ -129,14 +136,14 @@ export default function WalletConnection() {
129136
* Cleanup wallet event listeners
130137
*/
131138
const cleanupWalletListeners = () => {
132-
if (window.qnet) {
139+
if (window.qnet && window.qnet.removeListener) {
133140
window.qnet.removeListener('accountsChanged', handleAccountsChanged);
134141
window.qnet.removeListener('networkChanged', handleNetworkChanged);
135142
window.qnet.removeListener('disconnect', handleDisconnect);
136143
}
137144

138145
const phantom = (window as any).solana;
139-
if (phantom) {
146+
if (phantom && phantom.removeListener) {
140147
phantom.removeListener('accountChanged', handleAccountsChanged);
141148
phantom.removeListener('disconnect', handleDisconnect);
142149
}
@@ -180,8 +187,8 @@ export default function WalletConnection() {
180187
const updateWalletInfo = async () => {
181188
try {
182189
if (walletType === 'qnet' && window.qnet) {
183-
const balance = await window.qnet.getBalance();
184-
const network = await window.qnet.getNetwork();
190+
const balance = window.qnet.getBalance ? await window.qnet.getBalance() : 0;
191+
const network = window.qnet.getNetwork ? await window.qnet.getNetwork() : 'qnet';
185192
setBalance(balance);
186193
setNetwork(network);
187194
}
@@ -215,8 +222,8 @@ export default function WalletConnection() {
215222
setWalletType('qnet');
216223

217224
// Get wallet info
218-
const balance = await window.qnet.getBalance();
219-
const network = await window.qnet.getNetwork();
225+
const balance = window.qnet.getBalance ? await window.qnet.getBalance() : 0;
226+
const network = window.qnet.getNetwork ? await window.qnet.getNetwork() : 'qnet';
220227

221228
setBalance(balance);
222229
setNetwork(network);
@@ -295,7 +302,17 @@ export default function WalletConnection() {
295302
if (walletType !== 'qnet' || !window.qnet) return;
296303

297304
try {
298-
await window.qnet.switchNetwork(targetNetwork);
305+
if (window.qnet.switchNetwork) {
306+
await window.qnet.switchNetwork(targetNetwork);
307+
} else if (window.qnet.request) {
308+
// Fallback to request method
309+
await window.qnet.request({
310+
method: 'wallet_switchEthereumChain',
311+
params: [{ chainId: targetNetwork }]
312+
});
313+
} else {
314+
throw new Error('Network switching not supported');
315+
}
299316
setNetwork(targetNetwork);
300317
await updateWalletInfo();
301318
console.log(`Switched to ${targetNetwork} network`);

applications/qnet-explorer/frontend/src/contexts/AppContext.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ interface QNetProvider {
1212
disconnect(): void;
1313
isConnected(): boolean;
1414
request(args: { method: string; params?: any[] }): Promise<any>;
15+
// Optional wallet-specific methods
16+
getBalance?(): Promise<number>;
17+
getNetwork?(): Promise<string>;
18+
switchNetwork?(network: string): Promise<void>;
19+
signTransaction?(tx: any): Promise<string>;
20+
on?(event: string, callback: Function): void;
21+
removeListener?(event: string, callback: Function): void;
1522
}
1623

1724
interface AppContextType {

0 commit comments

Comments
 (0)