UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

70 lines (69 loc) 5.05 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { CheckCircledIcon, DownloadIcon } from "@radix-ui/react-icons"; import { useState } from "react"; import { cn } from "../../lib/utils.js"; import { Button } from "../ui/button.js"; import { Card, CardContent } from "../ui/card.js"; export function BackupDownload({ backup, password, onDownloaded, requireDownload = false, className = "", }) { const [downloaded, setDownloaded] = useState(false); const [isDownloading, setIsDownloading] = useState(false); const handleDownload = async () => { setIsDownloading(true); try { let dataToDownload; let filename; if (password) { // Encrypt the backup if password is provided const { encryptBackup } = await import("bitcoin-backup"); const encrypted = await encryptBackup(backup, password); // encryptBackup returns a Base64 string, don't double-stringify it dataToDownload = encrypted; filename = `bitcoin-auth-backup-${Date.now()}.txt`; } else { // Download unencrypted backup - determine extension based on backup type const backupData = JSON.stringify(backup, null, 2); dataToDownload = backupData; // Check backup type for appropriate extension if ("wif" in backup && !("xprv" in backup) && !("mnemonic" in backup)) { // WifBackup - simple WIF backup filename = `bitcoin-auth-backup-${Date.now()}.txt`; } else { // BapMasterBackup, BapMemberBackup, OneSatBackup - JSON format filename = `bitcoin-auth-backup-${Date.now()}.json`; } } // Create blob and download const blob = new Blob([dataToDownload], { type: password ? "text/plain" : filename.endsWith(".txt") ? "text/plain" : "application/json", }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); setDownloaded(true); onDownloaded?.(); } catch (error) { console.error("Download error:", error); } finally { setIsDownloading(false); } }; return (_jsx(Card, { className: cn("w-full", className), children: _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(DownloadIcon, { className: "h-5 w-5 text-primary", "aria-label": "Download" }), _jsx("p", { className: "font-medium text-base", children: password ? "Encrypted Backup" : "Master Backup" })] }), _jsx("p", { className: "text-sm text-muted-foreground", children: password ? "Download your encrypted backup file. You'll need your password to restore it." : "Download your complete identity backup. Keep this file secure." }), _jsx(Button, { size: "lg", variant: downloaded ? "secondary" : "default", onClick: handleDownload, disabled: isDownloading, className: cn("w-full", downloaded && "bg-green-50 hover:bg-green-100 text-green-700"), children: isDownloading ? (_jsxs(_Fragment, { children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-2", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", role: "img", "aria-label": "Loading", children: [_jsx("title", { children: "Loading" }), _jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Preparing..."] })) : (_jsxs(_Fragment, { children: [downloaded ? (_jsx(CheckCircledIcon, { className: "h-4 w-4 mr-2", "aria-label": "Success" })) : (_jsx(DownloadIcon, { className: "h-4 w-4 mr-2", "aria-label": "Download" })), downloaded ? "Downloaded" : `Download ${password ? "Encrypted" : "Master"} Backup`] })) }), downloaded && (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(CheckCircledIcon, { className: "h-4 w-4 text-green-600" }), _jsx("p", { className: "text-xs text-green-600", children: "Backup saved to your downloads folder" })] })), requireDownload && !downloaded && (_jsx("p", { className: "text-xs text-amber-600", children: "You must download your backup before continuing" }))] }) }) })); }