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
42 changes: 42 additions & 0 deletions CHROME_STORE_LISTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Chrome Web Store Listing – Lumen Wallet

## Extension Name
Lumen Wallet

## Short Description (≤ 132 chars)
Non‑custodial Lumen wallet with PQC support, swaps, and secure dApp connections.

## Detailed Description
Lumen Wallet is a non‑custodial browser extension for the Lumen blockchain.
It lets you create and manage Lumen accounts, connect to dApps, and sign transactions securely.

**Key features**
- Non‑custodial: keys are encrypted and stored locally
- PQC‑ready signing (Dilithium3)
- dApp connection & transaction approvals
- Swap v1 support (Lumen ecosystem)
- Multi‑account support

**Security & Privacy**
- We never store or transmit your seed phrase or private keys.
- All signing happens locally in the extension.

**Network**
- Uses public Lumen RPC/REST endpoints for chain data.

## Category
Productivity / Developer Tools / Finance (choose best fit)

## Website / Support
- Website: `https://YOUR_DOMAIN_HERE`
- Support: `support@YOUR_DOMAIN_HERE`

## Privacy Policy URL
`https://YOUR_DOMAIN_HERE/privacy`

## Keywords (optional)
Lumen, Cosmos, wallet, blockchain, PQC, Dilithium, crypto, non‑custodial

## Notes for Reviewers (optional)
This extension injects a provider to enable dApps to request wallet actions.
All sensitive data remains on device.
30 changes: 30 additions & 0 deletions PERMISSIONS_JUSTIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Permissions Justification – Lumen Wallet

This document explains why each permission is required.

## Chrome Extension Permissions
- **storage**
Store encrypted wallet vault, user settings, connected dApps, and pending approvals locally.

- **sidePanel**
Show approval requests consistently without opening multiple popups.

- **contextMenus**
Provide quick access actions from the extension icon menu.

## Host Permissions (Optional)
The extension interacts with Lumen RPC/REST endpoints to query balances, chain state, and submit transactions.

### Why broad host permissions exist
The extension is intended to connect to many dApps across different domains.
Some flows require access to specific RPC/REST endpoints and dApp domains.

> NOTE: For production, we recommend restricting or dynamically requesting host permissions only for approved domains.

## Content Script Injection
The provider is injected so dApps can request wallet actions (connect, sign, etc.).
This is standard for blockchain wallets and is required for compatibility with dApps.

---

If any reviewer needs more details, contact: `support@YOUR_DOMAIN_HERE`.
18 changes: 18 additions & 0 deletions PRIVACY_POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Lumen Wallet Privacy Policy

**Last updated:** 2026-02-15

Lumen Wallet is a non‑custodial browser extension for the Lumen blockchain. This policy explains what data is handled and how.

## Summary
- We do **not** collect, sell, or share personal data.
- Wallet keys are generated and stored **locally** on your device, encrypted with your password.
- No seed phrase or private key is ever sent to our servers.

## Data We Store Locally
The extension stores the following data **only on your device**:
- Encrypted wallet vault (keys + PQC data)
- Connected dApp permissions (approved domains)
- Recent settings (theme, active account, etc.)

## Network Requests
18 changes: 18 additions & 0 deletions SECURITY_REVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Security Review (Internal)

## Scope
- Inpage ↔ Content Script ↔ Background message flow
- Permission gating & approvals
- Wallet vault storage & session handling
- Transaction signing (Amino / Direct)

## Findings Checklist
- [ ] No seed/private key leakage in logs
- [ ] Origin validation for provider requests
- [ ] Approval requires explicit user gesture
- [ ] Pending queue recovery on service worker restart
- [ ] ChainId strict checking (Lumen only)
- [ ] RPC/REST endpoints health check & fallback

## Reviewer Notes
Add notes and date here after internal review.
19 changes: 19 additions & 0 deletions STORE_SUBMISSION_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Chrome Store Submission Checklist

