BigBlocks Docs

PostButton

Create on-chain social posts on the Bitcoin blockchain using the bSocial protocol

PostButton

A component for creating on-chain social posts on the Bitcoin blockchain using the bSocial protocol. Provides a rich text editor with markdown support and content type selection.

Installation

npx bigblocks add post-button

Import

import { PostButton } from 'bigblocks';

Props

PropTypeRequiredDefaultDescription
onPost(post: PostTransaction) => voidNo-Callback after posting
defaultContentstringNo-Default content in editor
placeholderstringNo-Input placeholder text
maxLengthnumberNo-Character limit
triggerTextstringNo'Post'Button text
showContentTypeSelectorbooleanNofalseShow content type dropdown
enableMarkdownbooleanNofalseEnable markdown support
classNamestringNo-Additional CSS classes
variantstringNo-Button variant
sizestringNo-Button size
disabledbooleanNofalseDisable posting

Basic Usage

import { PostButton } from 'bigblocks';

export default function SocialFeed() {
  const handlePost = (post) => {
    console.log('New post created:', post);
    // Refresh feed or add to state
  };

  return (
    <PostButton
      onPost={handlePost}
      placeholder="What's on your mind?"
    />
  );
}

Advanced Usage

With Custom Configuration

import { PostButton } from 'bigblocks';

export default function CustomPostButton() {
  return (
    <PostButton
      placeholder="Share your thoughts..."
      maxLength={500}
      triggerText="Share"
      showContentTypeSelector={true}
      enableMarkdown={true}
      onPost={(post) => {
        console.log('Posted:', post);
        toast.success('Post created successfully!');
      }}
    />
  );
}

With Default Content

import { PostButton } from 'bigblocks';

export default function PrefilledPost() {
  return (
    <PostButton
      defaultContent="Check out this awesome project!"
      placeholder="Add your thoughts..."
      onPost={(post) => {
        // Handle post creation
        addToFeed(post);
      }}
    />
  );
}

Different Variants and Sizes

import { PostButton } from 'bigblocks';

export default function StyledPostButtons() {
  return (
    <div className="space-y-4">
      <PostButton
        size="small"
        variant="outline"
        triggerText="Quick Post"
        onPost={handlePost}
      />
      
      <PostButton
        size="medium"
        variant="solid"
        triggerText="Post"
        onPost={handlePost}
      />
      
      <PostButton
        size="large"
        variant="ghost"
        triggerText="Share Story"
        onPost={handlePost}
      />
    </div>
  );
}

With Markdown Support

import { PostButton } from 'bigblocks';

export default function MarkdownPost() {
  return (
    <PostButton
      enableMarkdown={true}
      placeholder="Write your post with **markdown** support..."
      maxLength={1000}
      onPost={(post) => {
        console.log('Markdown post:', post);
      }}
    />
  );
}

Content Type Selection

import { PostButton } from 'bigblocks';

export default function ContentTypePost() {
  return (
    <PostButton
      showContentTypeSelector={true}
      placeholder="Select content type and write..."
      onPost={(post) => {
        console.log('Post type:', post.contentType);
        console.log('Content:', post.content);
      }}
    />
  );
}

Common Patterns

In Social Feed

import { PostButton, SocialFeed } from 'bigblocks';
import { useState } from 'react';

export default function SocialApp() {
  const [posts, setPosts] = useState([]);

  const handleNewPost = (post) => {
    // Add to feed immediately (optimistic update)
    setPosts(prevPosts => [post, ...prevPosts]);
    
    // Analytics
    analytics.track('post_created', {
      contentLength: post.content.length,
      hasMarkdown: post.enableMarkdown
    });
  };

  return (
    <div className="max-w-2xl mx-auto">
      <div className="mb-6">
        <PostButton
          placeholder="What's happening?"
          onPost={handleNewPost}
          enableMarkdown={true}
        />
      </div>
      
      <SocialFeed posts={posts} />
    </div>
  );
}

Reply to Post

import { PostButton } from 'bigblocks';

export default function ReplyButton({ parentPost }) {
  return (
    <PostButton
      placeholder={`Reply to ${parentPost.author.name}...`}
      triggerText="Reply"
      size="small"
      defaultContent={`@${parentPost.author.name} `}
      onPost={(reply) => {
        // Handle reply
        addReply(parentPost.txid, reply);
      }}
    />
  );
}

With Error Handling

import { PostButton } from 'bigblocks';
import { useState } from 'react';

