Skip to content

Integration Options

Typescript SDK

The @ecp.eth/sdk provides a comprehensive set of tools for interacting with the ECP protocol, including:

  • Creating and managing comments
  • Interacting with the smart contract
  • Fetching comments and replies from the indexer
  • Handling comment data and signatures

Installation

npm
npm install @ecp.eth/sdk
# install required peer dependencies
npm install viem wagmi @tanstack/react-query @tanstack/query-core

Core Concepts

Comment Data

The SDK provides utilities for creating and managing comment data. Each comment requires:

  • Content
  • Author address
  • App address
  • Either parent ID for replies or target URI for top-level comments

Contract Interaction

The SDK supports multiple comment posting flows, with the simplest being the "author pays gas" flow where:

  1. The author posts and pays for gas
  2. The app server authorizes the post by signing the comment data

For more details on different posting flows, see Post Comment Flows.

Examples

Creating and Posting Comments

Here's how to create and post a comment using the SDK:

import { createCommentData } from "@ecp.eth/sdk/comments";
import { usePostComment } from "@ecp.eth/sdk/comments/react";
import { waitForTransactionReceipt } from "wagmi";
import { parseEther } from "viem";
 
const comment = {
  content: "Hello, world!",
  author: "0x...", // author's address
  targetUri: "https://example.com",
};
 
// 1. Obtain the app signature from your backend
// You can use the Signer API Service to generate the signature
// @see https://github.com/ecp-eth/comments-monorepo/blob/main/apps/signer/README.md
//
// Or see the next section for server-side signing
const { signature: appSignature, commentData } = await fetch("/api/sign", {
  method: "POST",
  body: JSON.stringify({
    comment,
  }),
}).then((res) => res.json());
 
// 2. Post the comment (using wagmi)
// You can use the `usePostComment` hook to post the comment
const { mutateAsync: postCommentAsync } = usePostComment();
 
const { txHash } = await postCommentAsync({
  variables: {
    comment: commentData,
    appSignature,
    fee: parseEther("0.001"), // optional, fee to pay for the comment
  },
});
 
await waitForTransactionReceipt({
  hash: txHash,
});

Server-Side Signing

For security, the app signature should be generated on the server:

import {
  createCommentData,
  createCommentTypedData,
} from "@ecp.eth/sdk/comments";
import { SUPPORTED_CHAINS } from "@ecp.eth/sdk";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
import { hashTypedData } from "viem";
 
const chainConfig = SUPPORTED_CHAINS[baseSepolia.id];
 
const app = privateKeyToAccount(process.env.APP_SIGNER_PRIVATE_KEY);
 
const content = ""; // content obtained from the client
const author = ""; // author's address obtained from the client
const targetUri = ""; // target URI obtained from the client
 
// 1. Create comment data
const commentData = createCommentData({
  content,
  targetUri,
  author,
  app: app.address,
});
 
// 2. Create typed data for signing (EIP-712)
const typedCommentData = createCommentTypedData({
  commentData,
  chainId: chainConfig.chain.id,
});
 
// Sign using app's private key
const signature = await app.signTypedData(typedCommentData);
const hash = hashTypedData(typedCommentData);
 
return {
  hash,
  signature,
  commentData,
};

Fetching Comments

import { fetchComments } from "@ecp.eth/sdk/indexer";
 
const comments = await fetchComments({
  apiUrl: "https://api.ethcomments.xyz",
  targetUri: "https://example.com",
});
 
console.log("Comments:", comments);

The response includes a list of comments and pagination information, see IndexerAPIListCommentsSchemaType.

Fetching Replies

import { fetchCommentReplies } from "@ecp.eth/sdk/indexer";
 
const replies = await fetchCommentReplies({
  apiUrl: "https://api.ethcomments.xyz",
  commentId:
    "0xdce24de208a5e15b6b9b7e7c1ccdc5c08d8a7d8ab20c37c60e1d96a2aa1f9941",
});

Best Practices

  1. Security
    • Never expose app signer's private key on the client side
    • Store private keys in environment variables (without NEXT_PUBLIC_ prefix for Next.js)
    • Implement proper error handling
  2. Performance
    • Monitor gas costs and adjust gas limits accordingly
    • Implement retry mechanisms for failed transactions
    • Consider implementing application-level rate limiting
  3. User Experience
    • Consider implementing anti-spam measures
    • Provide clear feedback for transaction status
    • Handle network errors gracefully

API Reference

Core Functions

Indexer Functions

Types

Additional Resources