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
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"dependencies": {
"@tailwindcss/cli": "^4.1.14",
"electron-store": "^8.2.0",
"lucide": "^1.7.0",
"tailwindcss": "^4.1.14"
}
}
4 changes: 3 additions & 1 deletion src/components/connection/ConnectionStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Bitcoin Core Connection Status Component
* Shows connection progress and status while connecting to bitcoind
*/
import { icons } from '../../js/icons.js';

export function ConnectionStatusComponent(container, onConnected) {
const connectionDiv = document.createElement('div');
connectionDiv.id = 'connection-status';
Expand Down Expand Up @@ -60,7 +62,7 @@ export function ConnectionStatusComponent(container, onConnected) {
<!-- Error Display (hidden by default) -->
<div id="connection-error" class="hidden mt-4 bg-red-500/10 border border-red-500/30 rounded-lg p-4">
<div class="flex items-start">
<span class="text-red-400 mr-2">⚠️</span>
<span class="text-red-400 mr-2">${icons.alertTriangle(16)}</span>
<div>
<p class="text-sm font-medium text-red-400">Connection Failed</p>
<p id="error-message" class="text-xs text-red-300 mt-1"></p>
Expand Down
8 changes: 5 additions & 3 deletions src/components/log/Log.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { icons } from '../../js/icons.js';

export function LogComponent(container) {
const content = document.createElement('div');
content.id = 'log-content';
Expand Down Expand Up @@ -148,7 +150,7 @@ export function LogComponent(container) {

<div class="bg-blue-500/10 border border-blue-500/30 rounded-lg p-4 mb-6">
<div class="flex items-start gap-3">
<span class="text-2xl">💡</span>
<span>${icons.lightbulb(24)}</span>
<div class="flex-1">
<p class="text-blue-400 text-sm">
<strong>Limited view:</strong> Only the last ${MAX_LOGS} log lines are shown here for performance.
Expand All @@ -171,10 +173,10 @@ export function LogComponent(container) {
</div>
<div class="flex gap-2">
<button id="refresh-logs" class="bg-[#242d3d] hover:bg-[#2d3748] text-white px-4 py-2 rounded text-sm transition-colors">
🔄 Refresh
${icons.refreshCw(14, 'mr-1')} Refresh
</button>
<button id="open-log-file" class="bg-[#FF6B35] hover:bg-[#ff7d4d] text-white px-4 py-2 rounded text-sm font-semibold transition-colors">
📁 Open Log File
${icons.folder(14, 'mr-1')} Open Log File
</button>
</div>
</div>
Expand Down
20 changes: 11 additions & 9 deletions src/components/market/Market.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { icons } from '../../js/icons.js';

export function Market(container) {
const content = document.createElement('div');
content.id = 'market-content';
Expand All @@ -16,7 +18,7 @@ export function Market(container) {
case 'Taproot':
return {
label: 'Taproot',
icon: '⚡',
icon: icons.zap(14),
classes: 'bg-purple-500/20 text-purple-400',
};
case 'Unified':
Expand All @@ -30,7 +32,7 @@ export function Market(container) {
default:
return {
label: 'Legacy',
icon: '🔒',
icon: icons.lock(14),
classes: 'bg-blue-500/20 text-blue-400',
};
}
Expand Down Expand Up @@ -478,7 +480,7 @@ export function Market(container) {
'fixed top-4 right-4 bg-red-500 text-white px-6 py-3 rounded-lg shadow-lg z-50 max-w-md';
errorDiv.innerHTML = `
<div class="flex items-start gap-3">
<span class="text-xl"></span>
<span class="text-xl">${icons.xCircle(20)}</span>
<div class="flex-1">
<div class="font-semibold text-lg mb-1">Error</div>
<div class="text-sm">${message}</div>
Expand Down Expand Up @@ -617,7 +619,7 @@ export function Market(container) {
<div class="bg-[#0f1419] rounded-lg p-6 border border-blue-500/30">
<div class="flex items-center justify-between mb-4">
<span class="text-lg font-semibold text-lg text-blue-400">
🔄 Syncing Market Data...
${icons.refreshCw(16, 'mr-2 animate-spin')} Syncing Market Data...
</span>
<span class="text-sm text-gray-400">
Please wait
Expand Down Expand Up @@ -665,7 +667,7 @@ export function Market(container) {

<div class="flex items-center justify-center text-xs text-gray-400 mt-2">
<div class="text-cyan-400">
🔍 Discovering makers over Tor network...
${icons.search(16, 'mr-2')} Discovering makers over Tor network...
</div>
</div>
</div>
Expand Down Expand Up @@ -808,7 +810,7 @@ export function Market(container) {

<div class="bg-[#1a2332] rounded-lg p-6 mb-6">
<div class="flex items-start gap-3">
<span class="text-2xl">ℹ️</span>
<span class="text-[#FF6B35]">${icons.info(24)}</span>
<div>
<h3 class="text-lg font-semibold text-lg text-[#FF6B35] mb-2">Fee Calculation</h3>
<p class="text-gray-300 mb-2">Total fee for a swap is calculated as:</p>
Expand Down Expand Up @@ -841,13 +843,13 @@ export function Market(container) {
<!-- Maker Status Tabs -->
<div class="flex border-b-2 border-[#FF6B35]">
<button id="tab-good" class="flex-1 px-6 py-4 font-semibold text-lg bg-[#FF6B35] text-white border-b-4 border-[#FF6B35] transition-all">
Good Makers (<span id="good-count">0</span>)
${icons.checkCircle(14, 'mr-1')} Good Makers (<span id="good-count">0</span>)
</button>
<button id="tab-bad" class="flex-1 px-6 py-4 font-semibold text-lg bg-[#1a2332] text-gray-400 border-b-4 border-transparent hover:text-white hover:border-gray-600 transition-all">
Bad Makers (<span id="bad-count">0</span>)
${icons.xCircle(14, 'mr-1')} Bad Makers (<span id="bad-count">0</span>)
</button>
<button id="tab-unresponsive" class="flex-1 px-6 py-4 font-semibold text-lg bg-[#1a2332] text-gray-400 border-b-4 border-transparent hover:text-white hover:border-gray-600 transition-all">
⏸️ Unresponsive (<span id="unresponsive-count">0</span>)
${icons.pauseCircle(14, 'mr-1')} Unresponsive (<span id="unresponsive-count">0</span>)
</button>
</div>

Expand Down
10 changes: 6 additions & 4 deletions src/components/receive/AddressList.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { icons } from '../../js/icons.js';

export function AddressListComponent(container) {
let currentFilter = 'all';
let sortBy = 'newest';
Expand Down Expand Up @@ -218,7 +220,7 @@ const result = await window.api.taker.getTransactions(200, 0);
</div>
<div class="flex gap-2">
<button id="export-addresses" class="bg-[#242d3d] hover:bg-[#2d3748] text-white px-4 py-2 rounded-lg text-sm font-semibold text-lg transition-colors">
📥 Export CSV
${icons.arrowDownCircle(14, 'mr-1')} Export CSV
</button>
<button id="refresh-addresses" class="bg-[#FF6B35] hover:bg-[#ff7d4d] text-white px-4 py-2 rounded-lg text-sm font-semibold text-lg transition-colors">
Refresh
Expand Down Expand Up @@ -292,7 +294,7 @@ const result = await window.api.taker.getTransactions(200, 0);
filteredAddresses.length === 0
? `
<div class="text-center py-12">
<div class="text-4xl mb-4">📭</div>
<div class="text-gray-500 mb-4 flex justify-center">${icons.inbox(48)}</div>
<p class="text-gray-400 mb-4">No addresses ${currentFilter !== 'all' ? `for ${currentFilter} spend type` : 'found in transaction history'}</p>
<button id="go-to-receive" class="bg-[#FF6B35] hover:bg-[#ff7d4d] text-white font-semibold text-lg px-6 py-2 rounded-lg transition-colors">
Generate New Address
Expand Down Expand Up @@ -336,7 +338,7 @@ const result = await window.api.taker.getTransactions(200, 0);
${addr.address.substring(0, 12)}...${addr.address.substring(addr.address.length - 8)}
</a>
<button class="copy-btn text-gray-500 hover:text-[#FF6B35] transition-colors" data-address="${addr.address}" title="Copy address">
📋
${icons.clipboardCopy(14)}
</button>
</div>
</td>
Expand Down Expand Up @@ -430,7 +432,7 @@ const result = await window.api.taker.getTransactions(200, 0);
await copyToClipboard(address);
btn.textContent = '✓';
setTimeout(() => {
btn.textContent = '📋';
btn.innerHTML = icons.clipboardCopy(14);
}, 1500);
});
});
Expand Down
14 changes: 8 additions & 6 deletions src/components/receive/Receive.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { icons } from '../../js/icons.js';

export function ReceiveComponent(container) {
const content = document.createElement('div');
content.id = 'receive-content';
Expand Down Expand Up @@ -43,7 +45,7 @@ export function ReceiveComponent(container) {
<button id="generate-new" disabled class="w-full bg-[#242d3d] hover:bg-[#2d3748] disabled:bg-gray-700 disabled:cursor-not-allowed text-white font-semibold text-lg py-3 rounded-lg transition-colors border border-gray-700">
<span class="generate-text">Generate New Address</span>
<span class="generate-loading hidden">
<span class="inline-block animate-spin mr-2"></span>
<span class="inline-block animate-spin mr-2">${icons.loader(16)}</span>
Generating...
</span>
</button>
Expand All @@ -54,7 +56,7 @@ export function ReceiveComponent(container) {
<!-- Info Card -->
<div class="mt-6 p-3 bg-red-500/10 border border-red-500/30 rounded-lg">
<p class="text-xs text-red-400">
⚠️ Reusing addresses can cause significant privacy reduction. Always generate a fresh address for each transaction to maintain anonymity.
${icons.alertTriangle(16, 'mr-1')} Reusing addresses can cause significant privacy reduction. Always generate a fresh address for each transaction to maintain anonymity.
</p>
</div>

Expand Down Expand Up @@ -226,7 +228,7 @@ export function ReceiveComponent(container) {
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
copyButton.textContent = '✓ Copied!';
copyButton.innerHTML = icons.check(14, 'mr-1') + ' Copied!';
copyButton.classList.add('bg-green-500');
copyButton.classList.remove('bg-[#FF6B35]');

Expand All @@ -245,7 +247,7 @@ export function ReceiveComponent(container) {
document.execCommand('copy');
document.body.removeChild(textArea);

copyButton.textContent = '✓ Copied!';
copyButton.innerHTML = icons.check(14, 'mr-1') + ' Copied!';
setTimeout(() => {
copyButton.textContent = 'Copy';
}, 2000);
Expand Down Expand Up @@ -444,7 +446,7 @@ export function ReceiveComponent(container) {
currentAddressEl.textContent = `Error: ${error.message}`;
qrContainer.innerHTML = `
<div class="text-center text-red-400 p-4">
<p class="text-2xl mb-2">❌</p>
<div class="flex justify-center mb-2">${icons.xCircle(40, 'text-red-400')}</div>
<p class="text-sm">Address generation failed</p>
<p class="text-xs text-gray-500 mt-2">${error.message}</p>
</div>
Expand Down Expand Up @@ -473,7 +475,7 @@ export function ReceiveComponent(container) {
currentAddressEl.textContent = 'Failed to initialize';
qrContainer.innerHTML = `
<div class="text-center text-red-400 p-4">
<p class="text-2xl mb-2">❌</p>
<div class="flex justify-center mb-2">${icons.xCircle(40, 'text-red-400')}</div>
<p class="text-sm">Initialization failed</p>
<button onclick="location.reload()" class="mt-2 text-xs underline">Retry</button>
</div>
Expand Down
24 changes: 13 additions & 11 deletions src/components/send/Send.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { icons } from '../../js/icons.js';

export function SendComponent(container, preSelectedUtxos = null) {
const content = document.createElement('div');
content.id = 'send-content';
Expand Down Expand Up @@ -122,13 +124,13 @@ export function SendComponent(container, preSelectedUtxos = null) {
if (!signBtn) return;

if (errors.length === 0) {
signBtn.textContent = '🔏 Sign Transaction';
signBtn.innerHTML = icons.key(14, 'mr-1') + ' Sign Transaction';
signBtn.title = '';
return;
}

// Show first error as button text
signBtn.textContent = '⚠️ ' + errors[0];
signBtn.innerHTML = icons.alertTriangle(14, 'mr-1') + ' ' + errors[0];
signBtn.title = errors.join('\n');
}

Expand Down Expand Up @@ -659,7 +661,7 @@ export function SendComponent(container, preSelectedUtxos = null) {
signedTx = { id: 'simulated-tx' };
signedTxHex = '0200000001' + 'ff'.repeat(100);

alert('Transaction signed successfully!\n\nReview the details and click "Broadcast" to send.');
alert('Transaction signed successfully!\n\nReview the details and click "Broadcast" to send.');

const hexPanel = content.querySelector('#hex-panel');
if (hexPanel) hexPanel.classList.remove('hidden');
Expand All @@ -671,7 +673,7 @@ export function SendComponent(container, preSelectedUtxos = null) {

} catch (error) {
console.error('Signing failed:', error);
alert(`Failed to sign: ${error.message}`);
alert(`Failed to sign: ${error.message}`);
} finally {
signBtn.disabled = false;
signBtn.textContent = originalText;
Expand Down Expand Up @@ -754,7 +756,7 @@ export function SendComponent(container, preSelectedUtxos = null) {

} catch (error) {
console.error('Broadcast failed:', error);
alert(`Failed to broadcast: ${error.message}`);
alert(`Failed to broadcast: ${error.message}`);
} finally {
broadcastBtn.disabled = false;
broadcastBtn.textContent = originalText;
Expand All @@ -768,7 +770,7 @@ export function SendComponent(container, preSelectedUtxos = null) {
popup.innerHTML = `
<div class="bg-[#1a2332] rounded-lg p-8 max-w-2xl w-full mx-4 border border-green-500/50">
<div class="text-center mb-6">
<div class="text-6xl mb-4"></div>
<div class="flex justify-center mb-4">${icons.checkCircle(64, 'text-green-400')}</div>
<h2 class="text-2xl font-bold text-green-400 mb-2">Transaction Broadcast Successfully!</h2>
<p class="text-gray-400">Your transaction(s) have been sent to the Bitcoin network</p>
</div>
Expand Down Expand Up @@ -812,7 +814,7 @@ export function SendComponent(container, preSelectedUtxos = null) {
<!-- Warning Banner -->
<div class="mb-6 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<p class="text-sm text-yellow-400 font-semibold text-lg">
⚠️ Regular and Swap UTXOs cannot be selected together in a single transaction
${icons.alertTriangle(16, 'mr-1')} Regular and Swap UTXOs cannot be selected together in a single transaction
</p>
<p class="text-xs text-yellow-400/80 mt-1">Mixing these UTXO types compromises privacy. Use one type per send.</p>
</div>
Expand Down Expand Up @@ -893,7 +895,7 @@ export function SendComponent(container, preSelectedUtxos = null) {

<div id="utxo-warning" class="hidden mb-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg">
<p class="text-xs text-red-400 font-semibold text-lg">
⚠️ PRIVACY WARNING: You've selected both Regular and Swap UTXOs!
${icons.alertTriangle(16, 'mr-1')} PRIVACY WARNING: You've selected both Regular and Swap UTXOs!
</p>
<p class="text-xs text-red-400/80 mt-1">This compromises your privacy. Please use only one type.</p>
</div>
Expand All @@ -917,10 +919,10 @@ export function SendComponent(container, preSelectedUtxos = null) {
<!-- Action Buttons -->
<div class="grid grid-cols-2 gap-4">
<button id="sign-tx-btn" class="bg-blue-500 hover:bg-blue-600 disabled:bg-gray-600 disabled:cursor-not-allowed text-white font-bold py-4 rounded-lg transition-colors text-lg">
🔏 Sign Transaction
${icons.key(14, 'mr-1')} Sign Transaction
</button>
<button id="broadcast-tx-btn" disabled class="bg-[#FF6B35] hover:bg-[#ff7d4d] disabled:bg-gray-600 disabled:cursor-not-allowed text-white font-bold py-4 rounded-lg transition-colors text-lg">
📡 Broadcast
${icons.radio(14, 'mr-1')} Broadcast
</button>
</div>
</div>
Expand Down Expand Up @@ -980,7 +982,7 @@ export function SendComponent(container, preSelectedUtxos = null) {
</div>
<div class="flex justify-between">
<span class="text-gray-400">RBF:</span>
<span class="text-blue-400"> Enabled</span>
<span class="text-blue-400">${icons.check(14, 'mr-1')} Enabled</span>
</div>
</div>
</div>
Expand Down
Loading