tapestry

Social graph protocol integration for Copium app using Tapestry API. Use when building social features - profiles, follows, content/posts, comments, likes, activity feeds, identity resolution, or trades. Covers all 41 Tapestry API endpoints.

16 stars

Best use case

tapestry is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Social graph protocol integration for Copium app using Tapestry API. Use when building social features - profiles, follows, content/posts, comments, likes, activity feeds, identity resolution, or trades. Covers all 41 Tapestry API endpoints.

Teams using tapestry should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/tapestry/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/tapestry/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/tapestry/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How tapestry Compares

Feature / AgenttapestryStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Social graph protocol integration for Copium app using Tapestry API. Use when building social features - profiles, follows, content/posts, comments, likes, activity feeds, identity resolution, or trades. Covers all 41 Tapestry API endpoints.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Tapestry Social Graph Integration

You are building social features for a React Native (Expo) mobile app called **Copium** - a social trading app using Tapestry and Polymarket.

## Project Context

- **Framework**: React Native with Expo Router (file-based routing)
- **Auth**: Privy (OAuth + embedded Solana wallet) + Mobile Wallet Adapter (MWA)
- **Wallet hook**: `useUnifiedWallet()` from `@/hooks/use-wallet` provides `address`, `walletType`, `provider`, `isConnected`, `logout`
- **State**: React Query (`@tanstack/react-query`) for server state
- **Styling**: StyleSheet with `#0a0a0a` bg, `#232323` borders, `PlusJakartaSans` font
- **API Key**: `process.env.TAPESTRY_API_KEY` (server-side only, stored in `.env.local`)
- **Base URL**: `https://api.usetapestry.dev/api/v1`

## API Authentication

All endpoints require `apiKey` as a query parameter:
```
GET /profiles/{id}?apiKey=YOUR_API_KEY
```

The API key is in `.env.local` as `TAPESTRY_API_KEY`. Since this is a React Native app (no server-side routes), call the Tapestry API directly from a utility module, keeping the API key secure via `process.env.TAPESTRY_API_KEY` (bundled at build time but not exposed to web).

## Execution Methods (for write operations)

| Method | Speed | Use When |
|--------|-------|----------|
| `FAST_UNCONFIRMED` | <1s | Default. Returns after graph DB write, on-chain tx in background |
| `QUICK_SIGNATURE` | ~5s | Need tx signature but don't need confirmation |
| `CONFIRMED_AND_PARSED` | ~15s | Need full on-chain confirmation |

## API Client Pattern

Create API calls in `lib/tapestry/` directory. Use this pattern:

```typescript
// lib/tapestry/client.ts
const TAPESTRY_BASE = 'https://api.usetapestry.dev/api/v1';
const API_KEY = process.env.TAPESTRY_API_KEY!;

export async function tapestryFetch<T>(
  endpoint: string,
  options?: { method?: string; body?: any; params?: Record<string, string> }
): Promise<T> {
  const { method = 'GET', body, params = {} } = options ?? {};
  const url = new URL(`${TAPESTRY_BASE}${endpoint}`);
  url.searchParams.set('apiKey', API_KEY);
  Object.entries(params).forEach(([k, v]) => v && url.searchParams.set(k, v));

  const res = await fetch(url.toString(), {
    method,
    headers: body ? { 'Content-Type': 'application/json' } : undefined,
    body: body ? JSON.stringify(body) : undefined,
  });

  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.error || `Tapestry API error: ${res.status}`);
  }
  return res.json();
}
```

## React Hook Pattern

```typescript
// hooks/use-tapestry-profile.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { tapestryFetch } from '@/lib/tapestry/client';

export function useTapestryProfile(username: string) {
  return useQuery({
    queryKey: ['tapestry-profile', username],
    queryFn: () => tapestryFetch<ProfileResponse>(`/profiles/${username}`),
    enabled: !!username,
  });
}
```

## All Endpoints Reference

For detailed endpoint specs, see [reference.md](reference.md).

### Quick Endpoint Map