## Required (before submit)
- [ ] **Privacy Policy URL** hosted publicly (HTTPS)
- [ ] **Support contact** (email + website)
- [ ] **Data Disclosure** completed in Chrome Web Store dashboard
- [ ] **Permission justifications** ready for reviewer
- [ ] **Screenshots + icon assets** uploaded

## Data Disclosure (suggested answers)
- **Data collected:** None
- **Data shared:** None
- **Data sold:** No
- **Data processed off device:** No (all keys stay local)

## Notes for Reviewer
- Non‑custodial wallet, keys stored locally and encrypted
- dApp approval requires explicit user consent
- RPC/REST endpoints are public network calls for chain data
218 changes: 218 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,221 @@ if (typeof chrome !== 'undefined' && chrome.contextMenus && chrome.contextMenus.
}
});
}

/**
* LUMEN WALLET PROVIDER - BACKGROUND SERVICE WORKER
*
* This is the central hub for all wallet operations.
* It receives requests from Content Scripts and processes them.
*
* RESPONSIBILITIES:
* - Handle provider requests (enable, sign, send transactions, etc.)
* - Manage wallet state and storage
* - Trigger popup/notifications for user confirmations
* - Emit events to connected dApps (accountsChanged, chainChanged)
*/

// Message handler for provider requests
if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onMessage) {
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// Only handle Lumen provider requests
if (message.type !== 'lumen-provider-request') {
return false; // Not our message
}

console.log('[Lumen Background] Received request:', message);

// Handle async processing
handleProviderRequest(message, sender)
.then(response => sendResponse(response))
.catch(error => {
console.error('[Lumen Background] Error:', error);
sendResponse({ error: error.message || 'Request failed' });
});

// Return true to indicate async response
return true;
});
}

/**
* Process provider requests
* @param {Object} message - Request from content script
* @param {Object} sender - Chrome sender info (tab, frameId, etc.)
* @returns {Promise<Object>} Response object with data or error
*/
async function handleProviderRequest(message, sender) {
const { method, params, origin } = message;

try {
switch (method) {
// Wallet connection/enable request
case 'eth_requestAccounts':
case 'enable':
return await handleEnable(origin, sender.tab);

// Get current accounts
case 'eth_accounts':
return await handleGetAccounts(origin);

// Chain ID request
case 'eth_chainId':
case 'net_version':
return await handleGetChainId();

// Sign transaction
case 'eth_sendTransaction':
return await handleSendTransaction(params, origin, sender.tab);

// Sign message
case 'personal_sign':
case 'eth_sign':
return await handleSignMessage(params, origin, sender.tab);

// Sign typed data (EIP-712)
case 'eth_signTypedData':
case 'eth_signTypedData_v3':
case 'eth_signTypedData_v4':
return await handleSignTypedData(params, origin, sender.tab);

// Add network/chain
case 'wallet_addEthereumChain':
return await handleAddChain(params, origin, sender.tab);

// Switch network/chain
case 'wallet_switchEthereumChain':
return await handleSwitchChain(params, origin, sender.tab);

// Cosmos-specific methods (for Lumen chain)
case 'cosmos_getKey':
case 'getKey':
return await handleCosmosGetKey(params?.chainId);

case 'cosmos_signAmino':
case 'signAmino':
return await handleCosmosSignAmino(params, origin, sender.tab);

case 'cosmos_signDirect':
case 'signDirect':
return await handleCosmosSignDirect(params, origin, sender.tab);

default:
throw new Error(`Unsupported method: ${method}`);
}
} catch (error) {
console.error(`[Lumen Background] Error handling ${method}:`, error);
return { error: error.message };
}
}

/**
* PLACEHOLDER HANDLERS
* These should be implemented with actual wallet logic
*/

async function handleEnable(origin, tab) {
// TODO: Check if wallet is locked - if so, open unlock screen
// TODO: Check if origin is already connected
// TODO: If not, open approval popup for user to approve/reject connection
// TODO: Return array of account addresses

console.log('[Lumen] Enable request from:', origin);

// Placeholder response - replace with actual wallet logic
return {
data: ['0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1'] // Example address
};
}