export default function ErrorHandlingPost() {
  const [error, setError] = useState(null);

  const handlePost = async (post) => {
    try {
      setError(null);
      
      // Post to blockchain
      const result = await createPost(post);
      
      console.log('Post successful:', result);
      toast.success('Post created on blockchain!');
      
    } catch (err) {
      setError(err.message);
      
      if (err.code === 'INSUFFICIENT_FUNDS') {
        toast.error('Insufficient BSV balance for posting');
      } else {
        toast.error('Failed to create post');
      }
    }
  };

  return (
    <div>
      {error && (
        <div className="bg-red-100 text-red-700 p-3 rounded mb-4">
          {error}
        </div>
      )}
      
      <PostButton
        onPost={handlePost}
        placeholder="Share your thoughts..."
      />
    </div>
  );
}

Custom Styling

import { PostButton } from 'bigblocks';

export default function CustomStyledPost() {
  return (
    <PostButton
      className="bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-xl"
      placeholder="Create something amazing..."
      triggerText="✨ Create"
      onPost={(post) => {
        console.log('Styled post:', post);
      }}
    />
  );
}

Character Counter

import { PostButton } from 'bigblocks';

export default function LimitedPost() {
  return (
    <PostButton
      maxLength={280}
      placeholder="Share in 280 characters or less..."
      triggerText="Tweet"
      onPost={(post) => {
        if (post.content.length > 280) {
          toast.error('Post too long!');
          return;
        }
        handlePost(post);
      }}
    />
  );
}

Post Transaction Type

interface PostTransaction {
  txid: string;           // Transaction ID on blockchain
  content: string;        // Post content
  contentType?: string;   // Content type if selector enabled
  author: {
    idKey: string;        // BAP identity key
    name?: string;        // Author name
    address: string;      // Bitcoin address
  };
  timestamp: number;      // Creation timestamp
  block?: {
    height: number;       // Block height
    hash: string;         // Block hash
  };
  fee: number;           // Transaction fee in satoshis
  confirmed: boolean;     // Confirmation status
}

Features

  • Blockchain Storage: Posts are permanently stored on Bitcoin blockchain
  • Markdown Support: Rich text formatting with markdown
  • Content Types: Selectable content types for structured posts
  • Character Limits: Configurable maximum length
  • Real-time Preview: Preview formatted content before posting
  • Optimistic Updates: Immediate UI feedback
  • Error Handling: Comprehensive error states

Content Types

When showContentTypeSelector is enabled, users can select:

  • Text: Plain text posts
  • Markdown: Formatted text with markdown
  • Code: Code snippets with syntax highlighting
  • Quote: Quoted text or citations
  • Announcement: Important announcements
  • Question: Questions for community
  • Answer: Answers to questions

Requirements

  • Authentication: User must be authenticated with BigBlocks
  • Wallet Balance: Sufficient BSV for transaction fees
  • Network: Connection to Bitcoin network
  • Provider Context: Must be wrapped in BitcoinQueryProvider

Styling

The component uses Radix Themes and can be customized:

/* Custom post button styles */
.post-button {
  min-height: 120px;
}

.post-editor {
  resize: vertical;
  font-family: inherit;
}

.content-type-selector {
  margin-bottom: 0.5rem;
}

.character-counter {
  text-align: right;
  font-size: 0.875rem;
  color: var(--gray-11);
}

.character-counter.over-limit {
  color: var(--red-11);
}

Best Practices

  1. Content Guidelines: Encourage meaningful content
  2. Fee Management: Inform users about posting costs
  3. Error Feedback: Provide clear error messages
  4. Optimistic Updates: Show posts immediately
  5. Character Limits: Set reasonable limits for readability

Troubleshooting

Posts Not Appearing

  • Check user authentication status
  • Verify wallet has sufficient balance
  • Ensure network connectivity
  • Check for transaction confirmation

Markdown Not Rendering

  • Verify enableMarkdown is true
  • Check markdown syntax
  • Ensure preview is working

Content Type Issues

  • Verify showContentTypeSelector is enabled
  • Check default content type selection
  • Ensure proper type validation

API Integration

The component integrates with bSocial protocol APIs:

// Post creation endpoint
POST /api/social/posts
{
  content: string;
  contentType?: string;
  replyTo?: string;
}

// Response
{
  txid: string;
  post: PostTransaction;
  fee: number;
}

Notes for Improvement

Focused Implementation: The actual component is more focused than the prompt described:

  • Uses bmap-api-types for proper Bitcoin transaction integration
  • Includes content type selection and markdown support
  • Simpler props interface focused on essential functionality
  • No built-in media upload (handled separately)
  • Direct integration with blockchain posting services