**Profiles**
- `GET /profiles/` - List/search profiles (by wallet, phone, twitter, email)
- `POST /profiles/findOrCreate` - Find or create profile
- `GET /profiles/{id}` - Get profile by ID or username
- `PUT /profiles/{id}` - Update profile
- `GET /profiles/{id}/followers` - Get followers
- `GET /profiles/{id}/following` - Get following
- `GET /profiles/{id}/followers/global` - Cross-namespace followers
- `GET /profiles/{id}/following/global` - Cross-namespace following
- `GET /profiles/{id}/following-who-follow` - Mutual connections
- `GET /profiles/{id}/wallets` - Get linked wallets
- `PATCH /profiles/{id}/wallets` - Link wallets
- `DELETE /profiles/{id}/wallets` - Unlink wallets
- `PATCH /profiles/{id}/contacts` - Link contacts
- `DELETE /profiles/{id}/contacts` - Unlink contacts
- `POST /profiles/{id}/notification` - Send notification
- `GET /profiles/{id}/referrals` - Get referral tree
- `GET /profiles/{id}/suggested-profiles` - Suggested follows
- `GET /profiles/suggested/{identifier}` - Suggestions by wallet/contact
- `GET /profiles/suggested/{identifier}/global` - Cross-namespace suggestions
- `GET /profiles/token-owners/{tokenAddress}` - Token holder profiles
- `GET /search/profiles` - Search profiles by text

**Social Graph (Followers)**
- `POST /followers/add` - Follow `{ startId, endId }`
- `POST /followers/remove` - Unfollow `{ startId, endId }`
- `GET /followers/state` - Check follow state `?startId=&endId=`

**Content (Posts)**
- `GET /contents/` - List content (with filters, ordering, pagination)
- `GET /contents/aggregation` - Aggregate content properties
- `POST /contents/batch/read` - Batch get by IDs (max 20)
- `POST /contents/findOrCreate` - Create content `{ id, profileId, properties: [{key,value}] }`
- `GET /contents/{id}` - Get content details
- `PUT /contents/{id}` - Update content properties
- `DELETE /contents/{id}` - Delete content

**Comments**
- `GET /comments/` - List comments `?contentId=&profileId=&targetProfileId=`
- `POST /comments/` - Create comment `{ profileId, text, contentId?, commentId?, targetProfileId? }`
- `POST /comments/batch/read` - Batch get (max 20)
- `GET /comments/{id}` - Get comment with replies
- `PUT /comments/{id}` - Update comment
- `DELETE /comments/{id}` - Delete comment
- `GET /comments/{id}/replies` - Get replies

**Likes**
- `GET /likes/{nodeId}` - Get profiles who liked a node
- `POST /likes/{nodeId}` - Like `{ startId }`
- `DELETE /likes/{nodeId}` - Unlike `{ startId }`

**Activity Feeds**
- `GET /activity/feed` - User activity feed `?username=`
- `GET /activity/global` - Global activity feed
- `GET /activity/swap` - Swap activity from followed wallets `?username=&tokenAddress=`

**Identities**
- `GET /identities/{id}` - Resolve wallets/contacts from ID
- `GET /identities/{id}/profiles` - Find profiles across namespaces

**Trades**
- `POST /trades/` - Log a trade
- `GET /trades/all-trades` - Get all trades in time period
- `GET /trades/fetch-transaction-history` - Wallet tx history

**Wallets**
- `POST /wallets/{address}/connect` - Connect two wallets
- `GET /wallets/{address}/socialCounts` - Social counts by wallet

## Key Integration Points for Copium

### 1. Profile Creation (on signup/login)
After wallet connection + X login, call `findOrCreate`:
```typescript
await tapestryFetch('/profiles/findOrCreate', {
  method: 'POST',
  body: {
    username: twitterHandle, // from Privy OAuth
    walletAddress: address,  // from useUnifiedWallet
    blockchain: 'SOLANA',
    image: twitterProfileImage,
    bio: twitterBio,
    contact: { id: twitterHandle, type: 'TWITTER' },
  },
});
```

### 2. Follow/Unfollow
```typescript
await tapestryFetch('/followers/add', {
  method: 'POST',
  body: { startId: myProfileId, endId: targetProfileId },
});
```

### 3. Create a Post (Content)
```typescript
await tapestryFetch('/contents/findOrCreate', {
  method: 'POST',
  body: {
    id: `post-${Date.now()}`,
    profileId: myProfileId,
    properties: [
      { key: 'text', value: 'My post content' },
      { key: 'type', value: 'trade_call' },
    ],
  },
});
```

### 4. Like Content
```typescript
await tapestryFetch(`/likes/${contentId}`, {
  method: 'POST',
  body: { startId: myProfileId },
});
```

### 5. Comment on Content
```typescript
await tapestryFetch('/comments/', {
  method: 'POST',
  body: {
    profileId: myProfileId,
    contentId: contentId,
    text: 'Great trade!',
  },
});
```

### 6. Activity Feed
```typescript
const feed = await tapestryFetch('/activity/feed', {
  params: { username: myUsername },
});
```

### 7. Search Users
```typescript
const results = await tapestryFetch('/search/profiles', {
  params: { query: searchText },
});
```

