164 lines
4.9 KiB
JavaScript
164 lines
4.9 KiB
JavaScript
import { writable, derived } from 'svelte/store';
|
|
import { browser } from '$app/environment';
|
|
import { auth } from './auth';
|
|
|
|
// Store for current user's übercoin balance
|
|
export const ubercoinBalance = writable(0);
|
|
|
|
// Store for treasury info
|
|
export const treasury = writable({
|
|
balance: 0,
|
|
totalDestroyed: 0,
|
|
totalUsers: 0,
|
|
estimatedShare: 0,
|
|
nextDistribution: null,
|
|
lastGrowthAt: null,
|
|
lastDistributionAt: null
|
|
});
|
|
|
|
// Format übercoin amount for display (3 decimal places)
|
|
export function formatUbercoin(amount) {
|
|
if (amount === null || amount === undefined) return '0.000';
|
|
const num = parseFloat(amount);
|
|
if (isNaN(num)) return '0.000';
|
|
|
|
// Format with exactly 3 decimal places
|
|
return num.toFixed(3);
|
|
}
|
|
|
|
// Format übercoin with compact notation for large numbers
|
|
export function formatUbercoinCompact(amount) {
|
|
if (amount === null || amount === undefined) return '0.000';
|
|
const num = parseFloat(amount);
|
|
if (isNaN(num)) return '0.000';
|
|
|
|
if (num >= 1000000) {
|
|
return (num / 1000000).toFixed(2) + 'M';
|
|
} else if (num >= 1000) {
|
|
return (num / 1000).toFixed(2) + 'K';
|
|
}
|
|
return num.toFixed(3);
|
|
}
|
|
|
|
// Fetch current user's balance (called when user data is loaded)
|
|
export async function fetchBalance() {
|
|
if (!browser) return;
|
|
|
|
try {
|
|
const response = await fetch('/api/user/me', {
|
|
credentials: 'include'
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
if (data.success && data.user) {
|
|
ubercoinBalance.set(data.user.ubercoinBalance || 0);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to fetch übercoin balance:', error);
|
|
}
|
|
}
|
|
|
|
// Preview a transaction (get burn rate before sending)
|
|
export async function previewTransaction(recipientUsername, amount) {
|
|
if (!browser) return { success: false, error: 'Not in browser' };
|
|
|
|
try {
|
|
const response = await fetch('/api/ubercoin/preview', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
credentials: 'include',
|
|
body: JSON.stringify({
|
|
recipient: recipientUsername,
|
|
amount: parseFloat(amount)
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Failed to preview transaction:', error);
|
|
return { success: false, error: 'Network error' };
|
|
}
|
|
}
|
|
|
|
// Send übercoin to another user
|
|
export async function sendUbercoin(recipientUsername, amount) {
|
|
if (!browser) return { success: false, error: 'Not in browser' };
|
|
|
|
try {
|
|
const response = await fetch('/api/ubercoin/send', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
credentials: 'include',
|
|
body: JSON.stringify({
|
|
recipient: recipientUsername,
|
|
amount: parseFloat(amount)
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
// Update local balance
|
|
ubercoinBalance.set(data.newBalance);
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Failed to send übercoin:', error);
|
|
return { success: false, error: 'Network error' };
|
|
}
|
|
}
|
|
|
|
// Fetch treasury info
|
|
export async function fetchTreasury() {
|
|
if (!browser) return;
|
|
|
|
try {
|
|
const response = await fetch('/api/ubercoin/treasury', {
|
|
credentials: 'include'
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
if (data.success) {
|
|
treasury.set({
|
|
balance: data.balance || 0,
|
|
totalDestroyed: data.totalDestroyed || 0,
|
|
totalUsers: data.totalUsers || 0,
|
|
estimatedShare: data.estimatedShare || 0,
|
|
nextDistribution: data.nextDistribution,
|
|
lastGrowthAt: data.lastGrowthAt,
|
|
lastDistributionAt: data.lastDistributionAt
|
|
});
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to fetch treasury:', error);
|
|
}
|
|
}
|
|
|
|
// Calculate time until next distribution
|
|
export function getTimeUntilDistribution(nextDistribution) {
|
|
if (!nextDistribution) return null;
|
|
|
|
const now = new Date();
|
|
const next = new Date(nextDistribution);
|
|
const diff = next.getTime() - now.getTime();
|
|
|
|
if (diff <= 0) return { days: 0, hours: 0, minutes: 0 };
|
|
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
|
|
|
return { days, hours, minutes };
|
|
}
|
|
|
|
// Derived store for user's übercoin from auth
|
|
export const userUbercoin = derived(
|
|
auth,
|
|
$auth => $auth.user?.ubercoinBalance || 0
|
|
);
|