This commit is contained in:
@@ -1,15 +1,129 @@
|
||||
async function loadFeatures(){
|
||||
const fallback = [
|
||||
["Terminal", "VT-style surface, tabs, split panes, Unicode"],
|
||||
["Connections", "Local shell, SSH, Telnet, Serial profile model"],
|
||||
["UX", "Command palette, shortcuts, quake window, restored sessions"],
|
||||
["Footprint", "Rust core + Tauri shell instead of Electron"]
|
||||
];
|
||||
let rows = fallback;
|
||||
try {
|
||||
const { invoke } = window.__TAURI__.core;
|
||||
rows = (await invoke('workspace_summary')).map(x => [x.feature, x.detail]);
|
||||
} catch (_) {}
|
||||
document.getElementById('features').innerHTML = rows.map(([f,d]) => `<li><b>${f}</b>: ${d}</li>`).join('');
|
||||
const fallbackDashboard = {
|
||||
active_account: {
|
||||
name: 'Main Wallet',
|
||||
address: '0x1111111111111111111111111111111111111111',
|
||||
source: 'SeedPhrase'
|
||||
},
|
||||
chains: [
|
||||
{ id: 1, name: 'Ethereum' },
|
||||
{ id: 8453, name: 'Base' }
|
||||
],
|
||||
balances: [
|
||||
{ chain_id: 1, symbol: 'ETH', amount: 1.24, usd_value: 4200 },
|
||||
{ chain_id: 8453, symbol: 'USDC', amount: 1280, usd_value: 1280 }
|
||||
],
|
||||
approvals: [
|
||||
{ chain_id: 1, asset_symbol: 'USDC', spender: '0x2222222222222222222222222222222222222222', allowance: 'unlimited', risk: 'High' }
|
||||
],
|
||||
activities: [
|
||||
{ label: 'Swap ETH → USDC', status: 'Confirmed', chain_id: 1 }
|
||||
],
|
||||
settings: {
|
||||
theme: 'System',
|
||||
language: 'en',
|
||||
currency: 'USD',
|
||||
auto_lock_minutes: 15,
|
||||
prefer_rabby_over_metamask: true
|
||||
}
|
||||
};
|
||||
|
||||
const fallbackFeatures = [
|
||||
['Create/unlock wallet', 'Password, lock/unlock, encrypted local state', 'Modeled'],
|
||||
['Import/create accounts', 'Seed phrase, private key, JSON, watch-only', 'Modeled'],
|
||||
['Multi-chain networks', 'Built-in, custom RPC, testnet, offline chain flags', 'Modeled'],
|
||||
['Portfolio dashboard', 'Balances, NFTs, DeFi positions, activity', 'UiPrototype'],
|
||||
['Dapp provider and permissions', 'Origin/account/chain permissions', 'Modeled'],
|
||||
['Signing and security previews', 'Typed data/message/transaction previews and risk', 'Modeled'],
|
||||
['Settings and customization', 'Theme, language, currency, auto-lock, default wallet mode', 'UiPrototype']
|
||||
];
|
||||
|
||||
function money(value) {
|
||||
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value || 0);
|
||||
}
|
||||
loadFeatures();
|
||||
|
||||
function shortAddress(address) {
|
||||
if (!address || address.length < 12) return address || '';
|
||||
return `${address.slice(0, 6)}…${address.slice(-4)}`;
|
||||
}
|
||||
|
||||
function statusLabel(value) {
|
||||
if (typeof value === 'string') return value;
|
||||
if (value && typeof value === 'object') return Object.keys(value)[0] || 'Modeled';
|
||||
return 'Modeled';
|
||||
}
|
||||
|
||||
async function invokeOrFallback(command, fallback) {
|
||||
try {
|
||||
const tauri = window.__TAURI__?.core;
|
||||
if (!tauri) return fallback;
|
||||
return await tauri.invoke(command);
|
||||
} catch (_) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
function renderDashboard(dashboard) {
|
||||
const total = dashboard.balances.reduce((sum, token) => sum + token.usd_value, 0);
|
||||
const highRisk = dashboard.approvals.filter((approval) => ['High', 'Critical'].includes(statusLabel(approval.risk))).length;
|
||||
|
||||
document.getElementById('account-address').textContent = shortAddress(dashboard.active_account.address);
|
||||
document.getElementById('portfolio-total').textContent = money(total);
|
||||
document.getElementById('hero-total').textContent = money(total);
|
||||
document.getElementById('chain-count').textContent = dashboard.chains.length;
|
||||
document.getElementById('risk-count').textContent = highRisk;
|
||||
document.getElementById('approval-risk').textContent = highRisk;
|
||||
|
||||
document.getElementById('token-list').innerHTML = dashboard.balances.map((token) => `
|
||||
<div class="asset-row">
|
||||
<div class="coin-mark">${token.symbol.slice(0, 1)}</div>
|
||||
<div><strong>${token.symbol}</strong><span>Chain ${token.chain_id}</span></div>
|
||||
<div class="asset-value"><strong>${money(token.usd_value)}</strong><span>${token.amount}</span></div>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
document.getElementById('approval-list').innerHTML = dashboard.approvals.map((approval) => `
|
||||
<div class="approval-row">
|
||||
<div><strong>${approval.asset_symbol} allowance</strong><span>${shortAddress(approval.spender)}</span></div>
|
||||
<span class="risk ${statusLabel(approval.risk).toLowerCase()}">${statusLabel(approval.risk)}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
document.getElementById('activity-list').innerHTML = dashboard.activities.map((activity) => `
|
||||
<div class="activity-row"><span>↗</span><div><strong>${activity.label}</strong><small>${statusLabel(activity.status)} · Chain ${activity.chain_id}</small></div></div>
|
||||
`).join('');
|
||||
|
||||
const settings = dashboard.settings;
|
||||
document.getElementById('settings-summary').innerHTML = [
|
||||
['Theme', statusLabel(settings.theme)],
|
||||
['Language', settings.language],
|
||||
['Currency', settings.currency],
|
||||
['Auto-lock', `${settings.auto_lock_minutes} min`],
|
||||
['Default wallet', settings.prefer_rabby_over_metamask ? 'Rabby' : 'Browser default']
|
||||
].map(([label, value]) => `<div><span>${label}</span><strong>${value}</strong></div>`).join('');
|
||||
}
|
||||
|
||||
function renderFeatures(features) {
|
||||
document.getElementById('wallet-features').innerHTML = features.map((feature) => {
|
||||
const title = Array.isArray(feature) ? feature[0] : feature.feature;
|
||||
const acceptance = Array.isArray(feature) ? feature[1] : feature.acceptance;
|
||||
const status = Array.isArray(feature) ? feature[2] : statusLabel(feature.status);
|
||||
return `
|
||||
<article class="feature-card">
|
||||
<span class="feature-status">${status}</span>
|
||||
<strong>${title}</strong>
|
||||
<p>${acceptance}</p>
|
||||
</article>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
async function boot() {
|
||||
const [dashboard, features] = await Promise.all([
|
||||
invokeOrFallback('wallet_dashboard', fallbackDashboard),
|
||||
invokeOrFallback('wallet_mvp_summary', fallbackFeatures)
|
||||
]);
|
||||
renderDashboard(dashboard);
|
||||
renderFeatures(features);
|
||||
}
|
||||
|
||||
boot();
|
||||
|
||||
Reference in New Issue
Block a user