Skip to content

Commit 4116c45

Browse files
committed
URGENT: Restore QNet browser extension from dist/ folder
- Restore applications/qnet-wallet/dist/ - production browser extension - This is NOT build artifacts but ready-to-use Chrome/Firefox extension - Critical component for QNet wallet functionality - Apologies for mistakenly removing in cleanup process - Extension contains production wallet interface and integration
1 parent b8b04a1 commit 4116c45

66 files changed

Lines changed: 24364 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
// QNet Wallet Background Script
3+
console.log('QNet Wallet Background Script Loaded');
4+
5+
// Basic message handling
6+
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
7+
console.log('Background message received:', request);
8+
sendResponse({ success: true });
9+
});
10+
11+
// Tab management
12+
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
13+
if (changeInfo.status === 'complete' && tab.url) {
14+
console.log('Tab updated:', tab.url);
15+
}
16+
});
Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
/**
2+
* QNet Wallet Content Script - Production Provider Injection
3+
* Injects wallet provider into page context for website interaction
4+
*/
5+
6+
// Don't run in extension popup/options pages
7+
if (window.location.protocol === 'chrome-extension:') {
8+
console.log('🚫 Content script skipped - running in extension context');
9+
// Exit early to prevent provider injection in extension pages
10+
return;
11+
}
12+
13+
console.log('🔧 QNet Content Script Loading on:', window.location.href);
14+
15+
// Inject the provider script into page context
16+
function injectQNetProvider() {
17+
try {
18+
console.log('🚀 Attempting to inject QNet provider...');
19+
20+
// Method 1: Try direct script injection
21+
const script = document.createElement('script');
22+
script.setAttribute('async', 'false');
23+
script.src = chrome.runtime.getURL('inject.js');
24+
25+
// Inject into page head or documentElement
26+
const target = document.head || document.documentElement;
27+
if (target) {
28+
target.appendChild(script);
29+
console.log('✅ QNet provider injection script loaded');
30+
31+
// Remove script element after injection
32+
script.onload = () => {
33+
script.remove();
34+
console.log('🧹 QNet injection script element removed');
35+
36+
// Verify injection worked
37+
setTimeout(() => {
38+
if (typeof window.qnet === 'undefined') {
39+
console.log('🔄 Direct injection failed, trying inline injection...');
40+
injectInlineProvider();
41+
}
42+
}, 100);
43+
};
44+
45+
script.onerror = (error) => {
46+
console.error('❌ QNet injection script error:', error);
47+
console.log('🔄 Script injection failed, trying inline injection...');
48+
injectInlineProvider();
49+
};
50+
} else {
51+
console.error('❌ No target element found for injection');
52+
injectInlineProvider();
53+
}
54+
} catch (error) {
55+
console.error('❌ Failed to inject QNet provider:', error);
56+
injectInlineProvider();
57+
}
58+
}
59+
60+
// Fallback: Inject provider code directly inline
61+
function injectInlineProvider() {
62+
try {
63+
console.log('🔄 Attempting inline QNet provider injection...');
64+
65+
const script = document.createElement('script');
66+
script.textContent = `
67+
(function() {
68+
'use strict';
69+
70+
// Prevent multiple injections
71+
if (window.qnet) {
72+
return;
73+
}
74+
75+
console.log('🚀 QNet Wallet Provider Injecting (Inline)...');
76+
77+
// QNet Wallet Provider Implementation
78+
class QNetWalletProvider {
79+
constructor() {
80+
this.isQNetWallet = true;
81+
this.connected = false;
82+
this.accounts = [];
83+
this.networkVersion = 'mainnet';
84+
this.requestId = 0;
85+
}
86+
87+
// Connect to wallet
88+
async connect() {
89+
try {
90+
const response = await this.request({ method: 'connect' });
91+
if (response && response.accounts) {
92+
this.accounts = response.accounts;
93+
this.connected = true;
94+
this.emit('accountsChanged', this.accounts);
95+
return this.accounts;
96+
}
97+
return [];
98+
} catch (error) {
99+
console.error('QNet connect error:', error);
100+
throw error;
101+
}
102+
}
103+
104+
// Disconnect from wallet
105+
async disconnect() {
106+
try {
107+
await this.request({ method: 'disconnect' });
108+
this.accounts = [];
109+
this.connected = false;
110+
this.emit('accountsChanged', []);
111+
this.emit('disconnect');
112+
} catch (error) {
113+
console.error('QNet disconnect error:', error);
114+
}
115+
}
116+
117+
// Check if connected
118+
isConnected() {
119+
return this.connected && this.accounts.length > 0;
120+
}
121+
122+
// Get accounts
123+
getAccounts() {
124+
return this.accounts;
125+
}
126+
127+
// Request method - main communication with extension
128+
async request(args) {
129+
return new Promise((resolve, reject) => {
130+
const id = ++this.requestId;
131+
132+
// Listen for response
133+
const responseHandler = (event) => {
134+
if (event.source !== window) return;
135+
136+
const data = event.data;
137+
if (!data || data.target !== 'qnet-wallet-inject' || data.id !== id) return;
138+
139+
window.removeEventListener('message', responseHandler);
140+
141+
if (data.error) {
142+
reject(new Error(data.error.message || 'Request failed'));
143+
} else {
144+
resolve(data.result);
145+
}
146+
};
147+
148+
window.addEventListener('message', responseHandler);
149+
150+
// Send request to content script
151+
window.postMessage({
152+
target: 'qnet-wallet-content',
153+
method: args.method,
154+
params: args.params || {},
155+
id: id
156+
}, '*');
157+
158+
// Timeout after 30 seconds
159+
setTimeout(() => {
160+
window.removeEventListener('message', responseHandler);
161+
reject(new Error('Request timeout'));
162+
}, 30000);
163+
});
164+
}
165+
166+
// Event handling
167+
on(event, handler) {
168+
if (!this.listeners) this.listeners = {};
169+
if (!this.listeners[event]) this.listeners[event] = [];
170+
this.listeners[event].push(handler);
171+
}
172+
173+
removeListener(event, handler) {
174+
if (!this.listeners || !this.listeners[event]) return;
175+
const index = this.listeners[event].indexOf(handler);
176+
if (index > -1) {
177+
this.listeners[event].splice(index, 1);
178+
}
179+
}
180+
181+
emit(event, ...args) {
182+
if (!this.listeners || !this.listeners[event]) return;
183+
this.listeners[event].forEach(handler => {
184+
try {
185+
handler(...args);
186+
} catch (error) {
187+
console.error('QNet event handler error:', error);
188+
}
189+
});
190+
}
191+
192+
// Sign transaction
193+
async signTransaction(transaction) {
194+
return this.request({
195+
method: 'signTransaction',
196+
params: { transaction }
197+
});
198+
}
199+
200+
// Sign and send transaction
201+
async signAndSendTransaction(transaction) {
202+
return this.request({
203+
method: 'signAndSendTransaction',
204+
params: { transaction }
205+
});
206+
}
207+
208+
// Sign message
209+
async signMessage(message) {
210+
return this.request({
211+
method: 'signMessage',
212+
params: { message }
213+
});
214+
}
215+
}
216+
217+
// Create and inject provider
218+
const qnetProvider = new QNetWalletProvider();
219+
220+
// Inject into window
221+
Object.defineProperty(window, 'qnet', {
222+
value: qnetProvider,
223+
writable: false,
224+
configurable: false
225+
});
226+
227+
// Also provide as qnetWallet for compatibility
228+
Object.defineProperty(window, 'qnetWallet', {
229+
value: qnetProvider,
230+
writable: false,
231+
configurable: false
232+
});
233+
234+
console.log('✅ QNet Wallet Provider Injected (Inline)');
235+
236+
// Dispatch ready event
237+
window.dispatchEvent(new CustomEvent('qnet#initialized', {
238+
detail: qnetProvider
239+
}));
240+
241+
})();
242+
`;
243+
244+
const target = document.head || document.documentElement;
245+
if (target) {
246+
target.appendChild(script);
247+
script.remove(); // Remove immediately after execution
248+
console.log('✅ QNet provider injected inline successfully');
249+
}
250+
251+
} catch (error) {
252+
console.error('❌ Failed to inject inline provider:', error);
253+
}
254+
}
255+
256+
// Message relay between page and extension
257+
function setupMessageRelay() {
258+
console.log('🔗 Setting up QNet message relay...');
259+
260+
// Listen for messages from page
261+
window.addEventListener('message', async (event) => {
262+
if (event.source !== window) return;
263+
264+
const data = event.data;
265+
if (!data || data.target !== 'qnet-wallet-content') return;
266+
267+
console.log('📨 Content script received message:', data);
268+
269+
try {
270+
// Forward request to background script
271+
const response = await chrome.runtime.sendMessage({
272+
type: 'WALLET_REQUEST',
273+
method: data.method,
274+
params: data.params,
275+
id: data.id
276+
});
277+
278+
console.log('📤 Background response:', response);
279+
280+
// Send response back to page
281+
window.postMessage({
282+
target: 'qnet-wallet-inject',
283+
id: data.id,
284+
result: response.result,
285+
error: response.error
286+
}, '*');
287+
288+
} catch (error) {
289+
console.error('Content script message relay error:', error);
290+
291+
// Send error response back to page
292+
window.postMessage({
293+
target: 'qnet-wallet-inject',
294+
id: data.id,
295+
error: { message: error.message || 'Communication error' }
296+
}, '*');
297+
}
298+
});
299+
300+
console.log('✅ QNet message relay established');
301+
}
302+
303+
// Main initialization
304+
function initializeQNetWallet() {
305+
console.log('🎯 Initializing QNet Wallet on:', window.location.href);
306+
307+
// Only inject once
308+
if (window.qnetWalletInjected) {
309+
console.log('⚠️ QNet Wallet already injected, skipping');
310+
return;
311+
}
312+
313+
window.qnetWalletInjected = true;
314+
315+
// Setup message relay first
316+
setupMessageRelay();
317+
318+
// Inject provider script
319+
if (document.readyState === 'loading') {
320+
console.log('📄 Document loading, waiting for DOMContentLoaded...');
321+
document.addEventListener('DOMContentLoaded', injectQNetProvider);
322+
} else {
323+
console.log('📄 Document ready, injecting immediately...');
324+
injectQNetProvider();
325+
}
326+
327+
// Also check periodically if window.qnet exists
328+
let checkCount = 0;
329+
const checkInterval = setInterval(() => {
330+
checkCount++;
331+
const hasQnet = typeof window.qnet !== 'undefined';
332+
console.log(`🔍 Check ${checkCount}: window.qnet exists:`, hasQnet);
333+
334+
if (hasQnet || checkCount >= 10) {
335+
clearInterval(checkInterval);
336+
if (hasQnet) {
337+
console.log('✅ QNet provider successfully injected and accessible');
338+
} else {
339+
console.error('❌ QNet provider not accessible after 10 checks');
340+
}
341+
}
342+
}, 1000);
343+
}
344+
345+
// Initialize immediately for early injection
346+
console.log('🚀 QNet Content Script: Starting initialization...');
347+
initializeQNetWallet();
348+
349+
// Also handle late navigation
350+
if (document.readyState !== 'complete') {
351+
window.addEventListener('load', () => {
352+
console.log('🔄 Window loaded, re-initializing QNet Wallet...');
353+
initializeQNetWallet();
354+
});
355+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
// QNet Wallet Inject Script
3+
console.log('QNet Wallet Inject Script Loaded');
4+
5+
// Inject wallet provider
6+
if (typeof window !== 'undefined') {
7+
window.qnet = {
8+
isQNet: true,
9+
version: '2.0.0',
10+
network: 'testnet'
11+
};
12+
}

0 commit comments

Comments
 (0)