bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
17 lines • 6.27 kB
JSON
{
"name": "social-hooks-usesocialpost",
"type": "registry:hook",
"dependencies": [
"@tanstack/react-query"
],
"devDependencies": [],
"registryDependencies": [],
"files": [
{
"path": "components/social/hooks/useSocialPost.ts",
"type": "registry:hook",
"content": "// useSocialPost Hook - Create social posts on Bitcoin\nimport { useMutation } from \"@tanstack/react-query\";\nimport { useBitcoinAuth } from \"../../../hooks/useBitcoinAuth.js\";\nimport { useBlockchainService } from \"../../../hooks/useBlockchainService.js\";\nimport { broadcastSocialTransaction } from \"../../../lib/broadcast\";\nimport { SocialActions } from \"../../../lib/protocol\";\nimport type { PostMutationData, UseSocialPostResult } from \"../types/hooks.js\";\nimport type {\n\tAuthUserWithSigning,\n\tBroadcastResult,\n\tSocialError,\n} from \"../types/social.js\";\n\ninterface UseSocialPostOptions {\n\tapp?: string;\n\tonSuccess?: (result: BroadcastResult) => void;\n\tonError?: (error: SocialError) => void;\n}\n\nexport function useSocialPost(\n\toptions: UseSocialPostOptions = {},\n): UseSocialPostResult {\n\tconst { app: _app = \"bigblocks\", onSuccess, onError } = options;\n\tconst { user } = useBitcoinAuth();\n\tconst _blockchainService = useBlockchainService();\n\n\tconst mutation = useMutation<BroadcastResult, SocialError, PostMutationData>({\n\t\tmutationFn: async ({\n\t\t\tcontent,\n\t\t\tcontentType: _contentType = \"text/plain\",\n\t\t}) => {\n\t\t\tif (!user) {\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\tmessage: \"User must be authenticated to post\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\tif (!content.trim()) {\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"INVALID_CONTENT\",\n\t\t\t\t\tmessage: \"Post content cannot be empty\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\tif (content.length > 10000) {\n\t\t\t\t// Reasonable limit\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"CONTENT_TOO_LONG\",\n\t\t\t\t\tmessage: \"Post content exceeds maximum length\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Get signing key from user context\n\t\t\t\t// Note: This would need to be implemented in the auth system\n\t\t\t\t// For now, we'll assume it's available or throw an error\n\t\t\t\tconst signingKey = (user as AuthUserWithSigning).signingKey;\n\t\t\t\tif (!signingKey) {\n\t\t\t\t\tthrow {\n\t\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\t\tmessage: \"No signing key available\",\n\t\t\t\t\t} as SocialError;\n\t\t\t\t}\n\n\t\t\t\t// Build transaction\n\t\t\t\tconst signedTransaction = await SocialActions.post(content);\n\n\t\t\t\t// Broadcast to Bitcoin network using social transaction broadcaster\n\t\t\t\t// Note: SocialTransaction needs the specialized social broadcaster\n\t\t\t\tconst result = await broadcastSocialTransaction(signedTransaction);\n\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tthrow {\n\t\t\t\t\t\tcode: \"BROADCAST_FAILED\",\n\t\t\t\t\t\tmessage: result.error || \"Failed to broadcast transaction\",\n\t\t\t\t\t} as SocialError;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif ((error as SocialError).code) {\n\t\t\t\t\tthrow error; // Re-throw our custom errors\n\t\t\t\t}\n\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"TRANSACTION_FAILED\",\n\t\t\t\t\tmessage: \"Failed to create post transaction\",\n\t\t\t\t\tdetails: error,\n\t\t\t\t} as SocialError;\n\t\t\t}\n\t\t},\n\t\tonSuccess: (data) => {\n\t\t\tonSuccess?.(data);\n\t\t},\n\t\tonError: (error) => {\n\t\t\tconsole.error(\"Social post failed:\", error);\n\t\t\tonError?.(error);\n\t\t},\n\t});\n\n\t// Map React Query v5 properties to our interface\n\treturn {\n\t\tmutate: mutation.mutate,\n\t\tmutateAsync: mutation.mutateAsync,\n\t\tisLoading: mutation.isPending,\n\t\tisError: mutation.isError,\n\t\tisSuccess: mutation.isSuccess,\n\t\terror: mutation.error,\n\t\tdata: mutation.data,\n\t\treset: mutation.reset,\n\t} as UseSocialPostResult;\n}\n\n// Reply hook - extends post functionality\nexport function useReplyPost(options: UseSocialPostOptions = {}) {\n\tconst { app: _app = \"bigblocks\", onSuccess, onError } = options;\n\tconst { user } = useBitcoinAuth();\n\n\tconst _replyMutation = useMutation<\n\t\tBroadcastResult,\n\t\tSocialError,\n\t\tPostMutationData & { parentTxid: string }\n\t>({\n\t\tmutationFn: async ({\n\t\t\tcontent,\n\t\t\tcontentType: _contentType = \"text/plain\",\n\t\t\tparentTxid,\n\t\t}) => {\n\t\t\tif (!user) {\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\tmessage: \"User must be authenticated to reply\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\tif (!content.trim()) {\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"INVALID_CONTENT\",\n\t\t\t\t\tmessage: \"Reply content cannot be empty\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\tif (!parentTxid) {\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"INVALID_CONTENT\",\n\t\t\t\t\tmessage: \"Parent transaction ID is required for replies\",\n\t\t\t\t} as SocialError;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst signingKey = (user as AuthUserWithSigning).signingKey;\n\t\t\t\tif (!signingKey) {\n\t\t\t\t\tthrow {\n\t\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\t\tmessage: \"No signing key available\",\n\t\t\t\t\t} as SocialError;\n\t\t\t\t}\n\n\t\t\t\t// Build reply transaction\n\t\t\t\tconst signedTransaction = await SocialActions.reply(\n\t\t\t\t\tcontent,\n\t\t\t\t\tparentTxid,\n\t\t\t\t);\n\n\t\t\t\t// Broadcast to Bitcoin network\n\t\t\t\tconst result = await broadcastSocialTransaction(signedTransaction);\n\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tthrow {\n\t\t\t\t\t\tcode: \"BROADCAST_FAILED\",\n\t\t\t\t\t\tmessage: result.error || \"Failed to broadcast reply\",\n\t\t\t\t\t} as SocialError;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tif ((error as SocialError).code) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tthrow {\n\t\t\t\t\tcode: \"TRANSACTION_FAILED\",\n\t\t\t\t\tmessage: \"Failed to create reply transaction\",\n\t\t\t\t\tdetails: error,\n\t\t\t\t} as SocialError;\n\t\t\t}\n\t\t},\n\t\tonSuccess: (data) => {\n\t\t\tonSuccess?.(data);\n\t\t},\n\t\tonError: (error) => {\n\t\t\tconsole.error(\"Social reply failed:\", error);\n\t\t\tonError?.(error);\n\t\t},\n\t});\n}\n",
"target": "<%- config.aliases.hooks %>/usesocialpost.ts"
}
]
}