UNPKG

bigblocks

Version:

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

18 lines 7.14 kB
{ "name": "bap-identity-hooks-usebapencryption", "type": "registry:hook", "dependencies": [ "@bsv/sdk", "@tanstack/react-query" ], "devDependencies": [], "registryDependencies": [], "files": [ { "path": "components/bap-identity/hooks/useBapEncryption.ts", "type": "registry:hook", "content": "import { ECIES, PublicKey, Utils } from \"@bsv/sdk\";\n// useBapEncryption Hook - Encrypt/decrypt with BAP identity using React Query pattern\nimport { useMutation } from \"@tanstack/react-query\";\nimport { useBitcoinAuth } from \"../../../hooks/useBitcoinAuth.js\";\nimport type {\n\tDecryptedData,\n\tDecryptionOptions,\n\tDecryptionResult,\n\tEncryptedData,\n\tEncryptionKeyInfo,\n\tEncryptionOptions,\n\tEncryptionResult,\n\tUseBapEncryptionOptions,\n} from \"../types/encryption.js\";\nimport type { AuthUserWithBAP } from \"../types/identity.js\";\n\nconst { electrumEncrypt, electrumDecrypt } = ECIES;\nconst { toArray, toBase64, toUTF8 } = Utils;\n\nexport interface EncryptionParams {\n\tcontent: string;\n\toptions?: EncryptionOptions;\n}\n\nexport interface DecryptionParams {\n\tencryptedContent: string;\n\toptions?: DecryptionOptions;\n}\n\nexport function useBapEncryption(options: UseBapEncryptionOptions = {}) {\n\tconst { useType42: _useType42 = false } = options;\n\tconst { user } = useBitcoinAuth();\n\n\t// Get BAP instance from context\n\tconst bapInstance = (user as AuthUserWithBAP)?.bapInstance;\n\n\t// Encryption mutation\n\tconst encryptMutation = useMutation<\n\t\tEncryptionResult,\n\t\tError,\n\t\tEncryptionParams\n\t>({\n\t\tmutationFn: async ({ content, options: encryptOptions = {} }) => {\n\t\t\tif (!bapInstance) {\n\t\t\t\tthrow new Error(\"BAP instance not available\");\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst ids = bapInstance.listIds();\n\t\t\t\tif (!ids || ids.length === 0) {\n\t\t\t\t\tthrow new Error(\"No BAP identity available\");\n\t\t\t\t}\n\n\t\t\t\tconst currentId = ids[0];\n\t\t\t\tif (!currentId) {\n\t\t\t\t\tthrow new Error(\"Invalid BAP identity\");\n\t\t\t\t}\n\n\t\t\t\tconst identity = bapInstance.getId(currentId.idKey);\n\n\t\t\t\tif (!identity) {\n\t\t\t\t\tthrow new Error(\"BAP identity not found\");\n\t\t\t\t}\n\n\t\t\t\t// Get encryption key from the identity\n\t\t\t\tconst encryptionKey = encryptOptions.useType42\n\t\t\t\t\t? identity.getEncryptionKeyType42()\n\t\t\t\t\t: identity.getEncryptionKey();\n\n\t\t\t\t// Get recipient public key or use self\n\t\t\t\tlet targetPubKey: PublicKey;\n\t\t\t\tif (encryptOptions.recipientPublicKey) {\n\t\t\t\t\ttargetPubKey = PublicKey.fromString(\n\t\t\t\t\t\tencryptOptions.recipientPublicKey,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttargetPubKey = encryptionKey.pubKey;\n\t\t\t\t}\n\n\t\t\t\t// Perform ECIES encryption\n\t\t\t\tconst encrypted = toBase64(\n\t\t\t\t\telectrumEncrypt(\n\t\t\t\t\t\ttoArray(content, \"utf8\"),\n\t\t\t\t\t\ttargetPubKey,\n\t\t\t\t\t\tencryptOptions.recipientPublicKey\n\t\t\t\t\t\t\t? encryptionKey.privKey\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tconst encryptedData: EncryptedData = {\n\t\t\t\t\tencrypted,\n\t\t\t\t\ttype: encryptOptions.type || \"message\",\n\t\t\t\t\tmode: encryptOptions.mode || \"asymmetric\",\n\t\t\t\t\trecipientPublicKey: encryptOptions.recipientPublicKey,\n\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t\tmetadata: encryptOptions.metadata,\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: encryptedData,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error as Error,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t});\n\n\t// Decryption mutation\n\tconst decryptMutation = useMutation<\n\t\tDecryptionResult,\n\t\tError,\n\t\tDecryptionParams\n\t>({\n\t\tmutationFn: async ({ encryptedContent, options: decryptOptions = {} }) => {\n\t\t\tif (!bapInstance) {\n\t\t\t\tthrow new Error(\"BAP instance not available\");\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst ids = bapInstance.listIds();\n\t\t\t\tif (!ids || ids.length === 0) {\n\t\t\t\t\tthrow new Error(\"No BAP identity available\");\n\t\t\t\t}\n\n\t\t\t\tconst currentId = ids[0];\n\t\t\t\tif (!currentId) {\n\t\t\t\t\tthrow new Error(\"Invalid BAP identity\");\n\t\t\t\t}\n\n\t\t\t\tconst identity = bapInstance.getId(currentId.idKey);\n\n\t\t\t\tif (!identity) {\n\t\t\t\t\tthrow new Error(\"BAP identity not found\");\n\t\t\t\t}\n\n\t\t\t\t// Get encryption key from the identity\n\t\t\t\tconst encryptionKey = decryptOptions.useType42\n\t\t\t\t\t? identity.getEncryptionKeyType42()\n\t\t\t\t\t: identity.getEncryptionKey();\n\n\t\t\t\t// Get sender public key if provided\n\t\t\t\tlet senderPubKey: PublicKey | undefined;\n\t\t\t\tif (decryptOptions.senderPublicKey) {\n\t\t\t\t\tsenderPubKey = PublicKey.fromString(decryptOptions.senderPublicKey);\n\t\t\t\t}\n\n\t\t\t\t// Perform ECIES decryption\n\t\t\t\tconst decryptedBytes = electrumDecrypt(\n\t\t\t\t\ttoArray(encryptedContent, \"base64\"),\n\t\t\t\t\tencryptionKey.privKey,\n\t\t\t\t\tsenderPubKey,\n\t\t\t\t);\n\t\t\t\tconst content = toUTF8(decryptedBytes);\n\n\t\t\t\tconst decryptedData: DecryptedData = {\n\t\t\t\t\tcontent,\n\t\t\t\t\ttype: decryptOptions.type || \"message\",\n\t\t\t\t\tdecryptedAt: new Date(),\n\t\t\t\t\tsenderAddress: \"mock-address\",\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: decryptedData,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: error as Error,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t});\n\n\t// Get encryption key info\n\tconst getEncryptionKey = (): EncryptionKeyInfo | null => {\n\t\tif (!bapInstance) return null;\n\n\t\ttry {\n\t\t\tconst ids = bapInstance.listIds();\n\t\t\tif (!ids || ids.length === 0) return null;\n\n\t\t\tconst currentId = ids[0];\n\t\t\tif (!currentId) return null;\n\n\t\t\tconst identity = bapInstance.getId(currentId.idKey);\n\n\t\t\tif (!identity) return null;\n\n\t\t\t// Get the actual encryption key from the identity\n\t\t\tconst encryptionKey = options.useType42\n\t\t\t\t? identity.getEncryptionKeyType42()\n\t\t\t\t: identity.getEncryptionKey();\n\n\t\t\treturn {\n\t\t\t\tpublicKey: encryptionKey.pubKey.toString(),\n\t\t\t\taddress: identity.getCurrentAddress(),\n\t\t\t\tidentityKey: currentId.idKey,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\treturn {\n\t\t// React Query mutation interface\n\t\tencrypt: encryptMutation.mutate,\n\t\tencryptAsync: encryptMutation.mutateAsync,\n\t\tdecrypt: decryptMutation.mutate,\n\t\tdecryptAsync: decryptMutation.mutateAsync,\n\n\t\t// State\n\t\tisLoading: encryptMutation.isPending || decryptMutation.isPending,\n\t\tisError: encryptMutation.isError || decryptMutation.isError,\n\t\tisSuccess: encryptMutation.isSuccess || decryptMutation.isSuccess,\n\t\terror: encryptMutation.error || decryptMutation.error,\n\t\tdata: encryptMutation.data || decryptMutation.data,\n\n\t\t// Helpers\n\t\tgetEncryptionKey,\n\n\t\t// Reset\n\t\treset: () => {\n\t\t\tencryptMutation.reset();\n\t\t\tdecryptMutation.reset();\n\t\t},\n\t};\n}\n", "target": "<%- config.aliases.hooks %>/usebapencryption.ts" } ] }