Automated summary
Integrates the Tapestry social graph protocol into a React Native app to manage profiles, follows, content, and social interactions.
Strengths
- Covers all 41 Tapestry API endpoints
- Provides ready-to-use client and React Query hook patterns
- Handles API key authentication and execution methods for write operations
- Tailored for social trading apps like Copium
Limitations
- API key is bundled in the app, posing a potential security risk
- Requires understanding of the Tapestry API specifics
- Limited to a single social graph protocol
Use this skill when building social features such as profiles, feeds, follows, and social trading interactions with Tapestry.
Do not use if your app does not require a social graph or relies on a different protocol like Lens or Farcaster.
Security analysis
SafeThe skill is an informational reference; it does not instruct the AI to execute any shell commands, network requests, or file operations. The only concern is a potential insecure practice in the example, but this does not constitute a direct execution risk.
- •Recommends bundling API key into client-side React Native code (process.env.TAPESTRY_API_KEY), which can be extracted and may expose sensitive credentials.
Examples
I need to find or create a Tapestry profile for a user with wallet address 0x1234... and display name 'Alice'. Use the `/profiles/findOrCreate` endpoint with proper error handling.Create a React hook to fetch the list of followers for a given profile ID from Tapestry, using React Query and the paginated endpoint `/profiles/{id}/followers`.Implement a mutation that posts a comment to a Tapestry content item. Use the execution method FAST_UNCONFIRMED for speed, and invalidate the comments query after success.name: tapestry description: 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. argument-hint: [feature-or-endpoint]
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-walletprovidesaddress,walletType,provider,isConnected,logout - State: React Query (
@tanstack/react-query) for server state - Styling: StyleSheet with
#0a0a0abg,#232323borders,PlusJakartaSansfont - 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:
// 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
// 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.
Quick Endpoint Map
Profiles
GET /profiles/- List/search profiles (by wallet, phone, twitter, email)POST /profiles/findOrCreate- Find or create profileGET /profiles/{id}- Get profile by ID or usernamePUT /profiles/{id}- Update profileGET /profiles/{id}/followers- Get followersGET /profiles/{id}/following- Get followingGET /profiles/{id}/followers/global- Cross-namespace followersGET /profiles/{id}/following/global- Cross-namespace followingGET /profiles/{id}/following-who-follow- Mutual connectionsGET /profiles/{id}/wallets- Get linked walletsPATCH /profiles/{id}/wallets- Link walletsDELETE /profiles/{id}/wallets- Unlink walletsPATCH /profiles/{id}/contacts- Link contactsDELETE /profiles/{id}/contacts- Unlink contactsPOST /profiles/{id}/notification- Send notificationGET /profiles/{id}/referrals- Get referral treeGET /profiles/{id}/suggested-profiles- Suggested followsGET /profiles/suggested/{identifier}- Suggestions by wallet/contactGET /profiles/suggested/{identifier}/global- Cross-namespace suggestionsGET /profiles/token-owners/{tokenAddress}- Token holder profilesGET /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 propertiesPOST /contents/batch/read- Batch get by IDs (max 20)POST /contents/findOrCreate- Create content{ id, profileId, properties: [{key,value}] }GET /contents/{id}- Get content detailsPUT /contents/{id}- Update content propertiesDELETE /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 repliesPUT /comments/{id}- Update commentDELETE /comments/{id}- Delete commentGET /comments/{id}/replies- Get replies
Likes
GET /likes/{nodeId}- Get profiles who liked a nodePOST /likes/{nodeId}- Like{ startId }DELETE /likes/{nodeId}- Unlike{ startId }
Activity Feeds
GET /activity/feed- User activity feed?username=GET /activity/global- Global activity feedGET /activity/swap- Swap activity from followed wallets?username=&tokenAddress=
Identities
GET /identities/{id}- Resolve wallets/contacts from IDGET /identities/{id}/profiles- Find profiles across namespaces
Trades
POST /trades/- Log a tradeGET /trades/all-trades- Get all trades in time periodGET /trades/fetch-transaction-history- Wallet tx history
Wallets
POST /wallets/{address}/connect- Connect two walletsGET /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:
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
await tapestryFetch('/followers/add', {
method: 'POST',
body: { startId: myProfileId, endId: targetProfileId },
});
3. Create a Post (Content)
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
await tapestryFetch(`/likes/${contentId}`, {
method: 'POST',
body: { startId: myProfileId },
});
5. Comment on Content
await tapestryFetch('/comments/', {
method: 'POST',
body: {
profileId: myProfileId,
contentId: contentId,
text: 'Great trade!',
},
});
6. Activity Feed
const feed = await tapestryFetch('/activity/feed', {
params: { username: myUsername },
});
7. Search Users
const results = await tapestryFetch('/search/profiles', {
params: { query: searchText },
});
8. Polymarket Integration Pattern
Store Polymarket-related data as content properties:
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
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 for full endpoint details.
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/tapestry-social-graph-protocol-integration-mm5t8a4i/download' --output '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md.part' && mv '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md.part' '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && test -s '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/tapestry' && cp -R '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i' '.claude/skills/tapestry'Cursor
test -f '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && test -s '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/tapestry' && cp -R '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i' '.cursor/skills/tapestry'Codex
test -f '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && test -s '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/tapestry' && cp -R '.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i' '.agents/skills/tapestry'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i'openskills read 'tapestry-social-graph-protocol-integration-mm5t8a4i'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/tapestry-social-graph-protocol-integration-mm5t8a4i/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.