| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /**
- * Local mavi activity log (this browser only).
- * Not a full chain indexer — just what this wallet did here.
- */
- export type MaviActivityKind = "send" | "fund" | "receive_note";
- export type MaviActivityItem = {
- id: string;
- kind: MaviActivityKind;
- /** Wallet address that owns this history row */
- wallet: string;
- hash?: string;
- to?: string;
- from?: string;
- amountEth?: string;
- at: string;
- note?: string;
- };
- const KEY = "mavi_activity_v1";
- const MAX = 40;
- function loadAll(): MaviActivityItem[] {
- if (typeof window === "undefined") return [];
- try {
- const raw = window.localStorage.getItem(KEY);
- if (!raw) return [];
- const parsed: unknown = JSON.parse(raw);
- if (!Array.isArray(parsed)) return [];
- return parsed.filter(isItem);
- } catch {
- return [];
- }
- }
- function isItem(v: unknown): v is MaviActivityItem {
- if (!v || typeof v !== "object") return false;
- const o = v as Record<string, unknown>;
- return (
- typeof o.id === "string" &&
- (o.kind === "send" || o.kind === "fund" || o.kind === "receive_note") &&
- typeof o.wallet === "string" &&
- typeof o.at === "string"
- );
- }
- function saveAll(items: MaviActivityItem[]) {
- try {
- window.localStorage.setItem(KEY, JSON.stringify(items.slice(0, MAX)));
- } catch {
- /* quota */
- }
- }
- export function readActivityForWallet(
- walletAddress: string,
- limit = 20,
- ): MaviActivityItem[] {
- const w = walletAddress.toLowerCase();
- return loadAll()
- .filter((i) => i.wallet.toLowerCase() === w)
- .slice(0, limit);
- }
- export function addActivity(
- item: Omit<MaviActivityItem, "id" | "at"> & { at?: string },
- ): MaviActivityItem {
- const full: MaviActivityItem = {
- ...item,
- id: `act_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
- at: item.at ?? new Date().toISOString(),
- wallet: item.wallet.toLowerCase(),
- };
- const next = [full, ...loadAll()];
- saveAll(next);
- return full;
- }
- export function clearActivityForWallet(walletAddress: string): void {
- const w = walletAddress.toLowerCase();
- saveAll(loadAll().filter((i) => i.wallet.toLowerCase() !== w));
- }
- export function formatActivityTime(iso: string): string {
- try {
- const d = new Date(iso);
- if (Number.isNaN(d.getTime())) return iso;
- return d.toLocaleString(undefined, {
- month: "short",
- day: "numeric",
- hour: "2-digit",
- minute: "2-digit",
- });
- } catch {
- return iso;
- }
- }
- export function shortHash(hash: string): string {
- if (hash.length < 14) return hash;
- return `${hash.slice(0, 8)}…${hash.slice(-6)}`;
- }
- /** Call after writing activity so open tabs / home refresh. */
- export function notifyActivityChanged() {
- if (typeof window === "undefined") return;
- window.dispatchEvent(new Event("mavi-activity"));
- }
|