async function handleGetAccounts(origin) {
// TODO: Check if origin is connected
// TODO: Return accounts only if connected, empty array otherwise

console.log('[Lumen] Get accounts request from:', origin);
return {
data: ['0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1']
};
}

async function handleGetChainId() {
// TODO: Return current chain ID from wallet state
console.log('[Lumen] Get chain ID request');
return {
data: '0x1' // Mainnet
};
}

async function handleSendTransaction(params, origin, tab) {
// TODO: Validate transaction
// TODO: Open popup for user confirmation
// TODO: Sign and broadcast transaction
// TODO: Return transaction hash

console.log('[Lumen] Send transaction request:', params);
throw new Error('Transaction signing not yet implemented');
}

async function handleSignMessage(params, origin, tab) {
// TODO: Open popup for user to review and sign message
// TODO: Sign with private key
// TODO: Return signature

console.log('[Lumen] Sign message request:', params);
throw new Error('Message signing not yet implemented');
}

async function handleSignTypedData(params, origin, tab) {
// TODO: Parse and validate EIP-712 typed data
// TODO: Open popup for user to review
// TODO: Sign and return signature

console.log('[Lumen] Sign typed data request:', params);
throw new Error('Typed data signing not yet implemented');
}

async function handleAddChain(params, origin, tab) {
// TODO: Validate chain parameters
// TODO: Prompt user to add chain
// TODO: Save to storage if approved

console.log('[Lumen] Add chain request:', params);
return { data: null };
}

async function handleSwitchChain(params, origin, tab) {
// TODO: Check if chain exists
// TODO: Switch active chain
// TODO: Emit chainChanged event

console.log('[Lumen] Switch chain request:', params);
throw new Error('Chain switching not yet implemented');
}

// Cosmos-specific handlers for Lumen chain
async function handleCosmosGetKey(chainId) {
// TODO: Return public key and address for specified chain
console.log('[Lumen] Cosmos getKey request:', chainId);
throw new Error('Cosmos key retrieval not yet implemented');
}

async function handleCosmosSignAmino(params, origin, tab) {
// TODO: Sign Amino transaction (legacy Cosmos tx format)
console.log('[Lumen] Cosmos signAmino request:', params);
throw new Error('Cosmos Amino signing not yet implemented');
}

async function handleCosmosSignDirect(params, origin, tab) {
// TODO: Sign Direct transaction (Protobuf Cosmos tx format)
console.log('[Lumen] Cosmos signDirect request:', params);
throw new Error('Cosmos Direct signing not yet implemented');
}

/**
* Emit events to connected tabs
* Call this when accounts or chain changes
*/
async function emitProviderEvent(eventName, data) {
// TODO: Get all connected tabs
// TODO: Send message to content scripts in those tabs
console.log('[Lumen] Would emit event:', eventName, data);
}
Binary file removed chrome-extension.1.0.0.zip
Binary file not shown.
27 changes: 21 additions & 6 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
"sidePanel",
"contextMenus"
],
"host_permissions": [
"http://142.132.201.187:1317/*",
"http://142.132.201.187:26657/*",
"http://142.132.201.187:9190/*",
"optional_host_permissions": [
"https://*/*",
"http://*/*",
"https://*/*"
"https://rpc.lumen.chaintools.tech/*",
"https://lumen.blocksync.me/*",
"https://lumen-mainnet-rpc.mekonglabs.com/*",
"https://rpc-lumen.onenov.xyz/*",
"https://lumen-api.node9x.com/*",
"https://api.lumen.chaintools.tech/*",
"https://lumen-mainnet-api.mekonglabs.com/*",
"https://lumen-api.linknode.org/*",
"https://api-lumen.winnode.xyz/*"
],
"side_panel": {
"default_path": "index.html"
Expand All @@ -40,11 +46,20 @@
"48": "icons/logo.png",
"128": "icons/logo.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["contentScript.js"],
"run_at": "document_start",
"all_frames": true
}
],
"web_accessible_resources": [
{
"resources": [
"*.wasm",
"dilithium3.wasm"
"dilithium3.wasm",
"inject.js"
],
"matches": [
"<all_urls>"
Expand Down
Loading