UNPKG

bigblocks

Version:

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

167 lines (166 loc) 6.68 kB
import { ECIES, PublicKey, Utils } from "@bsv/sdk"; // useBapEncryption Hook - Encrypt/decrypt with BAP identity using React Query pattern import { useMutation } from "@tanstack/react-query"; import { useBitcoinAuth } from "../../../hooks/useBitcoinAuth.js"; const { electrumEncrypt, electrumDecrypt } = ECIES; const { toArray, toBase64, toUTF8 } = Utils; export function useBapEncryption(options = {}) { const { useType42: _useType42 = false } = options; const { user } = useBitcoinAuth(); // Get BAP instance from context const bapInstance = user?.bapInstance; // Encryption mutation const encryptMutation = useMutation({ mutationFn: async ({ content, options: encryptOptions = {} }) => { if (!bapInstance) { throw new Error("BAP instance not available"); } try { const ids = bapInstance.listIds(); if (!ids || ids.length === 0) { throw new Error("No BAP identity available"); } const currentId = ids[0]; if (!currentId) { throw new Error("Invalid BAP identity"); } const identity = bapInstance.getId(currentId.idKey); if (!identity) { throw new Error("BAP identity not found"); } // Get encryption key from the identity const encryptionKey = encryptOptions.useType42 ? identity.getEncryptionKeyType42() : identity.getEncryptionKey(); // Get recipient public key or use self let targetPubKey; if (encryptOptions.recipientPublicKey) { targetPubKey = PublicKey.fromString(encryptOptions.recipientPublicKey); } else { targetPubKey = encryptionKey.pubKey; } // Perform ECIES encryption const encrypted = toBase64(electrumEncrypt(toArray(content, "utf8"), targetPubKey, encryptOptions.recipientPublicKey ? encryptionKey.privKey : undefined)); const encryptedData = { encrypted, type: encryptOptions.type || "message", mode: encryptOptions.mode || "asymmetric", recipientPublicKey: encryptOptions.recipientPublicKey, timestamp: new Date(), metadata: encryptOptions.metadata, }; return { success: true, data: encryptedData, }; } catch (error) { return { success: false, error: error, }; } }, }); // Decryption mutation const decryptMutation = useMutation({ mutationFn: async ({ encryptedContent, options: decryptOptions = {} }) => { if (!bapInstance) { throw new Error("BAP instance not available"); } try { const ids = bapInstance.listIds(); if (!ids || ids.length === 0) { throw new Error("No BAP identity available"); } const currentId = ids[0]; if (!currentId) { throw new Error("Invalid BAP identity"); } const identity = bapInstance.getId(currentId.idKey); if (!identity) { throw new Error("BAP identity not found"); } // Get encryption key from the identity const encryptionKey = decryptOptions.useType42 ? identity.getEncryptionKeyType42() : identity.getEncryptionKey(); // Get sender public key if provided let senderPubKey; if (decryptOptions.senderPublicKey) { senderPubKey = PublicKey.fromString(decryptOptions.senderPublicKey); } // Perform ECIES decryption const decryptedBytes = electrumDecrypt(toArray(encryptedContent, "base64"), encryptionKey.privKey, senderPubKey); const content = toUTF8(decryptedBytes); const decryptedData = { content, type: decryptOptions.type || "message", decryptedAt: new Date(), senderAddress: "mock-address", }; return { success: true, data: decryptedData, }; } catch (error) { return { success: false, error: error, }; } }, }); // Get encryption key info const getEncryptionKey = () => { if (!bapInstance) return null; try { const ids = bapInstance.listIds(); if (!ids || ids.length === 0) return null; const currentId = ids[0]; if (!currentId) return null; const identity = bapInstance.getId(currentId.idKey); if (!identity) return null; // Get the actual encryption key from the identity const encryptionKey = options.useType42 ? identity.getEncryptionKeyType42() : identity.getEncryptionKey(); return { publicKey: encryptionKey.pubKey.toString(), address: identity.getCurrentAddress(), identityKey: currentId.idKey, }; } catch { return null; } }; return { // React Query mutation interface encrypt: encryptMutation.mutate, encryptAsync: encryptMutation.mutateAsync, decrypt: decryptMutation.mutate, decryptAsync: decryptMutation.mutateAsync, // State isLoading: encryptMutation.isPending || decryptMutation.isPending, isError: encryptMutation.isError || decryptMutation.isError, isSuccess: encryptMutation.isSuccess || decryptMutation.isSuccess, error: encryptMutation.error || decryptMutation.error, data: encryptMutation.data || decryptMutation.data, // Helpers getEncryptionKey, // Reset reset: () => { encryptMutation.reset(); decryptMutation.reset(); }, }; }