SDK Reference
Complete API reference for the Grapevine SDK.
GrapevineClient
The main client class for interacting with the Grapevine API.
Constructor
new GrapevineClient(config?: GrapevineConfig)GrapevineConfig
| Property | Type | Required | Description |
|---|---|---|---|
privateKey | string | No | Private key for wallet authentication (0x prefixed, 66 chars) |
walletAdapter | WalletAdapter | No | Wallet adapter for browser usage (use WagmiAdapter) |
network | 'testnet' | 'mainnet' | No | Network to connect to (default: 'testnet') |
debug | boolean | No | Enable debug logging (default: false) |
Network URLs (set automatically based on network):
testnet: https://api.grapevine.markets (Base Sepolia)mainnet: https://api.grapevine.fyi (Base)
Note: Either privateKey or walletAdapter can be provided for authentication. If neither is provided, the client will work for public endpoints only. You can configure a wallet later using setWalletClient().
Properties
feeds: FeedsResource
Feed management operations.
entries: EntriesResource
Entry management operations.
wallets: WalletsResource
Wallet profile and stats operations.
transactions: TransactionsResource
Transaction listing and lookup.
leaderboards: LeaderboardsResource
Leaderboard data (trending, popular, top revenue, etc).
categories: CategoriesResource
Category listing and lookup.
Methods
categories.getAll()
Get all available content categories.
categories.getAll(): Promise<Category[]>Returns: Array of category objects
Example:
const categories = await grapevine.categories.getAll();
console.log(categories); // [{ id: '...', name: 'technology', ... }, ...]getWalletAddress()
Get the current wallet address.
getWalletAddress(): stringReturns: Ethereum address (0x prefixed)
Throws: Error if no wallet is configured. Use setWalletClient() to configure a wallet first.
getNetwork()
Get the current network.
getNetwork(): stringReturns: Network identifier string (e.g., 'base-sepolia' for testnet, 'base' for mainnet)
isTestNetwork()
Check if using testnet.
isTestNetwork(): booleansetWalletClient(walletAdapter: WalletAdapter)
Set or update the wallet client for authentication. This allows dynamic wallet configuration after initialization.
setWalletClient(walletAdapter: WalletAdapter): voidhasWallet()
Check if a wallet is currently configured.
hasWallet(): booleanclearWallet()
Clear the current wallet configuration. Useful for logout scenarios.
clearWallet(): voidFeedsResource
Feed management operations accessible via grapevine.feeds.
create(input: CreateFeedInput): Promise<Feed>
Create a new feed.
interface CreateFeedInput {
name: string; // Required - feed name
description?: string; // Optional description
tags?: string[]; // Optional array of tags
category_id?: string; // Optional category UUID
image_url?: string; // Optional image URL or base64
}list(query?: ListFeedsQuery): Promise<PaginatedResponse<Feed>>
List feeds with optional filtering.
interface ListFeedsQuery {
page_size?: number; // Results per page (default: 20)
page_token?: string; // Pagination token
owner_id?: string; // Filter by owner UUID
category?: string; // Filter by category UUID
tags?: string[]; // Filter by tags
min_entries?: number; // Minimum entry count
min_age?: number; // Minimum age in seconds
max_age?: number; // Maximum age in seconds
is_active?: boolean; // Filter by active status
}get(feedId: string): Promise<Feed>
Get a specific feed by ID.
update(feedId: string, input: UpdateFeedInput): Promise<Feed>
Update an existing feed.
interface UpdateFeedInput {
name?: string;
description?: string;
tags?: string[];
category_id?: string;
is_active?: boolean;
image_url?: string;
}delete(feedId: string): Promise<void>
Delete a feed.
myFeeds(query?: ListFeedsQuery): Promise<PaginatedResponse<Feed>>
Get feeds owned by the current wallet.
Throws: Error if no wallet is configured.
paginate(query?: ListFeedsQuery, pageSize?: number): AsyncGenerator<Feed[]>
Async generator that yields batches of feeds.
// Example usage
for await (const batch of grapevine.feeds.paginate()) {
batch.forEach(feed => console.log(feed.name));
}createAccessLink(feedId: string, entryId: string): Promise<AccessLink>
Create a private access link for an entry.
interface AccessLink {
url: string;
expires_at: number;
}EntriesResource
Entry management operations accessible via grapevine.entries.
create(feedId: string, input: CreateEntryInput): Promise<Entry>
Create a new entry in a feed.
interface CreateEntryInput {
// Provide ONE of these content options:
content?: string | Buffer | Blob | File | ArrayBuffer | object;
content_base64?: string; // Pre-encoded base64 content
mime_type?: string; // Auto-detected if not provided
title?: string; // Optional title
description?: string; // Optional description
metadata?: Record<string, any>; // Additional metadata
tags?: string[]; // Optional tags
is_free?: boolean; // Default: true
expires_at?: number; // Unix timestamp expiration
price?: { // Required for paid entries
amount: string; // Amount in smallest unit (e.g., "1000000" for 1 USDC)
currency: string; // Currency (e.g., "USDC")
};
}list(feedId: string, query?: ListEntriesQuery): Promise<PaginatedResponse<Entry>>
List entries in a feed.
interface ListEntriesQuery {
page_size?: number; // Results per page (default: 20)
page_token?: string; // Pagination token
is_free?: boolean; // Filter by free status
}get(feedId: string, entryId: string): Promise<Entry>
Get a specific entry by ID.
delete(feedId: string, entryId: string): Promise<void>
Delete an entry.
batchCreate(feedId: string, entries: CreateEntryInput[], options?: BatchOptions): Promise<BatchResult>
Create multiple entries in a single operation.
interface BatchOptions {
onProgress?: (completed: number, total: number) => void;
delayMs?: number; // Rate limiting delay between requests
}
interface BatchResult {
successful: Entry[];
failed: Array<{
input: CreateEntryInput;
error: string;
}>;
}paginate(feedId: string, query?: ListEntriesQuery, pageSize?: number): AsyncGenerator<Entry[]>
Async generator that yields batches of entries.
Type Definitions
Feed
interface Feed {
id: string;
owner_id: string;
owner_wallet_address: string;
category_id?: string;
name: string;
description?: string;
image_cid?: string; // IPFS CID of uploaded image
is_active: boolean;
total_entries: number;
total_purchases: number;
total_revenue: string;
tags: string[] | null;
created_at: number;
updated_at: number;
}Entry
interface Entry {
id: string;
feed_id: string;
cid: string; // IPFS content identifier
mime_type: string;
title?: string | null;
description?: string | null;
metadata?: string | null; // JSON string
tags: string[] | null;
is_free: boolean;
expires_at?: number | null;
is_active: boolean;
total_purchases: number;
total_revenue: string;
pinata_upload_id?: string | null;
piid?: string | null;
created_at: number;
updated_at: number;
}PaginatedResponse
interface PaginatedResponse<T> {
data: T[];
next_page_token?: string;
has_more: boolean;
}Category
interface Category {
id: string;
name: string;
description: string | null;
icon_url: string | null;
is_active: boolean;
created_at: number;
updated_at: number;
}Wallet
interface Wallet {
id: string;
wallet_address: string;
wallet_address_network: WalletNetwork;
username: string | null;
picture_url: string | null;
created_at: number;
updated_at: number;
}
type WalletNetwork =
| 'base'
| 'base-sepolia'
| 'ethereum'
| 'ethereum-sepolia'
| 'polygon'
| 'polygon-amoy';Transaction
interface Transaction {
id: string;
piid?: string | null;
payer: string;
pay_to: string;
amount: string;
asset: string;
entry_id?: string | null;
transaction_hash: string;
created_at: number;
}React Hooks
useGrapevine(options: UseGrapevineOptions): GrapevineClient | null
React hook for creating a Grapevine client with wallet integration.
interface UseGrapevineOptions {
walletClient: WalletClient | undefined; // From useWalletClient()
network?: 'testnet' | 'mainnet';
debug?: boolean;
}Example:
import { useGrapevine, useGrapevineReady } from '@pinata/grapevine-sdk/react';
import { useWalletClient } from 'wagmi';
function MyComponent() {
const { data: walletClient } = useWalletClient();
const grapevine = useGrapevine({
walletClient,
network: 'testnet'
});
const isReady = useGrapevineReady(grapevine);
if (!grapevine || !isReady) {
return <div>Loading...</div>;
}
// Client is ready - can use public endpoints
const loadPublicFeeds = () => grapevine.feeds.list();
}useGrapevineReady(grapevine: GrapevineClient | null): boolean
Hook to check if Grapevine client is ready to use.
const grapevine = useGrapevine({ walletClient, network: 'testnet' });
const isReady = useGrapevineReady(grapevine);useGrapevineWalletReady(grapevine: GrapevineClient | null): boolean
Hook to check if Grapevine client has a wallet configured and ready for authenticated operations.
const grapevine = useGrapevine({ walletClient, network: 'testnet' });
const hasWallet = useGrapevineWalletReady(grapevine);Error Handling
All SDK methods throw errors for failed operations. Common error patterns:
import {
GrapevineError,
ContentError,
AuthError,
ApiError,
ValidationError,
ErrorCode
} from '@pinata/grapevine-sdk';
try {
const feed = await grapevine.feeds.create(feedData);
} catch (error) {
if (error instanceof AuthError) {
// Authentication/wallet error
console.error('Auth error:', error.message);
} else if (error instanceof ApiError) {
// API request failed
if (error.status === 402) {
console.log('Payment required');
} else if (error.status === 404) {
console.log('Not found');
}
} else if (error instanceof ValidationError) {
// Input validation error
console.error('Validation:', error.message);
} else if (error instanceof ContentError) {
// Content processing error
console.error('Content:', error.message);
}
}For comprehensive error handling, see the Error Handling Guide.
Advanced Usage
Dynamic Wallet Management
You can now use the Grapevine client for public operations without a wallet, and dynamically configure authentication when needed:
// Initialize client without wallet for public operations
const grapevine = new GrapevineClient({ network: 'testnet' });
// Use public endpoints
const categories = await grapevine.categories.getAll();
const publicFeeds = await grapevine.feeds.list();
// Later, configure wallet for authenticated operations
import { WagmiAdapter } from '@pinata/grapevine-sdk/adapters';
// Address is extracted from walletClient.account.address
const adapter = new WagmiAdapter(walletClient);
grapevine.setWalletClient(adapter);
// Now you can use authenticated operations
if (grapevine.hasWallet()) {
const myFeeds = await grapevine.feeds.myFeeds();
const address = grapevine.getWalletAddress();
}
// Clear wallet when user logs out
grapevine.clearWallet();All Resources Available
The SDK provides access to all API resources:
// Wallets
const wallet = await grapevine.wallets.getByAddress('0x...');
const stats = await grapevine.wallets.getStats(wallet.id);
// Transactions
const transactions = await grapevine.transactions.list({ payer: '0x...' });
// Leaderboards
const trending = await grapevine.leaderboards.trending();
const topProviders = await grapevine.leaderboards.topProviders({ period: '7d' });
const recentEntries = await grapevine.leaderboards.recentEntries();
// Categories
const categories = await grapevine.categories.getAll();Check Configuration
Access client configuration:
const network = grapevine.getNetwork(); // 'base-sepolia' or 'base'
const isTestnet = grapevine.isTestNetwork();
const hasWallet = grapevine.hasWallet();
console.log('Network:', network);
console.log('Is Testnet:', isTestnet);
console.log('Has Wallet:', hasWallet);
if (hasWallet) {
console.log('Wallet:', grapevine.getWalletAddress());
}Migration Guide
From v0.1.7 to v0.1.8
New Features:- Dynamic wallet management:
setWalletClient(),hasWallet(),clearWallet() - Public endpoint support: Client works without wallet configuration
- New React hook:
useGrapevineWalletReady() - Improved error messages for better developer experience
// Old (v0.1.7) - Required wallet at initialization
const grapevine = new GrapevineClient({
privateKey: process.env.PRIVATE_KEY,
network: 'testnet'
});
// New (v0.1.8) - Wallet optional, can be set later
const grapevine = new GrapevineClient({ network: 'testnet' });
// Use public endpoints without wallet
const publicFeeds = await grapevine.feeds.list();
// Set wallet when needed
grapevine.setWalletClient(adapter);
const myFeeds = await grapevine.feeds.myFeeds();From v0.1.6 to v0.1.7
Breaking Changes:feeds.list()now usesListFeedsQueryinstead ofListFeedsOptions- Token-based pagination replaces limit/offset pagination
// Old (v0.1.6)
const feeds = await grapevine.feeds.list({
limit: 20,
offset: 40
});
// New (v0.1.7)
const feeds = await grapevine.feeds.list({
page_size: 20,
page_token: 'token-from-previous-response'
});Examples
See the Complete Examples page for working code samples covering:
- Basic feed and entry operations
- React integration with hooks
- Error handling patterns
- Batch operations
- Pagination
- Payment handling
Support
- Error Handling - Handle errors gracefully
- Quick Start - Get started quickly
- API Documentation - Full REST API reference
- GitHub Issues - Report issues