### 8. Polymarket Integration Pattern
Store Polymarket-related data as content properties:
```typescript
await tapestryFetch('/contents/findOrCreate', {
  method: 'POST',
  body: {
    id: `prediction-${marketId}-${profileId}`,
    profileId: myProfileId,
    properties: [
      { key: 'type', value: 'prediction' },
      { key: 'marketId', value: polymarketConditionId },
      { key: 'position', value: 'YES' },
      { key: 'amount', value: 50 },
      { key: 'odds', value: 0.65 },
    ],
  },
});
```

## Response Types

```typescript
interface TapestryProfile {
  id: string;
  namespace: string;
  created_at: number;
  username: string;
  bio: string | null;
  image: string | null;
}

interface ProfileResponse {
  profile: TapestryProfile;
  walletAddress: string;
  socialCounts: { followers: number; following: number };
  namespace: { name: string | null; readableName: string | null };
}

interface ContentResponse {
  id: string;
  created_at: number;
  properties: Record<string, any>;
}

interface CommentResponse {
  comment: { id: string; created_at: number; text: string };
  author: TapestryProfile;
  socialCounts: { likeCount: number };
  requestingProfileSocialInfo?: { hasLiked: boolean };
}

interface ActivityItem {
  type: 'following' | 'new_content' | 'like' | 'comment' | 'new_follower';
  actor_id: string;
  actor_username: string;
  target_id?: string;
  target_username?: string;
  timestamp: number;
  activity: string;
}

interface PaginatedResponse<T> {
  page: number;
  pageSize: number;
  totalCount: number;
  data?: T[];
  profiles?: T[];
  activities?: T[];
}
```

## File Structure Convention

```
lib/tapestry/
  client.ts          # Base fetch wrapper
  profiles.ts        # Profile API functions
  social.ts          # Follow/unfollow/like functions
  content.ts         # Content/posts CRUD
  comments.ts        # Comments CRUD
  activity.ts        # Activity feed functions
  types.ts           # TypeScript interfaces

hooks/
  use-tapestry-profile.ts
  use-tapestry-feed.ts
  use-tapestry-social.ts
  use-tapestry-content.ts
```

When implementing features with `$ARGUMENTS`, refer to [reference.md](reference.md) for full endpoint details.

Related Skills

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

testing-builder

16
from diegosouzapw/awesome-omni-skill

Automatically generates comprehensive test suites (unit, integration, E2E) based on code and past testing patterns. Use when user says "write tests", "test this", "add coverage", or after fixing bugs to create regression tests. Eliminates testing friction for ADHD users.

Testing Anti-Patterns

16
from diegosouzapw/awesome-omni-skill

This skill should be used when encountering "flaky tests", "test maintenance issues", "slow test suites", "brittle tests", "test code smells", "test debugging problems", or when tests are hard to understand, maintain, or debug.

testcontainers-integration-tests

16
from diegosouzapw/awesome-omni-skill

Use when integration tests require real infrastructure (database, message queue, cache) or when mocking infrastructure is insufficient. Defines container lifecycle, test isolation, and performance optimization for Testcontainers-based testing.

test-generation

16
from diegosouzapw/awesome-omni-skill

Master skill for intelligent test case generation. Identifies technology stack and delegates to specialized testing sub-skills for creating high-quality integration and API tests.

test-driven-development

16
from diegosouzapw/awesome-omni-skill

Use when implementing any feature or bugfix, before writing implementation code

Test and Refine Your Kubernetes Skill

16
from diegosouzapw/awesome-omni-skill

No description provided.

test-and-fix-workflow

16
from diegosouzapw/awesome-omni-skill

Automated workflow for running tests and fixing failures systematically. Use when implementing the mandatory test workflow or fixing code quality issues. Keywords - testing, debugging, workflow, failures, systematic fixes.

terway-troubleshooting

16
from diegosouzapw/awesome-omni-skill

Troubleshoot Terway CNI issues in Kubernetes using Kubernetes events and Terway logs. Use when diagnosing "cni plugin not initialized", Pod create/delete failures, or ENI/IPAM problems in Terway (centralized or non-centralized IPAM).

Tero Voice Project Context

16
from diegosouzapw/awesome-omni-skill

Load full project context, tech stack, status, and guidelines for the AI Receptionist SaaS project

temporal-python-pro

16
from diegosouzapw/awesome-omni-skill

Master Temporal workflow orchestration with Python SDK. Implements durable workflows, saga patterns, and distributed transactions. Covers async/await, testing strategies, and production deployment.

temporal-golang-pro

16
from diegosouzapw/awesome-omni-skill

Use when building durable distributed systems with Temporal Go SDK. Covers deterministic workflow rules, mTLS worker configs, and advanced patterns.