@common-ground-dao/cg-plugin-lib
Drop-in replacement for Common Ground's client-side plugin library. This package provides the exact same API as the original @common-ground-dao/cg-plugin-lib but communicates with our custom host system instead of Common Ground's servers.
π― Purpose
This library allows existing Common Ground plugins to work without any code changes in your own hosting environment. Simply replace the package source and your plugins will seamlessly integrate with your custom host system.
π¦ Installation
npm install @common-ground-dao/cg-plugin-lib
yarn add @common-ground-dao/cg-plugin-lib
π Usage
Initialization (Exactly like original CG)
import { CgPluginLib } from '@common-ground-dao/cg-plugin-lib';
const cgPluginLib = await CgPluginLib.initialize(
iframeUid,
'/api/sign',
publicKey
);
API Methods (100% Compatible)
const userResponse = await cgPluginLib.getUserInfo();
console.log(userResponse.data);
const communityResponse = await cgPluginLib.getCommunityInfo();
console.log(communityResponse.data);
const friendsResponse = await cgPluginLib.getUserFriends(10, 0);
console.log(friendsResponse.data.friends);
await cgPluginLib.giveRole('contributor', 'user_12345');
Singleton Pattern (Exactly like original CG)
const lib = CgPluginLib.getInstance();
const userInfo = await lib.getUserInfo();
π§ API Reference
CgPluginLib.initialize(iframeUid, signEndpoint, publicKey)
Initialize the plugin library with host communication.
Parameters:
iframeUid: string - Unique iframe identifier from URL parameters
signEndpoint: string - Plugin's signing endpoint (e.g., '/api/sign')
publicKey: string - Plugin's public key for signature verification
Returns: Promise<CgPluginLib> - Initialized instance
CgPluginLib.getInstance()
Get the singleton instance after initialization.
Returns: CgPluginLib - The initialized instance
Throws: Error if not initialized
getUserInfo()
Get current user's profile and authentication data.
Returns: Promise<ApiResponse<UserInfoResponsePayload>>
interface UserInfoResponsePayload {
id: string;
name: string;
email?: string;
roles: string[];
twitter?: { username: string };
lukso?: { username: string };
farcaster?: { username: string };
}
Get community details and available roles.
Returns: Promise<ApiResponse<CommunityInfoResponsePayload>>
interface CommunityInfoResponsePayload {
id: string;
title: string;
description?: string;
roles: Array<{
id: string;
title: string;
description?: string;
assignmentRules?: {
type: string;
requirements?: any;
} | null;
}>;
}
getUserFriends(limit, offset)
Get user's friends/connections with pagination.
Parameters:
limit: number - Maximum number of friends to return
offset: number - Number of friends to skip (for pagination)
Returns: Promise<ApiResponse<UserFriendsResponsePayload>>
interface UserFriendsResponsePayload {
friends: Array<{
id: string;
name: string;
imageUrl: string;
}>;
}
giveRole(roleId, userId)
Assign a role to a user.
Parameters:
roleId: string - ID of the role to assign
userId: string - ID of the user to assign the role to
Returns: Promise<ApiResponse<void>>
ποΈ Architecture
Communication Flow
Plugin Code
β
CgPluginLib.getUserInfo()
β
Internal request signing via /api/sign
β
postMessage to host with signed request
β
Host validates signature and responds
β
Response returned to plugin
Security Features
- Cryptographic Signing: All requests are signed using your plugin's private key
- Request Correlation: Unique request IDs prevent response confusion
- Timeout Handling: Requests timeout after 30 seconds
- Error Handling: Comprehensive error messages and recovery
Request Signing Process
- Plugin makes API call (e.g.,
getUserInfo())
- Library prepares request data with timestamp
- Request sent to plugin's
/api/sign endpoint
- Plugin's server signs the request using private key
- Signed request sent to host via postMessage
- Host validates signature and processes request
π Integration Examples
Basic Plugin Setup
'use client';
import { CgPluginLib } from '@common-ground-dao/cg-plugin-lib';
import { useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
export default function MyPlugin() {
const [userInfo, setUserInfo] = useState(null);
const searchParams = useSearchParams();
const iframeUid = searchParams.get('iframeUid');
useEffect(() => {
async function initPlugin() {
const lib = await CgPluginLib.initialize(
iframeUid || '',
'/api/sign',
process.env.NEXT_PUBLIC_PUBKEY
);
const response = await lib.getUserInfo();
setUserInfo(response.data);
}
initPlugin();
}, [iframeUid]);
return (
<div>
<h1>Welcome {userInfo?.name}!</h1>
{/* Your plugin UI here */}
</div>
);
}
Server-side Signing Endpoint
import { CgPluginLibHost } from '@common-ground-dao/cg-plugin-lib-host';
export async function POST(req: Request) {
const body = await req.json();
const host = await CgPluginLibHost.initialize(
process.env.PRIVATE_KEY,
process.env.PUBLIC_KEY
);
const { request, signature } = await host.signRequest(body);
return Response.json({ request, signature });
}
π Migration from Original CG
No Code Changes Required!
If you have an existing Common Ground plugin, simply:
- Update package source: Point to our npm registry or local packages
- Update dependencies:
yarn add @common-ground-dao/cg-plugin-lib
- Test: Your plugin should work exactly the same
Environment Variables
Make sure your plugin has the required environment variables:
NEXT_PUBLIC_PUBKEY=your_public_key_here
NEXT_PRIVATE_PRIVKEY=your_private_key_here
π Error Handling
The library provides comprehensive error handling:
try {
const userInfo = await lib.getUserInfo();
} catch (error) {
if (error.message.includes('timeout')) {
} else if (error.message.includes('signature')) {
} else {
}
}
π§ Development
Building the Library
yarn build
yarn dev
Testing
Test the library using the host application:
cd packages/host-app
yarn dev
π Compatibility Matrix
| 0.9.6 | 0.9.6 | β
Fully compatible |
| Earlier versions | 0.9.6 | β
Forward compatible |
π€ Contributing
This package is part of the standalone embed system. See the root README for contribution guidelines.
π License
MIT License
Note: This is a drop-in replacement library. All code examples that work with the original @common-ground-dao/cg-plugin-lib will work exactly the same with this implementation.