Skip to content

Quick Start

Get up and running with the Grapevine SDK in minutes.

Installation

# Using npm
npm install @pinata/grapevine-sdk
 
# Using yarn
yarn add @pinata/grapevine-sdk
 
# Using Bun (recommended)
bun add @pinata/grapevine-sdk

Basic Setup

1. Import the SDK

import { GrapevineClient } from '@pinata/grapevine-sdk';

2. Initialize Client

Choose your authentication method:

Private Key (Server)
const grapevine = new GrapevineClient({
  privateKey: process.env.PRIVATE_KEY, // 0x...
  network: 'testnet' // or 'mainnet'
});

3. First API Call

// Test connection and get available categories
const categories = await grapevine.categories.getAll();
console.log('Available categories:', categories);

Complete Example

Here's a complete example showing the most common operations:

import { GrapevineClient } from '@pinata/grapevine-sdk';
 
async function main() {
  // Initialize client
  const grapevine = new GrapevineClient({
    privateKey: process.env.PRIVATE_KEY,
    network: 'testnet'
  });
 
  // Get wallet info
  console.log('Wallet address:', grapevine.getWalletAddress());
 
  // Create a feed
  const feed = await grapevine.feeds.create({
    name: 'My First Feed',
    description: 'Learning how to use Grapevine',
    tags: ['tutorial', 'getting-started']
  });
  
  console.log('Created feed:', feed.id);
 
  // Add a free entry
  const freeEntry = await grapevine.entries.create(feed.id, {
    title: 'Welcome Post',
    content: 'Hello, Grapevine! This is my first post.',
    tags: ['welcome'],
    is_free: true
  });
 
  // Add a paid entry
  const paidEntry = await grapevine.entries.create(feed.id, {
    title: 'Premium Content',
    content: 'This is premium content that requires payment to access.',
    tags: ['premium'],
    is_free: false,
    price: {
      amount: '1500000',  // 1.50 USDC
      currency: 'USDC'
    }
  });
 
  // List entries in the feed
  const entries = await grapevine.entries.list(feed.id);
  console.log(`Feed has ${entries.data.length} entries`);
 
  entries.data.forEach(entry => {
    console.log(`- ${entry.title} (${entry.is_free ? 'Free' : 'Paid'})`);
  });
}
 
main().catch(console.error);

React Integration

Use the React hooks for seamless wallet integration:

import { useGrapevine, useGrapevineReady } from '@pinata/grapevine-sdk/react';
import { useWalletClient } from 'wagmi';
import { useState, useEffect } from 'react';
 
function MyApp() {
  const { data: walletClient } = useWalletClient();
  
  // Address is automatically extracted from walletClient
  const grapevine = useGrapevine({
    walletClient,
    network: 'testnet'
  });
  
  const isReady = useGrapevineReady(grapevine);
 
  const [feeds, setFeeds] = useState([]);
 
  useEffect(() => {
    if (isReady) {
      loadUserFeeds();
    }
  }, [isReady]);
 
  const loadUserFeeds = async () => {
    try {
      const userFeeds = await grapevine.feeds.myFeeds();
      setFeeds(userFeeds.data);
    } catch (error) {
      console.error('Failed to load feeds:', error);
    }
  };
 
  const createNewFeed = async () => {
    try {
      const feed = await grapevine.feeds.create({
        name: 'My React Feed',
        description: 'Created from React app',
        tags: ['react', 'web3']
      });
      
      setFeeds([feed, ...feeds]);
    } catch (error) {
      console.error('Failed to create feed:', error);
    }
  };
 
  if (!isReady) {
    return <div>Connect your wallet to continue...</div>;
  }
 
  return (
    <div>
      <h1>My Feeds ({feeds.length})</h1>
      
      <button onClick={createNewFeed}>
        Create New Feed
      </button>
 
      <div>
        {feeds.map(feed => (
          <div key={feed.id} className="feed-card">
            <h3>{feed.name}</h3>
            <p>{feed.description}</p>
            <small>{feed.total_entries} entries</small>
          </div>
        ))}
      </div>
    </div>
  );
}

Environment Setup

Testnet (Recommended for Development)

# .env
PRIVATE_KEY=0x_your_private_key_here
GRAPEVINE_NETWORK=testnet
Testnet Benefits:
  • Free to use
  • No real money at risk
  • Same API functionality as mainnet
  • Get test ETH from Base Sepolia faucet

Mainnet (Production)

# .env
PRIVATE_KEY=0x_your_private_key_here
GRAPEVINE_NETWORK=mainnet
Mainnet Requirements:
  • Real ETH for gas fees
  • Real USDC for x402 payments
  • Production wallet security

Common Patterns

Error Handling

try {
  const feed = await grapevine.feeds.create(feedData);
  console.log('Success!', feed.id);
} catch (error) {
  if (error.message.includes('402')) {
    console.log('Payment required - ensure you have USDC');
  } else if (error.message.includes('401')) {
    console.log('Authentication failed - check private key');
  } else {
    console.error('Unexpected error:', error.message);
  }
}

Pagination

// Get all user feeds across multiple pages
const allFeeds = [];
let pageToken: string | undefined;
 
do {
  const response = await grapevine.feeds.myFeeds({
    page_token: pageToken,
    page_size: 50
  });
  
  allFeeds.push(...response.data);
  pageToken = response.next_page_token;
  
} while (pageToken);
 
console.log(`Loaded ${allFeeds.length} total feeds`);
 
// Or use the paginate helper
for await (const batch of grapevine.feeds.paginate({}, 50)) {
  console.log(`Processing ${batch.length} feeds`);
}

Batch Operations

// Create multiple entries efficiently
const entryData = [
  { title: 'Post 1', content: 'Content 1', mime_type: 'text/plain' },
  { title: 'Post 2', content: 'Content 2', mime_type: 'text/plain' },
  { title: 'Post 3', content: 'Content 3', mime_type: 'text/plain' }
];
 
const results = await grapevine.entries.batchCreate(feedId, entryData, {
  delayMs: 500 // Rate limiting between requests
});
 
console.log(`Created ${results.successful.length} entries`);
if (results.failed.length > 0) {
  console.log(`Failed to create ${results.failed.length} entries`);
}

Network Configuration

Base Sepolia (Testnet)

  • Chain ID: 84532
  • RPC: https://sepolia.base.org
  • API: https://api.grapevine.markets
  • Faucet: Base Sepolia Faucet

Base Mainnet (Production)

  • Chain ID: 8453
  • RPC: https://mainnet.base.org
  • API: https://api.grapevine.fyi

Useful Utilities

// Get wallet information
const address = grapevine.getWalletAddress();
const network = grapevine.getNetwork();
const isTestnet = grapevine.isTestNetwork();
 
console.log(`Connected to ${network} (testnet: ${isTestnet})`);
console.log(`Wallet: ${address}`);
 
// Check if wallet is configured
if (grapevine.hasWallet()) {
  // Safe to make authenticated API calls
  const myFeeds = await grapevine.feeds.myFeeds();
}
 
// Get available categories
const categories = await grapevine.categories.getAll();
console.log('Categories:', categories.map(c => c.name));

Next Steps

Now that you have the basics working:

  1. Browse Examples - See more code examples
  2. API Reference - Learn all available methods
  3. Error Handling - Handle errors gracefully
  4. React Integration - Build React apps with hooks
  5. Testing Guide - Test your integration

Need Help?


🎉 You're ready to build with Grapevine! Start creating feeds and publishing content on the decentralized web.