Overview
TUNA provides two hooks for comment management:
useArticleComments - Fetch comments for a specific article
usePostComment - Post a new comment to an article
useArticleComments
Fetch all comments for a specific news article from the Sui blockchain.
Function Signature
function useArticleComments(blobId: string): UseQueryResult<Comment[], Error>
Parameters
The Walrus blob ID of the article to fetch comments for
Return Type
Array of comments sorted by timestamp (newest first)Unique comment object ID on Sui
The article’s blob ID this comment belongs to
Sui address of the comment author
Unix timestamp when the comment was posted
Total tips received by this comment in SUI tokens
Whether the query is currently loading
Error object if the query failed
Usage
import { useArticleComments } from '@tuna/sdk';
function CommentList({ articleBlobId }: { articleBlobId: string }) {
const { data: comments, isLoading, error } = useArticleComments(articleBlobId);
if (isLoading) return <div>Loading comments...</div>;
if (error) return <div>Failed to load comments</div>;
if (!comments?.length) return <div>No comments yet</div>;
return (
<div>
<h3>{comments.length} Comments</h3>
{comments.map((comment) => (
<div key={comment.id}>
<p>{comment.text}</p>
<small>
By {comment.author.slice(0, 6)}...{comment.author.slice(-4)}
</small>
<small>💰 {comment.tipsReceived} SUI</small>
</div>
))}
</div>
);
}
Query Configuration
- Query Key:
['comments', blobId]
- Stale Time: 0 (always refetch)
- Refetch on Window Focus: Enabled
- Enabled: Only when
blobId is provided
Comments are automatically refetched when the window regains focus to ensure you see the latest discussions.
Post a new comment to an article. Requires a connected Sui wallet.
Function Signature
function usePostComment(): UseMutationResult<void, Error, { blobId: string, text: string }>
Parameters
This hook returns a mutation object. Call the mutate function with:
The Walrus blob ID of the article to comment on
Return Type
mutate
(variables: { blobId: string, text: string }) => void
Function to trigger the comment post transaction
mutateAsync
(variables: { blobId: string, text: string }) => Promise<void>
Async version of mutate that returns a Promise
Whether the mutation is currently in progress
Whether the mutation completed successfully
Whether the mutation encountered an error
Error object if the mutation failed
Usage
import { usePostComment } from '@tuna/sdk';
import { useState } from 'react';
function CommentForm({ articleBlobId }: { articleBlobId: string }) {
const [text, setText] = useState('');
const { mutate, isPending, isError } = usePostComment();
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
mutate(
{ blobId: articleBlobId, text },
{
onSuccess: () => {
setText(''); // Clear form
alert('Comment posted!');
}
}
);
};
return (
<form onSubmit={handleSubmit}>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Write a comment..."
disabled={isPending}
/>
<button type="submit" disabled={isPending || !text.trim()}>
{isPending ? 'Posting...' : 'Post Comment'}
</button>
{isError && <p>Failed to post comment. Please try again.</p>}
</form>
);
}
Automatic Cache Updates
When a comment is successfully posted, the hook automatically:
- Invalidates the comments query for that article
- Invalidates the article query to update comment count
- Waits 2 seconds for blockchain indexing before refetching
// This happens automatically - no action needed
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ['comments', variables.blobId] });
queryClient.invalidateQueries({ queryKey: ['article', variables.blobId] });
}
A connected Sui wallet is required to post comments. The hook will throw an error if no wallet is connected.
Error Handling
import { useCurrentAccount } from '@mysten/dapp-kit';
import { usePostComment } from '@tuna/sdk';
function CommentSection({ blobId }: { blobId: string }) {
const account = useCurrentAccount();
const { mutate } = usePostComment();
if (!account) {
return <div>Please connect your wallet to comment</div>;
}
return (
<button onClick={() => mutate({ blobId, text: 'Great article!' })}>
Post Comment
</button>
);
}
See Also