### End-to-End Circles SDK Setup Example in TypeScript Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Provides a complete example of setting up and using the Circles SDK in a browser environment. It initializes the SDK, retrieves avatar profile information, fetches trust relations, and lists top token holders. This pattern is adaptable for React, Next.js, or plain scripts. ```typescript import { Sdk } from '@aboutcircles/sdk'; import { circlesConfig } from '@aboutcircles/sdk-core'; import { createBrowserRunner } from './runner'; // use the helper from section 5 async function bootstrapCircles() { const runner = createBrowserRunner(); await runner.init(); const sdk = new Sdk(circlesConfig[100], runner); const avatar = await sdk.getAvatar(runner.address!); console.log(await avatar.profile.get()); const trustGraph = await sdk.data.getTrustRelations(avatar.address); console.log(`Trustees: ${trustGraph.length}`); const topHolders = sdk.tokens.getHolders(avatar.address, 3); await topHolders.queryNextPage(); console.log('Top holders', topHolders.currentPage?.results ?? []); } bootstrapCircles().catch(console.error); ``` -------------------------------- ### Install Circles SDK Packages with npm Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Installs the core and auxiliary packages for the Circles SDK, along with viem for RPC and wallet tooling. It's recommended to pin these versions to ensure alignment across bundlers. ```bash npm i @aboutcircles/sdk \ @aboutcircles/sdk-core \ @aboutcircles/sdk-types \ @aboutcircles/sdk-runner \ @aboutcircles/sdk-rpc \ @aboutcircles/sdk-transfers \ @aboutcircles/sdk-pathfinder \ @aboutcircles/sdk-profiles \ viem ``` -------------------------------- ### Instantiate Lower-Level SDK Packages Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Demonstrates how to instantiate core SDK modules for advanced use cases like analytics, dry-run tooling, or custom transfer flows. It shows the setup for `Core`, `CirclesRpc`, `TransferBuilder`, and `Profiles` using a shared configuration object. Requires `@aboutcircles/sdk-core`, `@aboutcircles/sdk-rpc`, `@aboutcircles/sdk-transfers`, and `@aboutcircles/sdk-profiles`. ```typescript import { Core, circlesConfig } from '@aboutcircles/sdk-core'; import { CirclesRpc } from '@aboutcircles/sdk-rpc'; import { TransferBuilder } from '@aboutcircles/sdk-transfers'; import { Profiles } from '@aboutcircles/sdk-profiles'; const config = circlesConfig[100]; const core = new Core(config); const rpc = new CirclesRpc(config.circlesRpcUrl); const transferBuilder = new TransferBuilder(core); const profilesClient = new Profiles(config.profileServiceUrl); ``` -------------------------------- ### Import Circles SDK Building Blocks in TypeScript Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Imports the primary SDK entry point, core configuration, type definitions, and optional lower-level modules. It also includes viem primitives for creating clients. ```typescript import { Sdk } from '@aboutcircles/sdk'; import { Core, circlesConfig, type CirclesConfig } from '@aboutcircles/sdk-core'; import type { ContractRunner } from '@aboutcircles/sdk-types'; import { createPublicClient, createWalletClient, custom, http } from 'viem'; import { gnosis } from 'viem/chains'; // Optional modules for lower-level access when you need them import { CirclesRpc } from '@aboutcircles/sdk-rpc'; import { TransferBuilder } from '@aboutcircles/sdk-transfers'; import { Profiles } from '@aboutcircles/sdk-profiles'; ``` -------------------------------- ### Initialize Circles SDK with TypeScript Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Initializes the Circles SDK with a specified configuration and runner. It demonstrates fetching avatar data, token balances, trust graphs, and demurraged wrappers. The runner is essential for signing and broadcasting transactions. ```typescript import { Sdk } from '@aboutcircles/sdk'; import { circlesConfig } from '@aboutcircles/sdk-core'; const runner = createBrowserRunner(); await runner.init(); const sdk = new Sdk(circlesConfig[100], runner); // config defaults to mainnet if omitted const avatar = await sdk.getAvatar(runner.address!); const balances = await avatar.balances.getTokenBalances(); const trustGraph = await sdk.data.getTrustRelations(avatar.address); const demurragedWrapper = await sdk.tokens.getDemurragedWrapper(avatar.address); const members = sdk.groups.getMembers('0xGroupAddress...'); await members.queryNextPage(); // fetch first page when you need it ``` -------------------------------- ### Build Browser Contract Runner with Viem Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Implements the ContractRunner interface for browser-based single-signers (e.g., MetaMask). It uses viem for interacting with the blockchain, handling wallet connections, chain ID enforcement, gas estimation, read-only calls, ENS resolution, and transaction sending. Requires `viem` and `@aboutcircles/sdk-types`. ```typescript import { createPublicClient, createWalletClient, custom, http } from 'viem'; import { gnosis } from 'viem/chains'; import type { Address, TransactionReceipt, TransactionRequest } from '@aboutcircles/sdk-types'; const circlesRPC = 'https://rpc.aboutcircles.com'; export const createBrowserRunner = () => { const publicClient = createPublicClient({ chain: gnosis, transport: http(circlesRPC), }); const walletClient = createWalletClient({ chain: gnosis, transport: custom(window.ethereum), }); const runner: ContractRunner = { publicClient, address: walletClient.account?.address, async init() { const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' }); this.address = account as Address; const currentChain = await walletClient.getChainId(); if (currentChain !== gnosis.id) { throw new Error('Please switch your wallet to Gnosis Chain (chainId 100).'); } }, estimateGas: (tx: TransactionRequest) => publicClient.estimateGas({ account: runner.address!, ...tx }), call: (tx: TransactionRequest) => publicClient.call({ account: tx.from || runner.address!, ...tx }), resolveName: (name: string) => publicClient.getEnsAddress({ name }), async sendTransaction(txs: TransactionRequest[]): Promise { if (!runner.address) throw new Error('Runner not initialised. Call init() first.'); let receipt: TransactionReceipt | undefined; for (const tx of txs) { const hash = await walletClient.sendTransaction({ account: runner.address, ...tx, }); receipt = await publicClient.waitForTransactionReceipt({ hash }); } if (!receipt) { throw new Error('No transactions submitted.'); } return receipt; }, }; return runner; }; ``` -------------------------------- ### Install Circles SDK Source: https://docs.aboutcircles.com/circles-sdk/circles-sdk-overview This snippet shows how to install the main Circles SDK npm package. It is a prerequisite for using the SDK's functionalities in your TypeScript or JavaScript project. ```bash npm install @aboutcircles/sdk ``` -------------------------------- ### Configure Gnosis Chain Mainnet Network Source: https://docs.aboutcircles.com/circles-sdk/getting-started-with-the-sdk Retrieves the production network configuration for Gnosis Chain Mainnet using the provided chain ID. This configuration includes service URLs and canonical contract addresses. ```typescript const gnosisMainnetConfig = circlesConfig[100]; ``` -------------------------------- ### POST /circles_query Request Example Source: https://docs.aboutcircles.com/api-reference Example POST request to the /circles_query endpoint for retrieving recent v2 avatar registrations. It specifies the 'Avatars' table and orders results by blockNumber. ```http POST /circles_query HTTP/1.1 Host: rpc.aboutcircles.com/ Content-Type: application/json Accept: */* Content-Length: 372 { "jsonrpc": "2.0", "id": 1, "method": "circles_query", "params": [ { "Namespace": "V_CrcV2", "Table": "Avatars", "Columns": [ "blockNumber", "timestamp", "transactionHash", "type", "avatar", "tokenId", "name", "cidV0Digest" ], "Filter": [], "Order": [ { "Column": "blockNumber", "SortOrder": "DESC" }, { "Column": "transactionIndex", "SortOrder": "DESC" }, { "Column": "logIndex", "SortOrder": "DESC" } ], "Limit": 25 } ] } ``` -------------------------------- ### SDK Token Information Retrieval Source: https://docs.aboutcircles.com/circles-sdk-reference/circles-sdk-interface Illustrates how to get information about token wrappers (inflationary and demurraged) and token holders using the SDK. ```typescript import { Sdk } from "@aboutcircles/sdk"; const sdk = new Sdk(); const tokenAddress = "0x..."; // Get the inflationary wrapper address const inflationaryWrapper = await sdk.tokens.getInflationaryWrapper(tokenAddress); console.log("Inflationary wrapper:", inflationaryWrapper); // Get the demurraged wrapper address const demurragedWrapper = await sdk.tokens.getDemurragedWrapper(tokenAddress); console.log("Demurraged wrapper:", demurragedWrapper); // Get token holders, paginated const holders = await sdk.tokens.getHolders(tokenAddress, 10, "ASC"); console.log("Token holders:", holders); ``` -------------------------------- ### Successful POST /circles_query Response Example Source: https://docs.aboutcircles.com/api-reference Example successful response (200 OK) from the /circles_query endpoint, indicating a tabular result set with a single 'text' column. ```json { "jsonrpc": "2.0", "id": 1, "result": { "columns": [ "text" ], "rows": [ [ "text" ] ] } } ``` -------------------------------- ### Search Profiles by Description (GET) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Finds user profiles by matching keywords in their description. Use the /profiles/search endpoint with the 'description' query parameter for this purpose. ```bash curl -X GET "https://rpc.aboutcircles.com/profiles/search?description=Circles" ``` -------------------------------- ### SDK Group Management Source: https://docs.aboutcircles.com/circles-sdk-reference/circles-sdk-interface Provides examples for retrieving group information, including members, collateral (treasury balances), and token holders. Note: Group type retrieval is currently unsupported. ```typescript import { Sdk } from "@aboutcircles/sdk"; const sdk = new Sdk(); const groupAddress = "0x..."; // Get group members const members = await sdk.groups.getMembers(groupAddress, 10, "DESC"); console.log("Group members:", members); // Get group collateral (treasury balances) const collateral = await sdk.groups.getCollateral(groupAddress); console.log("Group collateral:", collateral); // Get group token holders const groupHolders = await sdk.groups.getHolders(groupAddress, 10); console.log("Group token holders:", groupHolders); ``` -------------------------------- ### Search Profiles with Multiple Criteria (GET) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Performs a comprehensive search for profiles by combining multiple search parameters. Use the /profiles/search endpoint with various query parameters like 'name', 'description', 'address', and 'CID' simultaneously. ```bash curl -X GET "https://rpc.aboutcircles.com/profiles/search?name=John&description=blockchain&address=0x1234567890abcdef&CID=Qm12345abcdef" ``` -------------------------------- ### SQL-like Indexed Query (YAML) Source: https://docs.aboutcircles.com/api-reference Performs a SQL-like query on the indexed data within Circles. This example demonstrates how to query for recent v2 avatar registrations, specifying namespaces, tables, columns, filters, ordering, and limits. ```yaml jsonrpc: "2.0" id: 1 method: "circles_query" params: - Namespace: "V_CrcV2" Table: "Avatars" Columns: - "blockNumber" - "timestamp" - "transactionHash" - "type" - "avatar" - "tokenId" - "name" - "cidV0Digest" Filter: [] Order: - Column: "blockNumber" SortOrder: "DESC" - Column: "transactionIndex" SortOrder: "DESC" - Column: "logIndex" SortOrder: "DESC" Limit: 25 ``` -------------------------------- ### Retrieve Multiple Profiles by CIDs (GET) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Retrieves multiple user profiles simultaneously by providing a comma-separated list of CIDs to the /profiles/getBatch endpoint. This is an efficient way to fetch several profiles in a single request. ```bash curl -X GET "https://rpc.aboutcircles.com/profiles/getBatch?cids=Qm12345abcdef,Qm678bbdj" ``` -------------------------------- ### SDK Initialization and Configuration Source: https://docs.aboutcircles.com/circles-sdk-reference/circles-sdk-interface Demonstrates how to initialize the Sdk class with optional configuration and a contract runner. The default configuration uses Gnosis settings. ```typescript import { Sdk, circlesConfig } from "@aboutcircles/sdk"; // Initialize with default config (Gnosis) const sdk = new Sdk(); // Initialize with a specific config and contract runner // const runner = new SafeBrowserRunner(); // Or your custom runner // const sdk = new Sdk(circlesConfig[100], runner); ``` -------------------------------- ### Initialize Circles SDK in React Source: https://docs.aboutcircles.com/tutorials-and-examples/setting-up-circles-sdk-with-react-and-javascript This snippet shows how to set up the Circles SDK in a React application using TypeScript. It includes context and provider components for managing SDK instances, runner, and connection status. Dependencies include @aboutcircles/sdk, @aboutcircles/sdk-core, @aboutcircles/sdk-runner, and viem. ```typescript import React, { createContext, useCallback, useEffect, useState } from 'react'; import { Sdk } from '@aboutcircles/sdk'; import { circlesConfig } from '@aboutcircles/sdk-core'; import { SafeBrowserRunner } from '@aboutcircles/sdk-runner'; import { createPublicClient, http } from 'viem'; import { gnosis } from 'viem/chains'; export const CirclesSDKContext = createContext(null); export const CirclesSDKProvider = ({ children, safeAddress }) => { const [sdk, setSdk] = useState(null); const [runner, setRunner] = useState(null); const [address, setAddress] = useState(null); const [isConnected, setIsConnected] = useState(false); const initSdk = useCallback(async () => { try { if (!window.ethereum || !safeAddress) { // Read-only SDK without runner setSdk(new Sdk(circlesConfig[100])); setIsConnected(true); return; } const publicClient = createPublicClient({ chain: gnosis, transport: http(circlesConfig[100].circlesRpcUrl), }); const safeRunner = new SafeBrowserRunner(publicClient, window.ethereum, safeAddress); await safeRunner.init(); setRunner(safeRunner); setAddress(safeAddress); const sdkInstance = new Sdk(circlesConfig[100], safeRunner); setSdk(sdkInstance); setIsConnected(true); } catch (err) { console.error('Error initializing Circles SDK', err); setIsConnected(false); } }, [safeAddress]); useEffect(() => { initSdk(); }, [initSdk]); return ( {children} ); }; ``` -------------------------------- ### Search Profiles by Name (GET) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Searches for user profiles based on their name. A GET request to the /profiles/search endpoint with the 'name' query parameter will return matching profiles. ```bash curl -X GET "https://rpc.aboutcircles.com/profiles/search?name=John" ``` -------------------------------- ### Full Example: Find Groups and Avatar Memberships Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/group-avatars/find-groups-and-memberships Demonstrates a complete workflow using the AboutCircles SDK to first find groups by name and then retrieve group memberships for a specific avatar. It shows initialization, searching, and paginating through memberships. ```typescript const sdk = new Sdk({ rpcUrl: 'https://rpc.aboutcircles.com' }); const rpc = sdk.rpc; // Find groups whose names start with "Community" const groupsResult = await rpc.group.findGroups(10, { nameStartsWith: 'Community' }); console.log('Found groups:', groupsResult); // Find memberships for a specific avatar const avatarAddress = '0x123...'; const memberships = rpc.group.getGroupMemberships(avatarAddress, 10); await memberships.queryNextPage(); console.log('Group memberships:', memberships.currentPage?.results); ``` -------------------------------- ### Prepare Preview Image (TypeScript) Source: https://docs.aboutcircles.com/circles-sdk/circles-profiles A browser-friendly TypeScript function to crop and compress user-uploaded images to meet the 256x256 pixel and 150 KB file size requirements for preview images. It uses the FileReader API to read the file, an Image object to load and draw it onto a canvas, and `toDataURL` for compression and encoding. It warns if the compressed image still exceeds the file size limit. ```typescript const preparePreview = (file: File) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { const img = new Image(); img.src = reader.result as string; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const size = 256; if (!ctx) return reject(new Error('Canvas context unavailable')); canvas.width = canvas.height = size; ctx.drawImage(img, 0, 0, size, size); const dataUrl = canvas.toDataURL('image/jpeg', 0.5); if (dataUrl.length > 150 * 1024) { console.warn('Preview exceeds 150 KB after compression'); } resolve(dataUrl); }; img.onerror = reject; }; reader.onerror = reject; reader.readAsDataURL(file); }); ``` -------------------------------- ### Initialization Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Demonstrates how to initialize the CirclesData class, either by accessing it from an existing Sdk instance or by creating a new CirclesRpc instance for different networks. ```APIDOC ## Initialization ### Description Initialize the `CirclesData` class to query Circles protocol data. This can be done by accessing `sdk.data` if you have an initialized `Sdk` instance, or by creating a `CirclesRpc` instance for a specific network (e.g., Gnosis Chain or RINGS) and then instantiating `CirclesData`. ### Method Various initialization methods depending on existing SDK instance or network choice. ### Endpoint N/A (Client-side initialization) ### Parameters None directly for `CirclesData` initialization when using `sdk.data`. For manual initialization: - `circlesRpc` (CirclesRpc): An instance of `CirclesRpc` configured with the appropriate network endpoint. ### Request Example ```typescript // Using an existing Sdk instance const data = sdk.data; // Manual initialization for Gnosis Chain const circlesRpcGnosis = new CirclesRpc("https://rpc.aboutcircles.com/"); const dataGnosis = new CirclesData(circlesRpcGnosis); // Manual initialization for RINGS const circlesRpcRings = new CirclesRpc("https://static.94.138.251.148.clients.your-server.de/rpc/"); const dataRings = new CirclesData(circlesRpcRings); ``` ### Response #### Success Response - `data` (CirclesData): An initialized instance of the `CirclesData` class ready for querying. #### Response Example N/A (Client-side initialization) ``` -------------------------------- ### Retrieve a Profile by CID (GET) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Fetches a specific user profile using its Content Identifier (CID). This is a simple GET request to the /profiles/get endpoint, requiring the CID as a query parameter. ```bash curl -X GET "https://rpc.aboutcircles.com/profiles/get?cid=Qm12345abcdef" ``` -------------------------------- ### Create and Pin Profile (TypeScript) Source: https://docs.aboutcircles.com/circles-sdk/circles-profiles Shows how to create a new profile and pin it to IPFS using the `@aboutcircles/sdk`. This involves initializing the SDK with configuration and a contract runner, then calling the `create` method on the `profiles` client. The method returns the IPFS CID of the pinned profile data. ```typescript import { Sdk } from '@aboutcircles/sdk'; import { circlesConfig } from '@aboutcircles/sdk-core'; const runner = /* your ContractRunner */; await runner.init(); const sdk = new Sdk(circlesConfig[100], runner); const profile = { name: 'John Doe', description: 'Web3 Developer', previewImageUrl: 'data:image/jpeg;base64,...', }; const profileCid = await sdk.profiles.create(profile); console.log('Pinned profile CID:', profileCid); ``` -------------------------------- ### Get Total Circles Balance for Avatar Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/personal-human-avatars/get-token-balances-of-an-avatar Retrieves the total Circles balance for an avatar, summing both unwrapped and wrapped holdings. This method automatically detects the correct hub version based on avatar information and requires an initialized SDK runner. ```typescript const totalBalance = await avatar.balances.getTotal(); console.log(`Total Circles balance: ${totalBalance.toString()}`); ``` -------------------------------- ### SDK Profile Management Source: https://docs.aboutcircles.com/circles-sdk-reference/circles-sdk-interface Demonstrates creating and retrieving user profiles using IPFS via the SDK. Profile creation returns a CID, and retrieval fetches the profile data. ```typescript import { Sdk } from "@aboutcircles/sdk"; const sdk = new Sdk(); // Create a new profile const profileData = { name: "Alice", bio: "Loves circles" }; const cid = await sdk.profiles.create(profileData); console.log("Profile created with CID:", cid); // Get a profile by its CID const retrievedProfile = await sdk.profiles.get(cid); console.log("Retrieved profile:", retrievedProfile); ``` -------------------------------- ### Get Individual Token Balances for Avatar Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/personal-human-avatars/get-token-balances-of-an-avatar Fetches an array of token balances relevant to an avatar. Each entry includes the token identifier and its corresponding amount. This function relies on an initialized SDK runner and provides detailed balance information per token. ```typescript const tokenBalances = await avatar.balances.getTokenBalances(); tokenBalances.forEach((balance) => { console.log(`Token: ${balance.token}, Balance: ${balance.amount}`); }); ``` -------------------------------- ### Get Total Supply for Base Group Avatar (TypeScript) Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/group-avatars/getting-total-supply-of-group-tokens-available Retrieves the total supply of ERC-1155 tokens for a Base Group avatar. This function requires the AboutCircles SDK and specifically works with `BaseGroupAvatar` instances. It returns a BigNumber representing the total supply or logs an error for unsupported avatar types. ```typescript import { Sdk, BaseGroupAvatar } from '@aboutcircles/sdk'; const sdk = new Sdk({ rpcUrl: 'https://rpc.aboutcircles.com' }, runner); const avatar = await sdk.getAvatar('0xGroupAddress'); if (avatar instanceof BaseGroupAvatar) { const totalSupply = await avatar.balances.getTotalSupply(); console.log('Total group token supply:', totalSupply.toString()); } else { console.log('Total supply is only available for BaseGroup avatars.'); } ``` -------------------------------- ### Create a User Profile (POST) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Creates a new user profile by sending a POST request to the /profiles/pin endpoint. Requires a JSON payload with profile details like name, description, and image URLs. Extensions for social media links are optional. ```bash curl -X POST "https://rpc.aboutcircles.com/profiles/pin" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "description": "A blockchain developer", "previewImageUrl": "https://example.com/preview.jpg", "imageUrl": "https://example.com/image.jpg", "extensions": { "twitter": "@johndoe", "github": "johndoe" } }' ``` -------------------------------- ### Profile Data Model Examples (TypeScript) Source: https://docs.aboutcircles.com/circles-sdk/circles-profiles Demonstrates the structure of `Profile` and `GroupProfile` interfaces from the `@aboutcircles/sdk-types` package. These interfaces define the expected fields for human-readable avatar profiles and group profiles, respectively. `GroupProfile` extends `Profile` by adding a required `symbol` field. ```typescript import type { Profile, GroupProfile } from '@aboutcircles/sdk-types'; const humanProfile: Profile = { name: 'John Doe', description: 'Web3 Developer', imageUrl: 'https://example.com/image.jpg', previewImageUrl: 'data:image/jpeg;base64,...', location: 'Berlin, Germany', geoLocation: [52.52, 13.4050], extensions: { twitter: '@john' }, }; const groupProfile: GroupProfile = { name: 'My Community Group', symbol: 'MCG',//REQUIRED description: 'A community group for local initiatives', imageUrl: 'https://example.com/group-image.jpg', }; ``` -------------------------------- ### Get Profile by CID Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Retrieves a single user profile using its Content Identifier (CID). ```APIDOC ## GET /profiles/get ### Description Retrieves a user profile by its unique Content Identifier (CID). ### Method GET ### Endpoint /profiles/get ### Parameters #### Query Parameters - **cid** (string) - Required - The Content Identifier of the profile to retrieve. ### Response #### Success Response (200) - **profile** (object) - The user profile data. - **name** (string) - The name of the user. - **description** (string) - A brief description of the user. - **previewImageUrl** (string) - URL for a preview image. - **imageUrl** (string) - URL for the main image. - **extensions** (object) - Additional key-value pairs for extensions. #### Response Example ```json { "profile": { "name": "John Doe", "description": "A blockchain developer", "previewImageUrl": "https://example.com/preview.jpg", "imageUrl": "https://example.com/image.jpg", "extensions": { "twitter": "@johndoe", "github": "johndoe" } } } ``` ``` -------------------------------- ### Get Avatar Profile Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/personal-human-avatars/handle-profile-of-an-avatar Fetches the current profile associated with the avatar. Returns undefined if no profile exists. ```APIDOC ## GET /avatar/profile ### Description Fetches the current profile associated with the avatar. If no profile exists, it will return `undefined`. ### Method GET ### Endpoint /avatar/profile ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const profile = await inviteeAvatar.profile.get(); if (profile) { console.log(profile.name, profile.description); } ``` ### Response #### Success Response (200) - **profile** (object) - The profile object containing name, description, and avatarUrl. #### Response Example ```json { "name": "Avatar Name", "description": "Description of the avatar.", "avatarUrl": "ipfs://QmYourImageCIDHere" } ``` ``` -------------------------------- ### Get Multiple Profiles by CIDs Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Retrieves multiple user profiles by providing a comma-separated list of their Content Identifiers (CIDs). ```APIDOC ## GET /profiles/getBatch ### Description Retrieves multiple user profiles by providing a comma-separated list of their Content Identifiers (CIDs). ### Method GET ### Endpoint /profiles/getBatch ### Parameters #### Query Parameters - **cids** (string) - Required - A comma-separated string of Content Identifiers (CIDs) for the profiles to retrieve. ### Response #### Success Response (200) - **profiles** (array) - An array of user profile objects. - Each object contains: - **name** (string) - The name of the user. - **description** (string) - A brief description of the user. - **previewImageUrl** (string) - URL for a preview image. - **imageUrl** (string) - URL for the main image. - **extensions** (object) - Additional key-value pairs for extensions. #### Response Example ```json { "profiles": [ { "name": "John Doe", "description": "A blockchain developer", "previewImageUrl": "https://example.com/preview.jpg", "imageUrl": "https://example.com/image.jpg", "extensions": { "twitter": "@johndoe", "github": "johndoe" } }, { "name": "Jane Smith", "description": "A designer", "previewImageUrl": "https://example.com/jane_preview.jpg", "imageUrl": "https://example.com/jane.jpg", "extensions": {} } ] } ``` ``` -------------------------------- ### Get Inviter of an Avatar (TypeScript) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Queries who invited a specific avatar. Returns the inviter's avatar address or undefined if the avatar was not invited. ```typescript const invitedBy = await data.getInvitedBy("0x..."); ``` -------------------------------- ### Create Base Group with SDK Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/group-avatars/create-base-groups-for-your-community This snippet demonstrates how to create a new Base Group using the `sdk.register.asGroup` function. It involves setting up the SDK with RPC details and a contract runner, then providing owner, service, fee collection addresses, initial membership conditions, and group metadata. The function returns a `BaseGroupAvatar` instance. ```typescript import { Sdk } from '@aboutcircles/sdk'; const sdk = new Sdk( { rpcUrl: 'https://rpc.aboutcircles.com' }, runner // ContractRunner tied to your wallet ); const groupAvatar = await sdk.register.asGroup( '0xOwner', '0xService', '0xFeeCollection', ['0xCondition1', '0xCondition2'], // initial membership conditions 'My Base Group', 'MBG', { name: 'My Base Group', symbol: 'MBG', description: 'A base group for coordination', imageUrl: '', // optional previewImageUrl: '', // optional } ); console.log('Base group created at:', groupAvatar.address); ``` -------------------------------- ### Get Token Info Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Retrieves basic information about a Circles token, including its creation timestamp, Circles version, type, and the avatar that created it. ```APIDOC ## Get Token Info ### Description Fetches essential details for a specific Circles token. This includes when the token was created, the Circles protocol version it belongs to, whether it's a human or group token, and the address of the avatar that initially created the token. ### Method `GET` (Conceptual - this is a method call on the client-side SDK) ### Endpoint N/A (Client-side SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Method Parameters - **tokenId** (string) - Required - The unique identifier of the Circles token to query. ### Request Example ```typescript const tokenInfo = await data.getTokenInfo("0x..."); if (tokenInfo) { console.log("Token is a Circles token"); } else { console.log("Token is not a Circles token"); } ``` ### Response #### Success Response (200) - `TokenInfoRow | undefined`: An object containing token details if the token is found, otherwise `undefined`. - `creationTimestamp` (number): The timestamp when the token was created. - `circlesVersion` (number): The version of the Circles protocol the token uses. - `tokenType` (string): The type of the token ('human' or 'group'). - `creatorAvatarAddress` (string): The address of the avatar that created this token. #### Response Example ```json { "creationTimestamp": 1678886400, "circlesVersion": 2, "tokenType": "human", "creatorAvatarAddress": "0x..." } ``` ``` -------------------------------- ### Reading Profiles Source: https://docs.aboutcircles.com/circles-sdk/circles-profiles Explains the different methods available for retrieving profile data, including fetching metadata via avatars, using RPC calls, and accessing profiles through the SDK client. ```APIDOC ## Reading Profiles Back ### Description This section outlines the various methods to retrieve profile data, ranging from direct avatar interactions to RPC calls and batch processing via the SDK. ### Methods * **Via Avatars**: Use `await avatar.profile.get()` to pull and cache the current metadata. The `avatar.profile.update` method handles write operations. * **Via RPC**: The `CirclesRpc.avatar.getAvatarInfo` method includes the `cidV0`, allowing you to fetch profile blobs without needing to instantiate an avatar class. * **Via the Profiles Client**: The `await sdk.profiles.get(cid)` method is suitable for batch jobs or server-side verification purposes. **Note**: Since the CID is stored on-chain, any tool with the avatar address can look up its metadata by combining RPC data with the profile service. ``` -------------------------------- ### Get Avatar by Address Source: https://docs.aboutcircles.com/circles-sdk-reference/sdk-methods Retrieves an avatar instance using its unique address. This method is crucial for fetching existing avatar data and interacting with them. ```typescript sdk.getAvatar(avatarAddress: string): Promise; // Example: const avatar = await sdk.getAvatar('0x123...abc'); ``` -------------------------------- ### Get Transaction History Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Retrieves a paginated list of all incoming and outgoing Circles transfers for an avatar, including minting and transfers across different versions. ```APIDOC ## Get Transaction History ### Description Queries and retrieves a history of all Circles transfers associated with a given avatar, encompassing both incoming and outgoing transactions. This includes minting events and transfers of personal and group tokens for both Circles v1 and v2. The results are paginated and ordered by timestamp in descending order. ### Method `GET` (Conceptual - this is a method call on the client-side SDK) ### Endpoint N/A (Client-side SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Method Parameters - **avatar** (string) - Required - The address of the avatar for which to retrieve transaction history. - **pageSize** (number) - Required - The number of transaction records to retrieve per page. ### Request Example ```typescript const query = data.getTransactionHistory("0x...", 25); const hasResults = await query.queryNextPage(); if (!hasResults) { console.log("No transactions yet"); return; } const rows = query.currentPage.results; rows.forEach(row => console.log(row)); ``` ### Response #### Success Response (200) - `CirclesQuery`: A query object that allows fetching paginated results. The `currentPage.results` property contains an array of transaction history rows. - `timestamp` (number): The Unix timestamp when the transaction occurred. - `transactionHash` (string): The hash of the transaction. - `version` (number): The Circles protocol version (1 or 2) for the transaction. - `operator` (string | undefined): The address of the operator that facilitated the transaction (v2 only). - `from` (string): The sender's avatar address. - `to` (string): The receiver's avatar address. - `id` (string): In v1: the token address. In v2: the token ID. - `value` (string): The raw transferred value as a bigint string. - `timeCircles` (number): A floating-point number representation of the `value`, suitable for display. - `tokenAddress` (string | undefined): In v2: the address representation of the numeric `tokenId`. In v1: the actual ERC20 token address for a personal token. #### Response Example ```json { "timestamp": 1678886400, "transactionHash": "0x...", "version": 2, "operator": "0x...", "from": "0x...", "to": "0x...", "id": "0x...", "value": "1000000000000000000", "timeCircles": 1.0, "tokenAddress": "0x..." } ``` ``` -------------------------------- ### SDK Core Functionalities Source: https://docs.aboutcircles.com/circles-sdk-reference/circles-sdk-interface Illustrates accessing core SDK modules for low-level contract interactions, RPC client, IPFS profiles, and read-only data helpers. ```typescript import { Sdk } from "@aboutcircles/sdk"; const sdk = new Sdk(); // Access low-level contract wrappers const coreContracts = sdk.core; // Use the RPC client const rpcClient = sdk.rpc; // Interact with IPFS profiles const profilesClient = sdk.profilesClient; // Access read-only data helpers const circlesData = sdk.data; // Get avatar information const avatarInfo = await sdk.data.getAvatar("0x..."); ``` -------------------------------- ### Create Profile Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-circles-profiles Creates a new user profile with provided details. ```APIDOC ## POST /profiles/pin ### Description Creates a new user profile with provided details including name, description, image URLs, and extensions. ### Method POST ### Endpoint /profiles/pin ### Parameters #### Request Body - **name** (string) - Required - The name of the user. - **description** (string) - Optional - A brief description of the user. - **previewImageUrl** (string) - Optional - URL for a preview image. - **imageUrl** (string) - Optional - URL for the main image. - **extensions** (object) - Optional - Additional key-value pairs for extensions (e.g., social media links). - **twitter** (string) - Optional - Twitter handle. - **github** (string) - Optional - GitHub username. ### Request Example ```json { "name": "John Doe", "description": "A blockchain developer", "previewImageUrl": "https://example.com/preview.jpg", "imageUrl": "https://example.com/image.jpg", "extensions": { "twitter": "@johndoe", "github": "johndoe" } } ``` ### Response #### Success Response (200) - **cid** (string) - The Content Identifier of the newly created profile. #### Response Example ```json { "cid": "QmNewProfileCID" } ``` ``` -------------------------------- ### Initialize RPC Access with AboutCircles SDK Source: https://docs.aboutcircles.com/circles-sdk/circles-avatars/group-avatars/find-groups-and-memberships Initializes the AboutCircles SDK and accesses the RPC client for group-related operations. It requires the SDK and CirclesRpc imports and a valid RPC URL. ```typescript import { Sdk } from '@aboutcircles/sdk'; import { CirclesRpc } from '@aboutcircles/sdk-rpc'; // Preferred: reuse the RPC client from an SDK instance const sdk = new Sdk({ rpcUrl: 'https://rpc.aboutcircles.com' }); const rpc = sdk.rpc; ``` -------------------------------- ### Get Group Memberships (TypeScript) Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Queries all groups an avatar is a member of. The results include group details, the avatar's role, and membership expiry time. ```typescript const query = data.getGroupMemberships("0x...", 25); const hasResults = await query.queryNextPage(); if (!hasResults) { console.log("No trust events yet"); return; } const rows = query.currentPage.results; rows.forEach(row => console.log(row)); ``` -------------------------------- ### Get Avatar Info Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/query-data Retrieves basic information about a given avatar address, including signup timestamp, Circles version, avatar type, and profile CID. ```APIDOC ## Get Avatar Info ### Description Fetches fundamental details for a specified avatar address. This includes when the avatar was signed up, the version of Circles protocol it uses, whether it represents a human, organization, or group, and its associated profile CID if available. ### Method `GET` (Conceptual - this is a method call on the client-side SDK) ### Endpoint N/A (Client-side SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Method Parameters - **avatar** (string) - Required - The address of the avatar to query. ### Request Example ```typescript const avatarInfo = await data.getAvatarInfo("0x..."); if (avatarInfo) { console.log("Avatar is signed up at Circles"); } else { console.log("Avatar is not signed up at Circles"); } ``` ### Response #### Success Response (200) - `AvatarRow | undefined`: An object containing avatar details if the avatar is found, otherwise `undefined`. - `signupTimestamp` (number): The timestamp when the avatar signed up. - `circlesVersion` (number): The version of the Circles protocol used. - `avatarType` (string): Type of the avatar ('human', 'organization', 'group'). - `tokenAddress` (string): The address of the token associated with the avatar. - `tokenId` (string): The ID of the token associated with the avatar. - `profileCID` (string | undefined): The Content Identifier for the avatar's profile, if set. #### Response Example ```json { "signupTimestamp": 1678886400, "circlesVersion": 2, "avatarType": "human", "tokenAddress": "0x...", "tokenId": "0x...", "profileCID": "Qm..." } ``` ``` -------------------------------- ### Get Demurraged ERC20 Wrapper Address Source: https://docs.aboutcircles.com/circles-sdk-reference/sdk-methods Retrieves the demurraged ERC20 wrapper address for an avatar's token. Returns the zero address if the wrapper is undeployed. ```typescript sdk.tokens.getDemurragedWrapper(address: string): Promise; // Example: const demWrapper = await sdk.tokens.getDemurragedWrapper('0xAvatar...'); ``` -------------------------------- ### Preview Image Requirements Source: https://docs.aboutcircles.com/circles-sdk/circles-profiles Details the constraints for `previewImageUrl` in Circles profiles, ensuring lightweight responses. Includes format, dimensions, file size, and encoding requirements. ```APIDOC ## Preview Image Requirements ### Description When embedding an image as `previewImageUrl`, the profile service enforces constraints to maintain lightweight responses. These include specific format, dimensions, file size, and encoding requirements. ### Requirements * **Format**: PNG, JPEG, or GIF. * **Dimensions**: Exactly 256x256 pixels. * **File size**: Less than or equal to 150 KB after compression. * **Encoding**: Base64-encoded data URL (e.g., `data:image/png;base64,...`). ### Client-Side Helper (TypeScript Example) This browser-friendly helper function crops and compresses user uploads before pinning to meet the requirements. ```ts const preparePreview = (file: File) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { const img = new Image(); img.src = reader.result as string; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const size = 256; if (!ctx) return reject(new Error('Canvas context unavailable')); canvas.width = canvas.height = size; ctx.drawImage(img, 0, 0, size, size); const dataUrl = canvas.toDataURL('image/jpeg', 0.5); if (dataUrl.length > 150 * 1024) { console.warn('Preview exceeds 150 KB after compression'); } resolve(dataUrl); }; img.onerror = reject; }; reader.onerror = reject; reader.readAsDataURL(file); }); ``` **Note**: Profiles violating these constraints will be rejected by the pinning service. It is recommended to validate on the client and provide user-friendly error messages. ``` -------------------------------- ### Initialize and Execute a Circles Query - TypeScript Source: https://docs.aboutcircles.com/querying-circles-profiles-and-data/utilising-circlesquery-class Demonstrates how to initialize a `CirclesRpc` instance with a given RPC URL and then create a `CirclesQuery` instance using the RPC client and a query definition. It shows how to execute the query using `queryNextPage()` and access the results from the `currentPage` property. ```typescript const circlesRpc = new CirclesRpc('https://chiado-rpc.aboutcircles.com'); const query = new CirclesQuery(circlesRpc, queryDefinition); const hasResults = await query.queryNextPage(); if (!hasResults) { console.log("The query yielded no results."); } else { const rows = query.currentPage.results; rows.forEach(row => console.log(row)); } ```