Only this pageAll pages
Powered by GitBook
1 of 48

Circles Docs

Loading...

Overview

Loading...

Loading...

Loading...

Loading...

Loading...

Developer Docs

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Tutorials and Examples

Loading...

Querying Circles profiles and data

Loading...

Loading...

Loading...

Loading...

Loading...

Circles SDK Reference

Loading...

Loading...

Loading...

Loading...

Developer Support

Loading...

Loading...

Loading...

User Guides

Loading...

Understanding Personal and Group Currencies

In Circles, money is generated collectively by many individuals over time rather than by a central authority at specific events.

When you become part of the Circles network, every person has their own personal Circles token and receives one Circle (CRC) per hour, unconditionally.

The trust network forms a social graph where each trust relationship acts as a link, allowing tokens to flow between individuals through these connections. This ensures that the value of Circles is supported by genuine social relationships, fostering a community-driven economy.

At the same time, this mechanism is an effective soft sybil protection, as it decentralises the verification process and relies on human judgment for trust, preventing fake accounts from compromising the network. Since the connections between Circles accounts have a limited capacity (defined by their balances of fungible tokens), this limits the impact of fake accounts that manage to get trusted by a credible member of the network to their direct surroundings.

Personal Currencies and Trust Path

Personal currencies are unique and require trust to be transferred to others. To send tokens, other users must first trust your personal currency. When someone trusts your tokens, they become fungible with their own tokens.

This fungibility allows for the transfer of tokens along a trust path, enabling transactions even between people who do not directly trust each other.

Group Currencies

Additionally, Circles v2 introduces support for group currencies, allowing communities to share a currency backed by their members' personal tokens.

This collective currency reduces risk, simplifies payments, and enhances market creation by aggregating individual tokens into a more stable and fungible group currency. Group currencies make it easier to integrate Circles into existing economic structures and protocols, further promoting a robust and interconnected community economy.

Why Build on Circles?

Circles is a decentralized protocol with a social and economic value for humans, communities and groups. Circles is not a crypto startup or product in general, but a collective effort to bring a fair distribution model for the money created, owned and shared by people.

Explore our developer documentation, and join us in our mission to create a fair and sustainable economy for all.

Each user generates tokens continuously at a rate of one Circle (CRC) per hour, ensuring equal opportunity regardless of when they join. This promotes fairness as everyone has a chance to accumulate Circles.

Circles operates on a trust-based model, forming a social graph where users trust each other's CRC tokens. Trusted tokens become fungible, creating a dynamic economy backed by genuine social connections.

Circles integrates a demurrage mechanism, applying a 7% annual fee on held tokens. This keeps the currency circulating, benefiting the overall economy and promoting continuous engagement within the community. For most human users, the fee is offset by the steady income of 1 CRC per hour. Organizations always have to pay the fee.

By decentralising the verification process and leveraging human judgment for trust, Circles addresses the issue of fake accounts. This fosters a secure and resilient ecosystem, where the authenticity of each user is ensured by their social connections rather than centralised authorities or algorithms.

Circles v2 allows for the creation of group currencies, enabling communities to share a currency that's backed by their members' personal tokens. This reduces risk, simplifies payments, and enhances market creation by aggregating individual tokens into a more stable group currency that's easy to integrate into existing protocols.

By joining the Circles developer community, you can play a crucial role in building a more equitable and inclusive financial system. You can build applications, support developers, and invite more people to join your trust network.

Mint personal tokens

Get mintable amount for an avatar

This function will allow you to get maximum amount of CRC tokens that are available to mint at that point of time. Human avatars can mint only upto 24 personal Circles per day.

const mintableToken = await avatar.getMintableamount();

Mint personal tokens :

This function will allow you to mint your personal CRC tokens

const mintTransaction = await avatar.personalMint();
console.log('Transaction successful, receipt:', mintTransaction);

Inviting and accepting human avatars

1. Creation of Personal/Human Avatars :

Circles v2.0 will allow you to join the network as a human with a token ERC 1155 standard. You would have a profile and would require to be invited to join the network and start minting personal CRC tokens.

The V2 Hub contract is the main smart contract that a user would interact with. When you initialize an Avatar, it determines the appropriate implementation based on the avatar's version and type.

  • Inviting a human to Circles (V2 only):

await avatar.inviteHuman(newUserAddress);
  • Now, once your invited person has created it's profile, we will pass this along with inviter address

const avatar = await sdk.acceptInvitation(inviterAddress, profile);
console.log(avatar.avatarInfo);

Get an existing avatar

If you have the address of an existing avatar, you can get an instance by calling sdk.getAvatar(address). It returns either an AvatarInterface instance or throws an error if the avatar can't be found.

const avatar = await sdk.getAvatar(avatarAddress);
console.log(avatar.avatarInfo);

Group Currencies

In addition to individual CRC currencies, Circles has introduced the concept of Group Avatars and Currencies. The idea behind Group currencies is to social-economic value amongst groups, without the geographical bounds of where groups are generated or created. Group avatar tokens can't be minted based on time, rather depends on personal collateral.

If you want to become a part of group, you would require to be invited to the group itself by the group admin. Invitation to groups would be that you are simply trusting a human avatar. Now, in order to mint the group tokens, as a group member (human avatar in the group) you would require to trust the group address so that you can start accepting the tokens. When you are trusting a human, you are also trusting their personal tokens. You can currently mint group tokens based on the quantity of total personal tokens (CRC).

The current mint policy allows you to mint group tokens based on your total personal CRC tokens quantity that you hold as a human. In other words, your personal tokens would be swapped for your group tokens.

Organization Avatars

In the Circles SDK, an Organization Avatar represents a non-human entity within the ecosystem. Unlike human or group avatars, it has distinct capabilities:

  • Cannot mint tokens

  • Can participate in the trust network

  • Supports profiles for organization (in V2)

  • Compatible with both V1 and V2 of the Circles protocol

Unlike group avatars, organizations don't have membership conditions. Organizations are designed to represent entities that participate in the Circles economy without issuing their own currency.

Building with different Circles Avatars

An avatar represents a Circles user.

The SDK is built around the concept of avatars. An avatar is a Circles user and is used to interact with other Avatars.

  • New Circles users must sign up.

  • For existing Circles users, you can simply get exisiting avatars by address.

Creating a new avatar

You will need a Metamask account with some xDAI to be able to interact with contracts and follow along the steps. Make sure you configured MetaMask with the correct ChainID (Gnosis Chain or Chiado) before you continue.

Transfer personal Circles tokens to different avatar

Get Maximum amount of transferrable token

Utilizes the pathfinder to find the maximum Circles amount that can be transferred from this Avatar to the specified avatar. The address of the avatar passed would be the one to which the Circles will be transferred.

Transfer CRC tokens

This function will allow you to transfer CRC tokens to the avatars with a valid trust path. The maximum transferable amount can be lower than the avatar's balance depending on its trust relations and token holdings.

Direct token transfer (specific token):

Past Hackathon Projects on Circles

Here are some of the past hackathon projects built with Circles. You can use these as a reference or to get inspiration of what kind of applications to build.

1. EthGlobal Brussels 2024

BraceBuddy allows to onboard easily and in a fun way people to the Circles ecosystem with NFC!

Woleth is an easy to use EVM wallet embed into Telegram designed to build a Social Graph utilizing Circle's invite mechanism.

Famjam is a dapp that uses Circles to create a family currency to incentivize kids for good behaviour.

2. EthGlobal Singapore 2024

Voting with UBI is a dapp which implements a voting mechanism for DAOs by utilizing Circles group tokens.

Personal / Human Avatars

ERC-1155 standard avatars, which allows you to mint your personal Circles token (CRC) every hour, accumulating 24 CRC per day with an applied demurrage of 7%.

Group Avatars

Created by an owner, these avatars allow groups to trust human avatars within the group. Group tokens are utilized by collateralizing personal tokens, following the ERC-1155 standard.

Organization Avatars

As an organization, you are an avatar without any minting of new tokens. With your name and metadata file, which will be used for identification and can trust other avatars to receive Circles, with all owned Circles earned by avatars rather than minted.

const maxTransferable = await avatar.getMaxTransferableAmount(toAvatarAddress)
console.log(`Maximum transferable amount: ${maxTransferable}`);
const transferReceipt = await avatar.transfer(recipientAddress, amountToTransfer);
console.log(`Transfer successful! Transaction receipt: ${transferReceipt}`);
// Transfer specific token
await avatar.transfer(recipientAddress, amount, specificTokenAddress);

Manage trust connections

Trust an avatar

This function allows an avatar to trust another avatar or multiple avatars. Trusting an avatar means you are willing to accept Circles that have been issued by them. Once trusted, Circles transfers from the trusted avatar are allowed.

const trustReceipt = await avatar.trust("AvatarAddress");
console.log(receipt);

Untrust an avatar

This function revokes trust from another avatar or multiple avatars. Once trust is revoked, the avatar will no longer accept Circles issued by the untrusted avatar. However, this will not impact Circles that were already received from the untrusted avatar.

const untrustReceipt = await avatar.untrust("AvatarAddress");
console.log(receipt);

Check if avatar trusts another Avatar

This function checks if the current avatar is trusted by another avatar. It can be used to verify whether another avatar is willing to accept Circles issued by the current avatar.

const isTrusted = await avatar.isTrustedBy("AvatarAddress");
console.log(isTrusted); // true or false

This function retrieves all trust relationships of the current avatar. It returns an array of trust relations indicating which avatars are trusted, which avatars trust the current avatar, and which relationships are mutual.

const trustRelations = await avatar.getTrustRelations();
trustRelations.forEach
    (relation => { 
        console.log(${relation.avatar1} ${relation.relation} ${relation.avatar2}); });

Fetching profile of an human avatar

This section is dedicated to handling the profiles of an avatar

Get a profile for the avatar

This function fetches the current profile associated with the avatar. If no profile exists, it will return undefined.

  const profile = await avatar.getProfile();
  console.log("Avatar Profile:", profile);

Update metadata of the profile

This function updates the avatar's metadata by uploading a new content identifier (CID) to IPFS. The CID represents the new metadata for the avatar.

// IPFS CID for the new metadata
const cid = "QmYourIPFSCIDHere";

try {
  const receipt = await avatar.updateMetadata(cid);
  console.log("Metadata updated successfully:", receipt);
} catch (error) {
  console.error("Error updating metadata:", error);
}

Update profile of the avatar

This function updates the avatar’s profile and returns the IPFS CID of the newly updated profile.

const newProfile: Profile = {
  name: "Avatar Name",
  description: "Updated description for the avatar.",
  image: "ipfs://QmYourImageCIDHere", // Example IPFS image CID
};

try {
  const newCid = await avatar.updateProfile(newProfile);
  console.log("Profile updated successfully. New CID:", newCid);
} catch (error) {
  console.error("Error updating profile:", error);
}

Creating profile without an Avatar instance

const newProfile: Profile = {  
  name: "Avatar Name",  
  description: "Updated description for the avatar.",  
  imageUrl: "ipfs://QmYourImageCIDHere", // Note: changed from image to imageUrl  
};  
  
try {  
  const receipt = await sdk.createOrUpdateProfile(newProfile);  
  console.log("Profile created/updated successfully");  
} catch (error) {  
  console.error("Failed to create/update profile:", error);  
}

Getting total supply of group tokens available

This method retrieves the total amount of Circles associated with the avatar, which can be either Personal Circles or Group Circles, depending on the calling context.

getTotalSupply: () => Promise<bigint>;

// Example of calling the getTotalSupply method
try {
    const totalSupply = await circles.getTotalSupply();
    console.log('Total Circles Supply:', totalSupply.toString());
} catch (error) {
    console.error('Error fetching total supply:', error);
}

Mint group tokens

This method allows a group to mint new Group Circles using trusted collateral tokens. The group specifies which collateral to use and the corresponding amounts.

const groupAddress = '0xYourGroupAddress'; // The address of the group  
const collateralTokens = ['0xToken1', '0xToken2']; // Addresses of the collateral tokens  
const collateralAmounts = [BigInt(1000), BigInt(2000)]; // Corresponding amounts for each token  
const data = new Uint8Array(); // Empty data array or specific data if needed  
  
try {  
    const receipt = await avatar.groupMint(groupAddress, collateralTokens, collateralAmounts, data);  
    console.log('Minting successful:', receipt);  
} catch (error) {  
    console.error('Minting failed:', error);  
}

Managing group invites

To invite group members, you need to trust them. Trusting them would simply mean that you are inviting them to join group and would be accepting their personal token as collateral. Now, once invited, a group member will require to trust the group avatar address so that they can mint the group tokens.

Invitation to the group

const trustReceipt = await groupAvatar.trust("AvatarAddress");
console.log(receipt);

Revoke group member from the group

const trustReceipt = await groupAvatar.untrust("AvatarAddress");
console.log(receipt);

Group Avatars

Group avatars are a type of avatar in the Circles ecosystem that represent collective entities rather than individual users.

Group Structure

Each group in Circles has:

  • A unique blockchain address (similar to individual avatars)

  • A specific type identifier

  • An owner who has administrative control

  • A treasury where tokens are stored

  • A mint policy that governs token creation

  • A name and symbol for its tokens

  • A membership system

  • Groups also maintain a count of their members and can store metadata via IPFS CIDs (Content Identifiers).

Groups support following CRC token operations:

  • Minting: Groups can mint their own tokens using collateral from members

  • Redemption: Members can redeem group tokens for the underlying collateral

Understanding purpose of Groups

Groups within the Circles ecosystem serve several important purposes:

  1. Enabling Collective Economic Action: Groups allow multiple individuals to create shared economic entities with their own currencies, extending Circles beyond personal tokens.

  2. Creating Community Currencies: Groups can mint their own tokens backed by collateral, allowing communities to create currencies tailored to their specific needs.

  3. Pooling Resources: The group treasury system allows pooling of resources from members.

  4. Collective Governance: Groups implement membership systems that can include conditions and expiry times.

Personal Currencies

Circles is all about creating a fairer money system. Our current monetary system and most cryptocurrencies tend to benefit those with established wealth and market positions, making it challenging for newcomers to catch up. Wealth grows disproportionately for those already in the market, as time in the market often beats time to market.

Circles aims to solve this by ensuring equal opportunity for all. Each user continuously generates tokens at a rate of one Circle (CRC) per hour, regardless of when they join. Additionally, existing Circles incur a demurrage fee of 7% per year. By tying the issuance of tokens to time, a resource everyone has, Circles promotes fairness by giving everyone a chance to accumulate tokens and encouraging the active circulation of currency.

Issuance

Circles employs a unique token issuance mechanism where each user generates their own currency (CRC) at a steady rate of one token per hour. The minting rules are encoded in the so-called Hub, a token factory from which all individual Circles tokens are created.

All tokens existing in the system are ultimately rooted in personal tokens (Circles v1 only includes personal tokens, while v2 adds group currencies which are collateralized by personal tokens).

Demurrage

All tokens are automatically demurred at a rate of 7% per year.

For human users, the demurrage is offset by the steady income of new CRC. Only after minting for 80 years (roughly a human lifespan) or through economic activity can a person become negatively affected by demurrage. Once the person dies, no new tokens are minted and all of the person's tokens are subjected to demurrage.

Organizations cannot mint tokens. Therefore, their balance is always subject to a demurrage of 7% per year.

The following graph visualizes the balance of an account over time, assuming no economic activity and continuous minting of all CRC.

If understood as a tax, then the tax would be negative at first (you get money), but once your balance reaches the threshold of 125.000 Circles, it turns positive (you loose money).

Implementation

Circles v1 tokens adhere to the ERC20 token standard with added functionality for personal minting and a built-in allowance like mechanism for the Hub contract which is necessary to enable the path transfer functionality.

Circles v2 is built on the ERC1155 token standard. Here, the Hub uses a standard allowance to facilitate path transfers. The token metadata mimics as profile.

Dead man's switch

Circles v1 tokens have a built-in "dead man's switch" that permanently disables the minting of new tokens after 90 days of inactivity. This proved problematic, so in Circles v2, the mechanism was replaced by a limit that allows a maximum minting amount of 14 days' worth of Circles.

In both versions, minting can be stopped manually. This feature is used, for example, to ensure that users who migrate from v1 to v2 cannot mint in v1 before they are allowed to mint in v2.

Get token balances of an avatar

Get total balance of an avatar

This function fetches the total Circles balance of the avatar. It checks the balance from either the v1 or v2 versions of Circles, depending on which version the avatar is using.

To determine the version, you can refer to the avatarInfo property.

Get balances for an avatar

This function retrieves the avatar's token balances. Before calling this function, ensure that the system is initialized. It returns a promise that resolves to an array of TokenBalanceRow objects, each representing the balances for different tokens associated with the avatar in the current context.

Contributing Guide

Thanks for your interest in contributing! Follow these quick steps to open a pull request. We would encourage both technical and non-technical contributions. Technical contributions may include improvisations and addition of new details for the Circles SDK while non-technical contributions can be creating detailed user oriented guides on various Circles features. All non-technical guides should be created under the User Guides folder.

Prerequisites

- Node.js (v18+ recommended)

- Git + GitHub account

- Markdown editor or IDE (e.g., VS Code)

Steps to Contribute

1. Fork & Clone

Fork the repo -

2. Create a New Branch

3. Install Dependencies & Start Dev Server

Preview: http://localhost:3000

4. Make Your Changes

  • Edit or create .md files inside the docs/ folder.

  • Follow the tone and structure of existing content.

5. Commit & Push

6. Open a Pull Request

  • Visit your fork on GitHub.

  • Click “Compare & pull request”.

  • Base repo: aboutcircles/circles-docs, branch: main.

After that, your contribution will be reviewed shortly. Thank you for helping improve Circles documentation!

const totalBalance = await avatar.getTotalBalance();
console.log(`Total Circles balance: ${totalBalance}`);
const tokenBalances = await avatar.getBalances();
tokenBalances.forEach((balance) => {
  console.log(`Token: ${balance.token}, Balance: ${balance.amount}`);
});
git clone https://github.com/your-username/circles-docs.git
cd circles-docs
git remote add upstream https://github.com/aboutcircles/circles-docs.git
git checkout -b your-contribution-topic
npm install
npm run dev
git add .
git commit -m "docs: your concise message"
git push origin your-contribution-topic
https://github.com/aboutcircles/circles-docs

Setting Circles Profiles

Circles is built around the ERC-1155 token standard, which allows tokens to include metadata. Since Circles is all about personal currency, it makes sense to use this metadata to define a profile.

The profile data is stored on IPFS, and the Circles avatar references the CIDv0 of the profile on-chain. Using the profile interface from the Circles SDK, you can create user profiles for all avatars.

Required Field:

  • name: A string representing the user's name

Optional Fields:

  • description: A string for additional user information

  • previewImageUrl: A string URL for a preview/thumbnail image

  • imageUrl: A string URL for a full-size profile image

  • location: A string representing the user's location (e.g., "Berlin, Germany")

  • geoLocation: A tuple of two numbers representing coordinates [latitude, longitude]

  • extensions: A flexible Record type for storing additional custom data

Example for creating user profile:

  1. Let's create a test profile object.

const profile = {  
  name: 'John Doe',  
  description: 'Web3 Developer',  
  imageUrl: 'https://example.com/image.jpg',  
  previewImageUrl: 'https://example.com/preview.jpg',  
  location: 'Berlin, Germany',  
  geoLocation: [52.5200, 13.4050]  
};  
  1. You should already have circles SDK initialized to create profile.

//Accessing profiles through the SDK  
const profileCID = await sdk.profiles.create(profile);

Creating profile for your groups

The Group profile is used for groups created using Circles, each of which has its own token symbol. The GroupProfile inherits all fields from the base Profile—such as name, description, images, location, etc.—and adds a required symbol field representing the group's token symbol.

import { Sdk } from '@circles-sdk/sdk';  
import { GroupProfile } from '@circles-sdk/profiles';  
  
// Initialize the SDK - if not already
const sdk = new Sdk(contractRunner, config);  
  
// Create a group profile  
const groupProfile: GroupProfile = {  
  name: 'My Community Group',  
  symbol: 'MCG',  
  description: 'A community group for local initiatives',  
  imageUrl: 'https://example.com/group-image.jpg',  
  location: 'Berlin, Germany'  
};  
  
// Register the group with a mint policy address  
const mintPolicyAddress = '0x1234...'; // The address of the minting policy to use  
const groupAvatar = await sdk.registerGroupV2(mintPolicyAddress, groupProfile);

Profile schema

{  
  "$schema": "http://json-schema.org/draft-07/schema#",  
  "title": "Circles Profile Schema",  
  "type": "object",  
  "required": ["name"],  
  "properties": {  
    "name": {  
      "type": "string",  
      "description": "The user's name (required)"  
    },  
    "description": {  
      "type": "string",  
      "description": "Additional information about the user"  
    },  
    "previewImageUrl": {  
      "type": "string",  
      "format": "uri",  
      "description": "URL for a preview/thumbnail image"  
    },  
    "imageUrl": {  
      "type": "string",  
      "format": "uri",  
      "description": "URL for a full-size profile image"  
    },  
    "location": {  
      "type": "string",  
      "description": "Text representation of the user's location (e.g., 'Berlin, Germany')"  
    },  
    "geoLocation": {  
      "type": "array",  
      "minItems": 2,  
      "maxItems": 2,  
      "items": {  
        "type": "number"  
      },  
      "description": "Coordinates as [latitude, longitude]"  
    },  
    "extensions": {  
      "type": "object",  
      "description": "Additional custom data as key-value pairs"  
    }  
  }  
}

Profile picture

You can include a profile picture in the profile document (the previewImageUrl). If you choose to do so, make sure the picture you are using has the following properties:

  1. Format: The image must be in PNG, JPEG, or GIF format.

  2. Dimensions: The image must be exactly 256x256 pixels.

  3. File size: The image must not exceed 150KB.

  4. Encoding: The image must be base64 encoded and included as a data URL in the previewImageUrl field.

These requirements are enforced by the server to ensure consistency and performance across the platform.

  const img = new Image();
        img.src = reader.result as string;
        img.onload = () => {
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          const cropWidth = 256;
          const cropHeight = 256;

          if (ctx) {
            canvas.width = cropWidth;
            canvas.height = cropHeight;

            ctx.drawImage(img, 0, 0, cropWidth, cropHeight);

            const imageDataUrl = canvas.toDataURL('image/jpeg', 0.5);

            if (imageDataUrl.length > 150 * 1024) {
              console.warn('Image size exceeds 150 KB after compression');
            }

Here is a code example (Browser; TypeScript) that shows how you can prepare the previewImageUrl.

Profiles that don't adhere to the spec aren't considered and won't be served by Circles' profile service.

Personal / Human Avatars

A human avatar v2 is implemented through the V2Avatar class which implements the AvatarInterfaceV2 interface. This represents an upgrade from the v1 implementation with enhanced capabilities.

Key Characteristics of Human Avatar V2

  1. Registration Process: Human avatars in v2 are created through an invitation system, where an existing user must invite you to join the network:

  2. V2 human avatars have associated profiles stored on IPFS, containing information like name, description, and images:

  3. Personal Token Minting: Human avatars in v2 can mint their own personal Circles tokens

  4. V2 human avatars can establish trust relationships with other avatars

  5. Token Transfers: V2 human avatars can transfer tokens to other avatars, with support for both direct and transitive transfers

Data Structure of v2 human avatar

The data for a human avatar v2 is stored in an AvatarRow structure, which would look something like:

{  
  blockNumber: 12345678,  
  logIndex: 42,  
  transactionIndex: 3,  
  timestamp: 1620000000,  
  transactionHash: "0x123abc456def789ghi...",  
  version: 2,  
  type: "CrcV2_RegisterHuman",  
  avatar: "0xabcdef1234567890abcdef1234567890abcdef12",  
  tokenId: "0xabcdef1234567890abcdef1234567890abcdef12",  
  hasV1: false,  
  isHuman: true,  
  cidV0Digest: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",  
  cidV0: "QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX"  
}

1. Creation of Personal/Human Avatars :

Circles v2.0 allows you to join the network as a human with an ERC-1155 standard token. You would have a profile and would require to be invited to join the network and start minting personal CRC tokens.

The V2 Hub contract is the main smart contract that a user would interact. You would need a profile CID as well.

const avatar = await avatar.inviteHuman(inviteeAddress,"Hk.....");        //CID required

const avatar = await sdk.acceptInvitation(inviterAddress,"Qm.....");
console.log(avatar.avatarInfo);

Incase, you don't have CID, you can use the Profile object and implicitly use the Circles pinning service to pin it:

const avatar = await sdk.acceptInvitation(inviterAddress, {
    name: "My profile name"
});
console.log(avatar.avatarInfo);

2. Getting mintable amount for an avatar

This function will allow you to get maximum amount of CRC tokens that are available to mint at that point of time. Human avatars can mint only upto 24 personal Circles per day.

const mintableToken = await avatar.getMintableamount ()

This function will allow you to mint your personal CRC tokens

const mintTransaction = await sdk.personalMint();
console.log('Transaction successful, receipt:', mintTransaction);

Find groups and memberships

You would be requiring to initialize the Circles data property to find groups and get memberships.

const data = sdk.data

Otherwise you can create an instance like this:

const circlesRpc = new CirclesRpc("https://rpc.aboutcircles.com");
//or add RINGS rpc if you are building with RINGS

const data = new CirclesData(circlesRpc);

Find Groups

  • Functionality: This method allows you to fetch a list of groups from the Circles system, with options for pagination and filtering. This is useful for applications that need to display groups or for querying specific groups based on certain criteria.

  • Parameters:

    • pageSize: A number specifying how many groups should be returned in the response.

    • params: An optional parameter that can include various filters for the query, such as group types or statuses.

const groupsPageSize = 10; // Define the maximum number of groups to return
const queryParams = { /* Example filter parameters */ };

try {
    const groupsQueryResult = await circles.data.findGroups(groupsPageSize, queryParams);
    console.log('Retrieved groups:', groupsQueryResult);
} catch (error) {
    console.error('Error fetching groups:', error);
}

Get group memberships

This method is designed to fetch all group memberships associated with a specific avatar. This is useful for applications that want to display or manage the groups that a user belongs to.

Parameters:

  • avatar: A string representing the address of the avatar for which group memberships are being requested.

  • pageSize: A number that specifies the maximum number of group memberships to return.

const avatarAddress = '0xYourAvatarAddress'; 
// The address of the avatar
const membershipsPageSize = 5; 
// Define the maximum number of memberships to return

try {
    const membershipsQueryResult = await circles.getGroupMemberships(avatarAddress, membershipsPageSize);
    console.log('Retrieved group memberships:', membershipsQueryResult);
} catch (error) {
    console.error('Error fetching group memberships:', error);
}

Example Usage

Here's how you might use these methods in your code:

// Initialize the SDK  
const sdk = new Sdk(contractRunner, config);  
  
// Find all groups with names starting with "Community"  
const groupsQuery = sdk.data.findGroups(10, {  
  nameStartsWith: "Community"  
});  
  
// Fetch the first page of results  
await groupsQuery.queryNextPage();  
console.log("Found groups:", groupsQuery.currentPage?.results);  
  
// Find all groups that a specific avatar is a member of  
const avatarAddress = "0x123..."; // Replace with actual address  
const membershipsQuery = sdk.data.getGroupMemberships(avatarAddress, 10);  
  
// Fetch the first page of results  
await membershipsQuery.queryNextPage();  
console.log("Group memberships:", membershipsQuery.currentPage?.results);

Managing trust connections via Org avatar account

Organizations can establish trust relationships with other avatars:

  1. Trust other avatars:

    await orgAvatar.trust(otherAvatarAddress);  // Or trust multiple avatars at once  await orgAvatar.trust([avatar1Address, avatar2Address]);
  2. Revoke trust:

    await orgAvatar.untrust(otherAvatarAddress);
  3. Check trust relationships:

    const isTrusting = await orgAvatar.trusts(otherAvatarAddress);
    const isTrustedBy = await orgAvatar.isTrustedBy(otherAvatarAddress);
  4. Get all trust relations:

    const trustRelations = await orgAvatar.getTrustRelations();

Circles Architecture

An overview of different components of circles architecture.

A flow of architecture for Circles Protocol

Circles V2 Core Components

Subscribing to Avatar events

The Circles SDK let's you subscribe to protocol events. Either filtered for an avatar or as a complete stream. There is also a way to query all past events in a block range.

Subscribe

To subscribe, you need an initialized CirclesData class.

Then call the subscribeToEvents() method and supply the address of the avatar to subscribe to:

If you want to subscribe to all events, call it without parameter:

Query past events

If your client missed some events, you can query all events for a specific avatar in a block range.

You can omit the last parameter (toBlock) to query from fromBlock to the latest block:

Event types

The above methods yield CirclesEvents. All events have at least the following base properties:

  • $event: CirclesEventType One of the event types listed below

  • blockNumber: number In which block the event occurred

  • timestamp?: number When the event occurred

  • transactionIndex: number The index of the transaction in the block

  • logIndex: number The index of the log entry in the transaction

  • transactionHash?: string The transaction hash

Here's a list of all event types. Please refer to the for the event properties.

Circles SDK Overview

The is a TypeScript library that allows you to integrate Circles protocol into your dApp to implement avatars, profiles, token transfers and build trust connections for your use-case. In backend, Circles SDK utilizes deployed hub contracts on Gnosis Chain, pathfinder for finding trust network paths and profile service.

As a developer, you can start from installing the core SDK and supported packages.

Circles v2.0 SDK features :

  • Manage Signers: Use a contract runner (like MetaMask) to sign transactions.

  • Circles Configuration: Set up Circles-specific configuration (contract addresses, RPC endpoints).

  • Access Circles Data: Query data through the Circles RPC Query API, including balances, trust relations, and transaction histories.

  • Support for Circles V1 and V2 Hubs: Interact with both V1 and V2 of Circles protocol hubs for contract-related operations,

  • Pathfinder Client: Use the V1 and V2 Pathfinder for finding liquid paths in trust networks to facilitate transfers.

  • Profile Management: Store and retrieve profiles (human, group, organization) via the Circles profile service.

  • Avatar Management:

    • Retrieve avatars by their address.

    • Register human, group, and organization avatars in Circles V1 and V2.

  • Invitation Handling: Accept invitations to join the Circles network by specifying an inviter and providing profile data.

Circles SDK dependency packages

Package
Purpose
Why Use It

Notes for Developers

  • The SDK uses ethers.js v6 for Ethereum interactions. Make sure, you are using Ethers V6 in your actual project as well to avoid compatibility issues.

  • Some features are specific to either v1 or v2 of the Circles protocol such as kind of avatars that exist on hub contract.

  • The SDK includes TypeScript definitions for improved developer experience and type safety.

  • When working with CIDs, the SDK provides utilities for handling both the raw bytes and base58-encoded formats.

Setting up Circles SDK with React

To access the entire codebase for building frontend applications using React and Circles SDK, check out the Github repo .

Query Circles profiles

💡 Query Circles Profiles

Retrieve user profile data using the Profiles Nethermind plugin. You can:

  • Create new user profiles

  • Search existing profiles using parameters such as:

    • Name

    • CID (Content Identifier)

    • Description

    • Wallet Address

1. Create a Profile (POST request)

2. Get a Profile by CID (GET request)

3. Get Multiple Profiles by CIDs (GET request)

4. Search Profiles by Name (GET request)

5. Search Profiles by Description (GET request)

6. Search Profiles by Address (GET request)

7. Search Profiles by CID (GET request)

8. Search Profiles with Multiple Criteria (GET request)

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"
           }
         }'
curl -X GET "https://rpc.aboutcircles.com/profiles/get?cid=Qm12345abcdef"
curl -X GET "https://rpc.aboutcircles.com/profiles/getBatch?cids=Qm12345abcdef,Qm678bbdj
curl -X GET "https://rpc.aboutcircles.com/profiles/search?name=John"
curl -X GET "https://rpc.aboutcircles.com/profiles/search?description=Circles"
curl -X GET "https://rpc.aboutcircles.com/profiles/search?address=0x1234567890abcdef"
curl -X GET "https://rpc.aboutcircles.com/profiles/search?CID=Qm12345abcdef"
curl -X GET "https://rpc.aboutcircles.com/profiles/search?name=John&description=blockchain&address=0x1234567890abcdef&CID=Qm12345abcdef"
npm i @circles-sdk/sdk

@circles-sdk/abi-v1

Provides the ABI for Circles V1 contracts.

Interact with Circles V1 smart contracts for transfers, minting, and managing trust relations.

@circles-sdk/abi-v2

Provides the ABI for Circles V2 contracts.

Interact with Circles V2 smart contracts for advanced features like group avatars, inflationary/demurrage tokens.

@circles-sdk/data

Wrapper around the Circles RPC Query API.

Query Circles-related data (balances, trust relationships, transaction histories) without direct contract interaction.

@circles-sdk/profiles

Manages Circles avatar profiles (human, group, organization).

Retrieve and store avatar profiles, manage trust relations, and handle identity in the Circles ecosystem.

@circles-sdk/adapter-ethers

Adapter to connect Circles SDK with Ethers.js.

Leverage Ethers.js for signing and sending transactions, connecting to wallets, and interacting with contracts.

ethers

Library for interacting with Ethereum-based blockchains.

Simplify blockchain interactions like sending transactions, querying data, and working with smart contracts. We would be using ethers v6 version for Circles SDK.

multihashes

Handles multihash algorithms for decentralized file storage.

Ensure compatibility with IPFS and manage content-addressable storage for file integrity in decentralized systems.

Circles SDK
import React, { createContext, useState, useEffect, useCallback } from "react";  
import { BrowserProviderContractRunner } from "@circles-sdk/adapter-ethers";  
import { Sdk } from "@circles-sdk/sdk";  
  
// Create a context for the Circles SDK  
const CirclesSDKContext = createContext(null);  
  
// Provider component to wrap around your application  
export const CirclesSDK = ({ children }) => {  
    const [sdk, setSdk] = useState(null);  
    const [isConnected, setIsConnected] = useState(false);  
    const [adapter, setAdapter] = useState(null);  
    const [circlesProvider, setCirclesProvider] = useState(null);  
    const [circlesAddress, setCirclesAddress] = useState(null);  
  
    // Configuration for the Circles SDK on Gnosis Chain  
    const circlesConfig = {  
        circlesRpcUrl: "https://rpc.aboutcircles.com/",  
        pathfinderUrl: "https://pathfinder.aboutcircles.com",  
        v1HubAddress: "0x29b9a7fbb8995b2423a71cc17cf9810798f6c543",  
        v2HubAddress: "0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8",  
        nameRegistryAddress: "0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474",  
        migrationAddress: "0xD44B8dcFBaDfC78EA64c55B705BFc68199B56376",  
        profileServiceUrl: "https://rpc.aboutcircles.com/profiles/",   
        baseGroupFactory: "0xD0B5Bd9962197BEaC4cbA24244ec3587f19Bd06d",  
        coreMembersGroupDeployer: "0xFEca40Eb02FB1f4F5F795fC7a03c1A27819B1Ded",
        }
  
    // Function to initialize the SDK  
    const initSdk = useCallback(async () => {  
        try {  
            // Create and initialize the adapter  
            const adapter = new BrowserProviderContractRunner();  
            await adapter.init(); // Initialize the adapter before using it  
              
            setAdapter(adapter);  
  
            // Get the provider and address  
            const provider = adapter.provider;  
            setCirclesProvider(provider);  
              
            const address = await adapter.address;  
            setCirclesAddress(address);  
              
            // Create the SDK instance with the config and adapter  
            const sdk = new Sdk(adapter, circlesConfig);  
            setSdk(sdk);  
            setIsConnected(true);  
        } catch (error) {  
            console.error("Error initializing SDK:", error);  
            setIsConnected(false);  
        }  
    }, []);  
  
    useEffect(() => {  
        initSdk();  
    }, [initSdk]);  
  
    return (  
        <CirclesSDKContext.Provider value={{  
            sdk,  
            isConnected,  
            setIsConnected,  
            adapter,  
            circlesProvider,  
            circlesAddress,  
            initSdk,  
        }}>  
            {children}  
        </CirclesSDKContext.Provider>  
    );  
};  
  
export default CirclesSDKContext;
here

Hub V2 Contract

An ERC-1155 standard contract for registeration of

  • human,

  • groups and

  • organisation avatars.

Manages trust relations, minting of personal CRC tokens, group currencies and demurrage.

Migration Contract

Allows transition from Legacy V1 hub avatars to V2 hub. Migration will lock V1 CRC tokens, stop minting V1 tokens and convert into V2 tokens.

Name Registry

NameRegistry contract manages names, symbols and metadata for avatars (humans, groups, and organizations).

The name would be of 12 characters with a base58 encoding and store metadata for avatar profiles.

Base Mint Policy

Base mint policy is standard contract is utilized group registration. Once registered the policy address is immutable for the group address. This is a reference implementation for minting, burning and redeeming the group currencies and developers can build their own custom policies as well.

Vaults

Vaults is a factor contract that holds the personal CRC collateral against the group currencies. Every group, there is single vault to query balance. This contract is deployed by Standard treasury and is utilized during redemption of group circles token.

Standard Treasury

The Standard Treasury handles minting and redemption of group Circles by managing collateral transfers. It ensures collateral is forwarded to the correct vault based on structured data from the Hub contract. Additionally, it verifies data during redemption to release or burn collateral as specified by the group's mint policy.

const avatarEvents = await data.subscribeToEvents("0x...");
avatarEvents.subscribe(event => {
    console.log(event);
});
const avatarEvents = await data.subscribeToEvents("0x...");
avatarEvents.subscribe(event => {
    console.log(event);
});
const avatarEvents = await data.getEvents("0x..", 9000000, 10000000);
const avatarEvents = await data.getEvents("0x..", 10000000);
export type CirclesEvent =

// CrcV1 Events

| CrcV1_HubTransfer
| CrcV1_Signup
| CrcV1_OrganizationSignup
| CrcV1_Trust
| CrcV1_Transfer

// CrcV2 Events

 | CrcV2_InviteHuman
 | CrcV2_PersonalMint
 | CrcV2_RegisterGroup
 | CrcV2_RegisterHuman
 | CrcV2_RegisterOrganization
 | CrcV2_Stopped
 | CrcV2_Trust
 | CrcV2_TransferSingle
 | CrcV2_Erc20WrapperTransfer
 | CrcV2_Erc20WrapperDeployed
 | CrcV2_URI
 | CrcV2_ApprovalForAll
 | CrcV2_TransferBatch
 | CrcV2_RegisterShortName
 | CrcV2_UpdateMetadataDigest
 | CrcV2_CidV0
 | CrcV2_StreamCompleted
 | CrcV2_CreateVault
 | CrcV2_GroupMintSingle
 | CrcV2_GroupMintBatch
 | CrcV2_GroupRedeem
 | CrcV2_GroupRedeemCollateralReturn
 | CrcV2_GroupRedeemCollateralBurn
 | CrcV2_DepositDemurraged
 | CrcV2_DepositInflationary
 | CrcV2_WithdrawDemurraged
 | CrcV2_WithdrawInflationary
source code
const circlesRpc = new CirclesRpc("https://rpc.aboutcircles.com/");
const data = new CirclesData(circlesRpc);
const circlesRpc = new CirclesRpc("https://static.94.138.251.148.clients.your-server.de/rpc/");
const data = new CirclesData(circlesRpc);

Circles Tools

Circles Tools is a collection of useful tooling for the community. These tools can be used as an extension to the circles core app for niche, specific and advanced usecases.

Here is a detailed list of tools, you can currently use:

  • Group Checker

    This tool displays detailed information about Circles group memberships and token balances. It can fetch on-chain data like ERC20 supplies, fees, and balances using a smart contract and direct links to relevant explorers and swap platforms.

  • Group Creator

    This tool allows users to create Circles groups with customizable metadata and membership conditions. It supports input of service address, group name, symbol, and optional initial trust conditions for setup.

  • Group Manager

    This tool enables group owners to manage and update their Circles group contracts directly from the browser. Owners can view contract details, add or remove trusted members, and modify settings like service or fee collection addresses.

  • Profile Checker

    This tool provides a detailed overview of any address’s Circles v1 and v2 profile details like profile data, token balances, trusted relationships, and live ERC20 prices, including bot classification and expiry info.

  • Safe State & Tx Hash Checker

    This tool allows users to inspect the state of a Gnosis Safe (owners, threshold, nonce) and compute a Safe transaction hash with full control over parameters like gas settings, operation type, and calldata. It also includes an interactive function encoder to help generate calldata from ABI inputs, and shows the full execTransaction calldata when approvals meet the threshold.

  • Trust Graph Visualizer

    This tool visualizes the web of trust relationships in the Circles ecosystem using an interactive force-directed graph. It supports avatars, PageRank-based trust scores, dynamic expansion (recursive and top-ranked), and rich filtering (Humans, Groups, Orgs). Users can explore any address, see stats and trust rankings in a sortable table, and view incoming/outgoing trust via tooltips and double-click expansion.

  • Trust Path Visualizer

    This advanced visualization tool helps users explore trust flow paths between two Circles addresses using an interactive Sankey diagram.

    It calculates on-chain trust paths for a given Circles token transfer amount, retrieves real-time token supply capacities, and visualizes flow bottlenecks. It’s ideal for understanding how CRC tokens route across trust relationships and for debugging why a transfer may or may not succeed.

  • Personal CRC Replenisher

    This tool lets Circles users replenish their own CRC token balance by routing it through the trust network back to themselves.

    It calculates the maximum amount you can send to yourself using existing trust paths, and builds a transaction to call operateFlowMatrix on the Circles Hub.

  • Circles Backing dApp

    This tool allows users to back their Circles tokens (CRC) with real-world assets like WBTC, WETH, GNO, or sDAI through a Safe-based flow on Gnosis Chain. It supports both Safe Apps and MetaMask wallet connections, computes a deterministic CirclesBacking contract address for any given Safe, registers appData with CowSwap to enable post-swap hooks, and guides the user through submitting two required transactions: approve() USDC.e to the factory and safeTransferFrom() CRC tokens via Hub V2.

  • LBP Starter

    This tool helps users easily create and manage Liquidity Bootstrapping Pools (LBPs) using their Circles tokens. It allows local groups or organizations to launch an LBP by selecting a group token (CRC), choosing a paired asset (like sDAI or GNO), specifying the amount of each token, and optionally configuring advanced parameters such as weight curves, swap fees, and duration. It also supports reloading or continuing with existing LBP contracts for inspection or finalization.

  • Token Distribution Checker

    This is an analytics tool for exploring the distribution of ERC-1155 Circles tokens. It allows users to input any Circles-compatible token address and fetch a full breakdown of its holders using the Circles Hub RPC API. The tool visually presents token holdings using a pie chart (with custom legends), paginated data tables, and balance percentages per holder. Each address is enriched with profile names (if available), explorer links, quick copy buttons, and the ability to recursively check other token distributions. Users can export the full dataset as CSV, verify the raw API data via a debug panel, and dynamically navigate token ownership. This tool is ideal for community organizers, protocol designers, or auditors who want transparency and insight into token spread, supply concentration, and holder identity.

  • Legagacy Circles Safe Creator

    This tool is designed to help users deploy a Gnosis Safe (v1.1.1) contract instance with a single owner, tailored for legacy use within the Circles ecosystem. By connecting a MetaMask wallet, users can specify any valid Ethereum address as the owner and generate a new Safe contract using a proxy factory and master copy on Gnosis Chain. The tool handles address validation, transaction submission, and post-deployment verification to confirm that the specified address was correctly set as the owner of the Safe. It is especially useful for onboarding Circles users who need a compatible Safe to manage CRC tokens and interact with legacy dApps.

  • Onboarding Helper

    This tool allows people to easily join a Circles group by scanner a QR code.

  • Equilibrium Analaysis

    This tool provides a dynamic view into market efficiency and arbitrage activity within the Circles economy. It visualizes the moving average of arbitrage profit opportunities over time—expressed in USD—based on configurable time windows, helping identify trends in CRC market imbalances. Simultaneously, it offers a price equilibration analysis by showing the distribution of price spreads between liquid CRC token pairs, flagging deviations from parity using customizable thresholds, liquidity filters, and deviation types (absolute or relative). Together, these insights help traders, analysts, and protocol maintainers detect inefficiencies, monitor arbitrage potential, and assess the overall health of price discovery in the Circles ecosystem.

  • Pathfinder Pro App

    This is an advanced visualization and simulation tool that computes and displays optimal token transfer paths through the Circles network graph. Users can specify a source address, destination address, and CRC value, along with custom token inclusion filters for both sender and receiver. The tool supports optional wrapped token inclusion and lets users configure visual and performance parameters—such as edge curvature, capacity gradients, node/edge labels, and tooltip details—for clarity and analysis. Upon clicking “Find Path,” the graph engine simulates feasible routes, showing flow capacity and rendering performance in real-time. This makes the Pathfinder useful for debugging trust routes, analyzing payment viability, and exploring how CRC tokens can move through the social trust graph, especially in complex multi-hop scenarios.

Query Circles Data

The CirclesData class provides an easy-to-use selection of common queries that are suitable for most use cases.

Initialization

Most of the previously shown avatar methods internally use the CirclesData class with filters for the current avatar address. If you already have a configured Sdk instance, you can use the sdk.data property to access the class:

const data = sdk.data;

Otherwise you can create an instance like this:

const circlesRpc = new CirclesRpc("https://rpc.aboutcircles.com/");
const data = new CirclesData(circlesRpc);
const circlesRpc = new CirclesRpc("https://static.94.138.251.148.clients.your-server.de/rpc/");
const data = new CirclesData(circlesRpc);

Get avatar info

The getAvatarInfo(avatar: string): Promise<AvatarRow | undefined> method finds basic information about an avatar. This includes the signup timestamp, circles version, avatar type (human, organization or group), and token address/id as well as it's profile CID (if any).

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");
}

Get token info

The getTokenInfo(tokenId: string): Promise<TokenInfoRow | undefined> methods finds basic information about a Circles token. This includes the creation timestamp, circles version, token type (human or group) and the address of the avatar that created the token.

const tokenInfo = await data.getTokenInfo("0x...");
if (tokenInfo) {
   console.log("Token is a Circles token");
} else {
   console.log("Token is not a Circles token");
}

Get total balance (v1, v2)

The total Circles balance of an avatar is the sum of all it's personalized and group token holdings. It can be queried with the getTotalBalance(avatar:string): Promise<string> method. There is a separate method for each Circles version.

const totalBalanceV1 = await data.getTotalBalance("0x...");
const totalBalanceV2 = await data.getTotalBalanceV2("0x...");

The methods have a second, optional parameter asTimeCircles?: boolean = true that controls the return value format. The default value (true) returns a floating point number as a string, while false returns a bigint number as a string. If you want to use the value for calculations you need to parse them.

Get detailed token balances (v1, v2)

In contrast to the above method, the getTokenBalances(avatar: string): Promise<TokenBalanceRow[]> method gives a detailed overview of an avatar's Circles holdings. As with the method above, this one also exists for both versions of the Circles protocol.

The result row contains the token, balance and the tokenOwner.

const detailedCirclesBalancesV1 = await data.getTokenBalances("0x...");
const detailedCirclesBalancesV2 = await data.getTokenBalancesV2("0x...");

The methods have a second, optional parameter asTimeCircles?: boolean = true that controls the return value format. The default value (true) returns a floating point number as a string, while false returns a bigint number as a string. If you want to use the value for calculations you need to parse them.

Get transaction history

The getTransactionHistory(avatar: string, pageSize: number): CirclesQuery<TransactionHistoryRow> method can be used to query all incoming and outgoing Circles transfers from and to an avatar. This includes minting and transfers of personal and group Circles for v1 and v2.

The result rows have the following properties:

  • timestamp When the transaction happened

  • transactionHash

  • version If the transaction happened in Circles v1 or v2

  • operator (the operator that facilitated the transaction - v2 only)

  • from the sender address

  • to the receiver address

  • id in v1: the token address, in v2: the token id

  • value the transferred raw value for the given version (bigint)

  • timeCircles a floating point number representation of the value for display purposes

  • tokenAddress an address representation of the numeric tokenid (v2) or the actual erc20 token address of a v1 personal token

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));

The results are ordered in descending order.

Get trust relations

The getTrustRelations(avatar: string, pageSize: number): CirclesQuery<TrustListRow> method can be used to query the effective trust events for an avatar. Already expired or removed trust relations are omitted from the results.

const trustsQuery = data.getTrustRelations("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));

The results of this method contain one row per incoming or outgoing event. This is useful when you need to know when a relation was established. However, if you just want to display a contact list you should consider using getAggregatedTrustRelations(avatarAddress: string): Promise<TrustRelationRow[]> instead.

Get aggregated trust relations

In contrast to the above method, this method queries all relevant trust events and groups mutual trust events into a single row instead of one for each direction.

The result rows have the following properties:

  • subjectAvatar The acting avatar

  • relation The relation between the acting avatar and the one it's related to

  • objectAvatar The other avatar

The possible relations are: trusts, trustedBy, mutuallyTrusts, and selfTrusts. The last one (selfTrusts) exists because, in Circles, every avatar trusts itself.

const trustRelations = await data.getAggregatedTrustRelations("0x..");
trustRelations.forEach(row => console.log(row));

Find groups

Circles groups have a name and symbol that's stored on-chain. You can use the findGroups(pageSize: number, params: GroupQueryParams): CirclesQuery<GroupRow> method to find groups by name or symbol.

The params parameter can be used to filter and order the result set by the name and symbol of a group.

export interface GroupQueryParams {
  nameStartsWith?: string;
  symbolStartsWith?: string;
  groupAddressIn?: string[];
  sortBy?: 'age_asc' | 'age_desc' | 'name_asc' | 'name_desc' | 'symbol_asc' | 'symbol_desc';
}

Use the method as following:

const query = data.findGroups(25, {
  nameStartsWith: "Test",
});

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));

If an avatar is member at a group (as defined by a trust relation from the group to the avatar), it's usually eligible to mint tokens of that group.

Get group memberships

You can query the group memberships of an avatar using the getGroupMemberships(avatar: string, pageSize: number): CirclesQuery<GroupMembershipRow> method to get a list of all groups an avatar is a member of.

The result rows contain the following properties: group, member, expiryTime.

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));

If you want to query the details of the returned groups, you can pass the group addresses into the groupAddressIn filter field of the findGroups() method.

Get invited users

Avatars can invite others to join Circles. The getInvitations(avatar: string, pageSize: number): CirclesQuery<InvitationRow> method returns a list of invitations sent by the specified avatar.

Th e result rows contain the follwing properties: timestamp, transactionHash, inviter, invited.

const query = data.getInvitations("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 invited by

You can query who invited an other avatar by calling getInvitedBy(avatar:string): Promise<string|undefined>. If the avatar wasn't invited, the method returns undefined.

const invitedBy = await data.getInvitedBy("0x...");

SDK Methods

1. getAvatar

Gets an avatar instance by its address.

getAvatar: (avatarAddress: string, subscribe?: boolean) => Promise<Avatar>
  • Parameters:

    • avatarAddress: The avatar’s wallet address.

    • subscribe: Optional, whether to subscribe to avatar events.

  • Returns: A Promise that resolves to an Avatar instance.

Usage Example:

const avatar = await sdk.getAvatar("0x123...abc");

2. acceptInvitation

Accepts an invitation to join Circles using either CID or Profile.

acceptInvitation: (inviter: string, cidV0: string) => Promise<AvatarInterface>;
//or
acceptInvitation: (inviter: string, profile: Profile) => Promise<AvatarInterface>;
  • Parameters:

    • inviter: The address of the inviting avatar.

    • cidV0: The CIDv0 of the avatar’s metadata (or profile data).

  • Returns: A Promise resolving to an AvatarInterface.

Usage Example:

await sdk.acceptInvitation("0xInviterAddress", "QmProfileCID");

3. registerHuman

Registers the connected wallet as a human avatar in Circles V1.

registerHuman: () => Promise<AvatarInterface>
  • Returns: A Promise resolving to an AvatarInterface, representing the registered human avatar.

Usage Example:

const humanAvatar = await sdk.registerHuman();

4. registerOrganization

Registers the connected wallet as an organization avatar in Circles V1.

registerOrganization: () => Promise<AvatarInterface>
  • Returns: A Promise resolving to an AvatarInterface for the organization avatar.

Usage Example:

const organizationAvatar = await sdk.registerOrganization();

5. registerOrganizationV2

Registers the connected wallet as an organization avatar in Circles V2 with profile data.

registerOrganizationV2: (profile: Profile) => Promise<AvatarInterface>
  • Parameters:

    • profile: A Profile object representing the organization’s profile.

  • Returns: A Promise resolving to an AvatarInterface.

Usage Example:

const orgProfile = { name: "OrgName", description: "An example organization." };
const orgAvatarV2 = await sdk.registerOrganizationV2(orgProfile);

6. registerGroupV2

Registers the connected wallet as a group avatar in Circles V2 with profile data.

registerGroupV2: (mint: string, profile: GroupProfile) => Promise<AvatarInterface>
  • Parameters:

    • mint: Address of the minting policy contract.

    • profile: A GroupProfile object containing group information.

  • Returns: A Promise resolving to an AvatarInterface.

Usage Example:

const groupProfile = { name: "GroupName", description: "An example group." };
const groupAvatarV2 = await sdk.registerGroupV2("0xMintAddress", groupProfile);

7. migrateAvatar

Migrates a V1 avatar and its Circles holdings to V2.

migrateAvatar: (avatar: string, profile: Profile, trustRelations?: string[]) => Promise<void>
  • Parameters:

    • avatar: The address of the avatar to migrate.

    • profile: Profile data of the avatar.

    • trustRelations: Optional, a list of trust relations to migrate.

  • Returns: A Promise resolving to void.

Usage Example:

const profile = { name: "John Doe", description: "Human Avatar" };
await sdk.migrateAvatar("0xAvatarAddress", profile);

8. createOrUpdateProfile

Creates or updates a user profile in Circles.

UpdateProfile: (profile: Profile | string) => Promise<ContractTransactionReceipt>
  • Parameters:

    • profile: A Profile object or a CID string pointing to the profile.

  • Returns: A Promise that resolves to a ContractTransactionReceipt.

Usage Example:

const profileData = { name: "John Doe", description: "Developer" };
const receipt = await sdk.createOrUpdateProfile(profileData);

9. migrateV1Tokens

Migrates all V1 token holdings of an avatar to V2.

migrateV1Tokens: (avatar: string, tokens?: string[]) => Promise<void>
  • Parameters:

    • avatar: The avatar whose tokens need to be migrated.

    • tokens: Optional list of token addresses.

  • Returns: A Promise resolving to void.

Usage Example:

await sdk.migrateV1Tokens("0xAvatarAddress");

10. getInflationaryWrapper

Gets an inflationary wrapper for managing tokens.

getInflationaryWrapper: (wrapperAddress: string) => Promise<InflationaryCircles>
  • Parameters:

    • wrapperAddress: Address of the inflationary wrapper contract.

  • Returns: A Promise resolving to InflationaryCircles.

Usage Example:

const inflationaryWrapper = await sdk.getInflationaryWrapper("0xWrapperAddress");

11. getDemurragedWrapped

This function retrieves a demurrage wrapper, which is used to manage tokens that decrease in value over time (demurrage).

getDemurragedWrapper: (wrapperAddress: string) => Promise<DemurrageCircles>

Parameters:

  • wrapperAddress: The address of the demurrage wrapper contract.

Returns : A Promise that resolves to an instance of DemurrageCircles.

Usage Example:

const demurrageWrapper = await sdk.getDemurragedWrapper("0xWrapperAddress");

Glossary

This glossary contains terms and definitions used throughout the Circles documentation.

ERC-1155

ERC-1155 is an Ethereum token standard that enables the efficient transfer and bundling of multiple fungible and non-fungible tokens in a single transaction. This multi-token standard allows for the creation of complex token systems, such as those used in gaming or supply chain management, where different types of tokens need to be managed simultaneously.

The standard introduces a new set of functions, including safeTransferFrom, safeBatchTransferFrom, and balanceOfBatch, which allow for the transfer and querying of multiple token balances in a single call. This reduces gas costs and simplifies token management compared to using multiple ERC-20 or ERC-721 contracts.

ERC-1155 tokens are identified by a unique combination of an address and an ID, allowing for the creation of an unlimited number of token types within a single contract. The standard also includes an optional metadata extension, enabling developers to associate additional information, such as images or descriptions, with each token type.

See also:

Externally-Owned Account

An externally-owned account (also known as EOA) is one of the two types of Ethereum accounts. A private key controls it; it has no code, and users can send messages by creating and signing Ethereum transactions.

See also:

  • on ethereum.org

  • on ethereum.org

Gasless Transaction

Gasless transactions (also known as meta-transactions) are Ethereum transactions that are executed by a third party called on behalf of a to abstract the use of gas. Users must sign a message (instead of the transaction itself) with information about the transaction they want to execute. A relayer will create the Ethereum transaction, sign and execute it, and pay for the gas costs. The main benefit is that users can interact with the blockchain without holding the native token in their account.

See also:

  • on docs.safe.global

Network

A blockchain network is a collection of interconnected computers that utilize a blockchain protocol for communication. Decentralized networks allow users to send transactions, that are processed on a distributed ledger with a consensus mechanism ensuring the batching, verification, and acceptance of data into blocks. This structure enables the development of applications without the need for a central authority or server.

See also:

  • on ethereum.org

Owner

A Safe owner is one of the accounts that control a given Safe. Only owners can manage the configuration of a Safe and approve transactions. They can be either or . The of a Safe defines how many owners need to approve a Safe transaction to make it executable.

See also:

  • on github.com

Relayer

A relayer is a third-party service acting as an intermediary between users' accounts and . It executes transactions on behalf of users and covers the associated execution costs, which may or may not be claimed.

See also:

  • on docs.gelato.network

Safe Wallet

Safe is a smart contract wallet that requires a minimum number of people to approve a transaction before it can occur (M-of-N). If for example you have 3 main stakeholders in your business, you are able to set up the wallet to require approval from 2 out of 3 (2/3) or all 3 people before the transaction is sent. This assures that no single person could compromise the funds.

See also:

Smart Account

A smart account (also known as a smart contract account) leverages the programmability of smart contracts to extend its functionality and improve its security in comparison with . Smart accounts are controlled by one or multiple externally-owned accounts or other smart accounts, and all transactions have to be initiated by one of those.

Some common features that smart accounts offer to their users are:

  • Multi-signature scheme

  • Transaction batching

  • Account recovery

Safe is one of the most trusted implementations of a smart account.

Transaction

A transaction is an action initiated by an to update the state of the EVM network. Transaction objects must be signed using the sender's private key, require a fee, and be included in a validated block.

A Safe transaction is a transaction sent to a Safe Proxy contract calling the method.

See also:

  • on ethereum.org

Threshold

The threshold of a Safe account is a crucial configuration element that enables using Safe as a multi-signature smart account. It defines the number of required confirmations from the Safe owners a (Safe) transaction must have to be executable.

See also:

  • and of a Safe with the Safe{Core} SDK on docs.safe.global

Wallet

A wallet is an interface or application that gives users control over their blockchain account. Wallets allow users to sign in to applications, read their account balance, send transactions, and verify their identity.

See also:

  • on ethereum.org

First Prize
Runner Up
ERC-1155 Multi Token Standard on Ethereum.org
Ethereum Accounts
Ethereum Whitepaper
relayer
smart account
Relay Kit documentation
Networks
externally-owned accounts
smart accounts
threshold
OwnerManager.sol
blockchain networks
What's Relaying?
What is Safe?
externally-owned accounts
Gasless transactions
externally-owned account
execTransaction
Transactions
Get the threshold
change the threshold
Ethereum Wallets
BraceBuddy | ETHGlobalethglobal
Voting with UBI | ETHGlobalethglobal
Famjam | ETHGlobalethglobal
woleth.eth | ETHGlobalethglobal
Runner Up

Circles Data Methods

Circles Data class provides various methods to query and interact with Circles' data, such as balances, transaction history, trust relations, group memberships, and avatar information. It is built around the Circles RPC to facilitate communication with the blockchain and retrieve relevant data. The CirclesData class exposes methods for both CRCv1 and CRCv2 tokens, trust events, and group information, as well as subscriptions to events.

1. getTotalBalance

Gets the total CRC V1 balance of an address.

Parameters:

  • avatar: The address to get the CRC balance for.

  • asTimeCircles (optional): Return the balance as TimeCircles or not (default is true).

Returns: A Promise<string> representing the total balance.

Usage Example:


2. getTotalBalanceV2

Gets the total CRC V2 balance of an address.

Parameters:

  • avatar: The address to get the CRC balance for.

  • asTimeCircles (optional): Return the balance as TimeCircles or not (default is true).

Returns: A Promise<string> representing the total balance.

Usage Example:


3. getTokenBalances

Gets the detailed token balances of an address.

Parameters:

  • avatar: The address to get the token balances for.

Returns: A Promise<TokenBalanceRow[]> containing the token balances.

Usage Example:


4. getTransactionHistory

Gets the transaction history of an address (incoming/outgoing transactions and CRC minting).

Parameters:

  • avatar: The address to get the transaction history for.

  • pageSize: The maximum number of transactions per page.

Returns: A CirclesQuery<TransactionHistoryRow> object.

Usage Example:


5. getTrustRelations

Gets the current incoming and outgoing trust relations of an address.

Parameters:

  • avatar: The address to get the trust list for.

  • pageSize: The maximum number of trust relations per page.

Returns: A CirclesQuery<TrustListRow> object.

Usage Example:


6. getAggregatedTrustRelations

Gets all trust relations of an avatar and groups mutual trust relations together.

Parameters:

  • avatarAddress: The address to get the trust relations for.

Returns: A Promise<TrustRelationRow[]> representing the trust relations.

Usage Example:


7. getAvatarInfo

Gets basic information about an avatar.

Parameters:

  • avatar: The address to check.

Returns: A Promise<AvatarRow | undefined> with the avatar info or undefined if not found.

Usage Example:


8. getAvatarInfos

Gets basic information about multiple avatars.

Parameters:

  • avatars: The addresses to check.

Returns: A Promise<AvatarRow[]> containing avatar information.

Usage Example:


9. getTokenInfo

Gets the token info for a given token address.

Parameters:

  • address: The address of the token.

Returns: A Promise<TokenInfoRow | undefined> with the token info or undefined if not found.

Usage Example:


10. subscribeToEvents

Subscribes to Circles events.

Parameters:

  • avatar (optional): The avatar to subscribe to. If not provided, all events are subscribed to.

Returns: A Promise<Observable<CirclesEvent>> representing the event stream.

Usage Example:


11. getEvents

Gets the events for a given avatar in a block range.

Parameters:

  • avatar (optional): The avatar to get the events for.

  • fromBlock (optional): The starting block number.

  • toBlock (optional): The ending block number.

  • eventTypes (optional): Types of events to filter.

  • filters (optional): Additional filter criteria.

  • sortAscending (optional): Whether to sort events in ascending order.

Returns: A Promise<CirclesEvent[]> representing the events.

Usage Example:


12. getInvitations

Gets the invitations sent by an avatar.

Parameters:

  • avatar: The avatar to get the invitations for.

  • pageSize: The maximum number of invitations per page.

Returns: A CirclesQuery<InvitationRow> object.

Usage Example:


13. getInvitedBy

Gets the avatar that invited the given avatar.

Parameters:

  • avatar: The address of the invited avatar.

Returns: A Promise<string | undefined> with the address of the inviting avatar or undefined if not found.

Usage Example:


14. findGroups

Gets the list of groups.

Parameters:

  • pageSize: The maximum number of groups per page.

  • params (optional): Query parameters to filter groups.

Returns: A CirclesQuery<GroupRow> object.

Usage Example:


15. getGroupMemberships

Gets the group memberships of an avatar.

Parameters:

  • avatar: The avatar to get the group memberships for.

  • pageSize: The maximum number of group memberships per page.

Returns: A CirclesQuery<GroupMembershipRow> object.

Usage Example:


16. getMetadataCidForAddress

Gets the metadata CID for an address.

Parameters:

  • address: The address to get the metadata CID for.

Returns: A Promise<string | undefined> with the CID or undefined if not found.

Usage Example:

Circles API Specifications

getTotalBalance(avatar: string, asTimeCircles?: boolean): Promise<string>
const balance = await circlesData.getTotalBalance("0xAvatarAddress");
getTotalBalanceV2(avatar: string, asTimeCircles?: boolean): Promise<string>
const balanceV2 = await circlesData.getTotalBalanceV2("0xAvatarAddress");
getTokenBalances(avatar: string): Promise<TokenBalanceRow[]>
const balances = await circlesData.getTokenBalances("0xAvatarAddress");
getTransactionHistory(avatar: string, pageSize: number): CirclesQuery<TransactionHistoryRow>
const history = await circlesData.getTransactionHistory("0xAvatarAddress", 10);
getTrustRelations(avatar: string, pageSize: number): CirclesQuery<TrustListRow>
const trustRelations = await circlesData.getTrustRelations("0xAvatarAddress", 10);
getAggregatedTrustRelations(avatarAddress: string): Promise<TrustRelationRow[]>
const aggregatedTrust = await circlesData.getAggregatedTrustRelations("0xAvatarAddress");
getAvatarInfo(avatar: string): Promise<AvatarRow | undefined>
const avatarInfo = await circlesData.getAvatarInfo("0xAvatarAddress");
getAvatarInfos(avatars: string[]): Promise<AvatarRow[]>
const avatarInfos = await circlesData.getAvatarInfos(["0xAvatar1", "0xAvatar2"]);
getTokenInfo(address: string): Promise<TokenInfoRow | undefined>
const tokenInfo = await circlesData.getTokenInfo("0xTokenAddress");
subscribeToEvents(avatar?: string): Promise<Observable<CirclesEvent>>
const eventStream = await circlesData.subscribeToEvents("0xAvatarAddress");
getEvents(avatar?: string, fromBlock?: number, toBlock?: number, eventTypes?: string[], filters?: FilterPredicate[], sortAscending?: boolean): Promise<CirclesEvent[]>
const events = await circlesData.getEvents("0xAvatarAddress", 0, 100, ["Transfer"], [], true);
getInvitations(avatar: string, pageSize: number): CirclesQuery<InvitationRow>
const invitations = await circlesData.getInvitations("0xAvatarAddress", 10);
getInvitedBy(avatar: string): Promise<string | undefined>
const inviter = await circlesData.getInvitedBy("0xAvatarAddress");
findGroups(pageSize: number, params?: GroupQueryParams): CirclesQuery<GroupRow>
const groups = await circlesData.findGroups(10, { name: "ExampleGroup" });
getGroupMemberships(avatar: string, pageSize: number): CirclesQuery<GroupMembershipRow>
const memberships = await circlesData.getGroupMemberships("0xAvatarAddress", 10);
getMetadataCidForAddress(address: string): Promise<string | undefined>
const metadataCid = await circlesData.getMetadataCidForAddress("0xAddress");

Welcome to Circles

Circles is a decentralized protocol designed to create and distribute fair and social money through personal currencies. At the core of the Circles project lies a simple yet powerful principle:

"Every person receives one Circle every hour, unconditionally."

Circles uses smart contracts, deployed on Gnosis Chain, for creation of personal and group Avatars and their currencies (CRC). Circles as a network works via trust connection. To join Circles 2.0, you would require an invitation from a human/personal avatar. The pathfinder service is deployed to find the optimal path between trust connections to exchange personal and group currencies. Circles smart contracts are based on ERC1155 multi-token standard for both personal avatars and group avatars.

Every person receives 1 CRC every hour, hence 24 CRC per single day. Circles undergo daily demurrage at a rate equivalent to 7% per year. Issuance for past days accounts for this demurrage, ensuring fair distribution over time.

This documentation will guide developers in understanding Avatars and using the Circles SDK.

Logo
Logo
Logo
Logo

Creation of Organizations

Organizations are different from groups as you can't mint an organization token, use profiles and trust other avatars to receive tokens from them.

const profile = {  
  name: "Organization Name",  
  description: "About the organization"  
};  
  
// Register a V2 organization avatar with the profile  
const orgAvatarV2 = await sdk.registerOrganizationV2(profile);
const registerLegacyOrganization = async (sdk) => {
    try {
        const avatar = await sdk.registerOrganization(); // Call the legacy method
        console.log('Legacy Organization Avatar:', avatar);
    } catch (error) {
        console.error('Error registering legacy organization:', error);
    }
};

Circles SDK interface

The Circles SDK provides a high-level interface for interacting with the Circles protocol, focusing on features like user profiles, avatars, token transfers, and contract interactions. It integrates with Circles V1 and V2 hubs, and enables registration, migration, and management of avatars and profiles.

Class: Sdk

This class implements the SdkInterface, which provides core functionality to interact with the Circles protocol.

The Sdk class implements the following interface:

import { Avatar } from './avatar';
import { CirclesConfig } from './circlesConfig';
import { V1Pathfinder } from './v1/pathfinderV1';
import { AvatarInterface } from './AvatarInterface';
import { EthSafeTransaction } from "@safe-global/protocol-kit";
import { Hub as HubV1, NameRegistryV1 } from '@circles-sdk/abi-v1';
import { CMGroupDeployer, BaseGroupFactory, DemurrageCircles, Hub as HubV2, InflationaryCircles, NameRegistry } from '@circles-sdk/abi-v2';
import { AvatarRow, CirclesData, CirclesRpc } from '@circles-sdk/data';
import { Address } from '@circles-sdk/utils';
import { GroupProfile, Profile, Profiles } from '@circles-sdk/profiles';
import { ContractTransactionReceipt } from 'ethers';
import { SdkContractRunner } from '@circles-sdk/adapter';
import { V2Pathfinder } from './v2/pathfinderV2';
import { GroupType } from '@circles-sdk/data/dist/circlesDataInterface';
/**
 * The SDK interface.
 */
interface SdkInterface {
    /**
     * The signer used to sign transactions (connected wallet e.g. MetaMask).
     */
    contractRunner: SdkContractRunner;
    /**
     * The chain specific Circles configuration (contract addresses and rpc endpoints).
     */
    circlesConfig: CirclesConfig;
    /**
     * A configured instance of the CirclesData class, an easy-to-use wrapper around
     * the Circles RPC Query API.
     */
    data: CirclesData;
    /**
     * An instance of the typechain generated Circles V1 Hub contract wrapper.
     */
    v1Hub: HubV1;
    /**
     * An instance of the typechain generated Circles V2 Hub contract wrapper.
     */
    v2Hub?: HubV2;
    /**
     * An instance of the v1 Pathfinder client (necessary for transfers; only available on gnosis chain with v1 Circles at the moment).
     */
    v1Pathfinder?: V1Pathfinder;
    /**
     * An instance of the v2 Pathfinder client.
     */
    v2Pathfinder?: V2Pathfinder;
    /**
     * An instance of the v2 Core Members Group deployer.
     */
    coreMembersGroupDeployer?: CMGroupDeployer;
    /**
     * An instance of the v2 Base Group deployer.
     */
    baseGroupFactory?: BaseGroupFactory;
    /**
     * Stores and retrieves profiles from the Circles profile service.
     */
    profiles?: Profiles;
    /**
     * Gets an Avatar instance by its address. Fails if the avatar is not signed up at Circles.
     * @param avatarAddress The avatar's address.
     * @returns The Avatar instance.
     */
    getAvatar: (avatarAddress: Address) => Promise<Avatar>;
    /**
     * Registers the connected wallet as a human avatar in Circles v1.
     * @returns The Avatar instance.
     */
    registerHuman: () => Promise<AvatarInterface>;
    /**
     * Registers the connected wallet as an organization avatar in Circles v1.
     */
    registerOrganization: () => Promise<AvatarInterface>;
    /**
     * Registers the connected wallet as an organization avatar in Circles v2.
     * @param profile The profile data of the organization.
     */
    registerOrganizationV2: (profile: Profile) => Promise<AvatarInterface>;
    /**
     * Registers the connected wallet as a group avatar in Circles v2.
     * @param mint The address of the minting policy contract to use.
     * @param profile The profile data of the group.
     */
    registerGroupV2: (mint: Address, profile: GroupProfile) => Promise<AvatarInterface>;
    /**
     * Migrates a v1 avatar and all its Circles holdings to v2.
     * [[ Currently only works for human avatars. ]]
     * @param inviter The address of the avatar that invited the user to v2. Can be 'ZeroAddress' during migration period.
     * @param avatar The avatar's address.
     * @param profile The profile data of the avatar.
     * @trustRelations An optional list of trust relations to migrate.
     */
    migrateAvatar: (inviter: Address, avatar: Address, profile: Profile, trustRelations?: string[]) => Promise<void | EthSafeTransaction>;
    /**
     * Creates or updates a user profile.
     *
     * @param {Profile | string} profile - Profile object containing user information or a CID pointing to an existing profile.
     * @returns {Promise<ContractTransactionReceipt>} - A promise that resolves to the transaction receipt of the operation.
     */
    createOrUpdateProfile: (profile: Profile | string) => Promise<ContractTransactionReceipt>;
    /**
     * Checks if an avatar can self-migrate to v2.
     * @param avatarInfo The avatar's info.
     */
    canSelfMigrate: (avatarInfo: AvatarRow) => Promise<boolean>;
}
/**
 * The SDK provides a high-level interface to interact with the Circles protocol.
 */
export declare class Sdk implements SdkInterface {
    /**
     * The signer used to sign transactions.
     */
    readonly contractRunner: SdkContractRunner;
    /**
     * The chain specific Circles configuration.
     */
    readonly circlesConfig: CirclesConfig;
    /**
     * The Circles RPC client.
     */
    readonly circlesRpc: CirclesRpc;
    /**
     * The Circles data client.
     */
    readonly data: CirclesData;
    /**
     * The typechain generated V1 hub contract wrapper.
     */
    readonly v1Hub: HubV1;
    /**
     * The typechain generated V2 hub contract wrapper.
     */
    readonly v2Hub?: HubV2;
    /**
     * The typechain generated NameRegistry contract wrapper.
     */
    readonly nameRegistry?: NameRegistry;
    /**
     * The typechain generated V1NameRegistry contract wrapper.
     */
    readonly v1NameRegistry?: NameRegistryV1;
    /**
     * The pathfinder client (v1).
     */
    readonly v1Pathfinder?: V1Pathfinder;
    /**
     * The pathfinder client (v2).
     */
    readonly v2Pathfinder: V2Pathfinder;
    /**
     * The Core Members Group deployer (v2).
     */
    readonly coreMembersGroupDeployer?: CMGroupDeployer;
    /**
     * The Base Group deployer (v2).
     */
    readonly baseGroupFactory?: BaseGroupFactory;
    /**
     * The profiles service client.
     */
    readonly profiles?: Profiles;
    /**
     * Contains the bootstrap periods for each known hub contract.
     */
    readonly bootstrapPeriods: {
        [contract: string]: number;
    };
    /**
     * Creates a new SDK instance.
     * @param contractRunner A contract runner instance and its address.
     * @param config The optional chain specific Circles configuration.
     */
    constructor(contractRunner: SdkContractRunner, config?: CirclesConfig);
    /**
     * Gets an avatar by its address.
     * @param avatarAddress The avatar's address.
     * @param subscribe Whether to subscribe to avatar events.
     * @returns The avatar instance.
     * @throws If the given avatar address is not signed up at Circles.
     */
    getAvatar: (avatarAddress: Address, subscribe?: boolean) => Promise<Avatar>;
    /**
     * Creates or updates a profile and registers its CID in the NameRegistry.
     *
     * @param {Profile | string} profile - The profile information or profile ID to be created or updated.
     * @returns {Promise<ContractTransactionReceipt>} - A promise that resolves to the transaction receipt.
     * @throws {Error} - Throws an error if the Profiles service or NameRegistry is not configured,
     *                   or if the transaction fails.
     */
    createOrUpdateProfile: (profile: Profile | string) => Promise<ContractTransactionReceipt>;
    /**
     * Registers the connected wallet as a human avatar.
     * @returns The avatar instance.
     */
    registerHuman: () => Promise<AvatarInterface>;
    /**
     * If you have been invited to Circles, you can accept the invitation and join the Circles network.
     * Specify who invited you and supply the profile you want to use with your new account.
     * @param inviter The address of the avatar that invited you.
     * @param cidV0 The CIDv0 of the avatar's ERC1155 token metadata.
     */
    acceptInvitation(inviter: Address, cidV0: string): Promise<AvatarInterface>;
    /**
     * If you have been invited to Circles, you can accept the invitation and join the Circles network.
     * @param inviter The address of the avatar that invited you.
     * @param profile The profile data of the avatar.
     */
    acceptInvitation(inviter: Address, profile: Profile): Promise<AvatarInterface>;
    private _registerHuman;
    /**
     * Checks if the profile argument is a string or a Profile object and creates the profile if necessary.
     * If the profile is a string, it must be a CIDv0 string (Qm...).
     * @param profile The profile data or CIDv0 of the avatar.
     * @private
     */
    private createProfileIfNecessary;
    /**
     * Registers the connected wallet as an organization avatar.
     * @returns The avatar instance.
     */
    registerOrganization: () => Promise<AvatarInterface>;
    /**
     * Registers the connected wallet as an organization avatar in Circles v2.
     * @param profile The profile data of the organization.
     */
    registerOrganizationV2: (profile: Profile) => Promise<AvatarInterface>;
    /**
     * Registers the connected wallet as a group avatar in Circles v2.
     * @param mint The address of the minting policy contract to use.
     * @param profile The profile data of the group.
     */
    registerGroupV2: (mint: Address, profile: GroupProfile) => Promise<AvatarInterface>;
    private waitForAvatarInfo;
    /**
     * Migrates a v1 avatar, and optionally it's trust relations to v2.
     * @param inviter The address of the avatar that invited the user to v2. Can be 'ZeroAddress' during migration period or if the account that's migrating stopped minting in v1 during the migration period.
     * @param avatar The avatar's address.
     * @param profile The profile data of the avatar.
     * @param trustRelations An optional list of trust relations to migrate.
     */
    migrateAvatar: (inviter: Address, avatar: Address, profile: Profile, trustRelations?: string[], isRawCalldata?: boolean) => Promise<void | EthSafeTransaction>;
    /**
     * Checks if an avatar can self-migrate to v2.
     * This is possible either during the migration period or if the avatar stopped minting in v1 before or during that period.
     * @param avatarInfo The avatar's info.
     * @private
     */
    canSelfMigrate(avatarInfo: AvatarRow): Promise<boolean>;
    /**
     * Migrates all V1 token holdings of an avatar to V2 using batch transactions.
     * @param avatar The avatar whose tokens to migrate.
     * @param tokens An optional list of token addresses to migrate. If not provided, all tokens will be migrated.
     * @param batch An optional batch transaction to add transactions to.
     */
    migrateV1TokensBatch: (avatar: Address, tokens?: Address[], batch?: any) => Promise<void>;
    /**
     * Migrates all V1 token holdings of an avatar to V2.
     * @param avatar The avatar whose tokens to migrate.
     * @param tokens An optional list of token addresses to migrate. If not provided, all tokens will be migrated.
     */
    migrateV1Tokens: (avatar: Address, tokens?: Address[]) => Promise<void>;
    getInflationaryWrapper: (wrapperAddress: Address) => Promise<InflationaryCircles>;
    getDemurragedWrapper: (wrapperAddress: Address) => Promise<DemurrageCircles>;
    isCoreMembersGroup: (avatar: Address) => Promise<boolean>;
    getGroupType: (avatar: Address) => Promise<GroupType | undefined>;
    /**
     * Checks if the `to` address is a group minter and excludes the group tokens from the transfer
     * if that's the case.
     * @param to The receiver of the transfer
     * @param excludeFromTokens The existing list of tokens to exclude from the transfer
     * @returns The complete list of tokens to exclude from the transfer
     */
    getDefaultTokenExcludeList(to: Address, excludeFromTokens?: Address[]): Promise<Address[] | undefined>;
}
export {};
//# sourceMappingURL=sdk.d.ts.map

Constructor

constructor(contractRunner: SdkContractRunner, config?: CirclesConfig)
  • Parameters:

    • contractRunner: An instance of SdkContractRunner, which is responsible for signing transactions.

    • config: Optional, an instance of CirclesConfig, containing chain-specific configurations (addresses and endpoints).

Additional Modules Used

  • Avatar: Represents the Circles avatar with methods for interacting with its state.

  • CirclesConfig: Holds chain-specific configurations such as contract addresses and RPC endpoints.

  • Pathfinder: Provides routing for token transfers on the Circles network.

  • Profiles: Manages avatar profiles within Circles.

  • ContractTransactionReceipt: Used to manage transactions and their receipts on the Ethereum blockchain.

Circles Tools

Utilising CirclesQuery Class

The CirclesQuery class allows you to execute custom queries against the Circles RPC api.

The previously shown CirclesData class returns CirclesQuery<T> objects for all paged query results. You can execute custom queries against all tables in the Circles index and filter with them.

Write a query

First you'll need to define a query. The basic structure of a query is the same as for a basic SQL select. It has the following fields:

  • namespace: Used to distinguish between tables and views as well and to tell the tables of the two Circles version apart from each other.

  • table: The name of the table you want to query.

  • columns: A list of column names you want to select.

  • filter: A list of filter conditions that must be met.

  • sortOrder: Can be 'asc' or 'desc'.

  • limit: How many rows to return (max: 1000).

Check out the documentation of the for a list of tables.

Here is a query that reads all avatars with type group. Other avatar types you can try are human and organization.

If you want to be able to load the next page (queryNextPage()) you must always include the following fields in your query:blockNumber, transactionIndex, logIndex.

Define a row type

You can define a type for the rows of your query, or just go with any if the type doesn't matter.

If you want to specify a custom type, it must extend the EventRow type. The EventRow type contains the blockNumber, transactionIndex and logIndex fields which are required for pagination.

Execute the query

To execute the query definition, you'll need a CirclesRpc instance. Create one and pass the Circles rpc url to the constructor.

Then create a CirclesQuery<MyGroupType> instance.

Call getNextPage() to retrieve the first page of the result set. You can then access the results through the currentPage property. This property includes the results themselves, along with firstCursor, lastCursor, limit, size, and sortOrder.

Add computed columns

You can extend the CirclesQuery with computed columns. Computed columns are defined by a callback that takes in the row and returns a new value. Here we convert the value of the previously queried cidV0Digest field (which is originally a hex-string) to a CID in Qm.. format.

The new column should be added to the custom type.

Then you can execute the query just like you did before. The calculated column function will be executed for each row in a page.

const queryDefinition: PagedQueryParams = {
  namespace: 'V_Crc',
  table: 'Avatars',
  columns: [
    'blockNumber',
    'transactionIndex',
    'logIndex',
    'avatar',
    'name',
    'cidV0Digest'
  ],
  filter: [
    {
      Type: 'FilterPredicate',
      FilterType: 'Equals',
      Column: 'type',
      Value: 'group'
    }
  ],
  sortOrder: 'ASC',
  limit: 100
};
interface MyGroupType extends EventRow {
  avatar: string;
  name: string;
  cidV0Digest?: string;
}
const circlesRpc = new CirclesRpc('https://chiado-rpc.aboutcircles.com');
const query = new CirclesQuery<MyGroupType>(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));
}
const calculatedColumns = [{
  name: 'cidV0',
  generator: async (row: MyGroupType) => {
    if (!row.cidV0Digest) {
      return undefined;
    }

    const dataFromHexString = hexStringToUint8Array(row.cidV0Digest.substring(2));
    return uint8ArrayToCidV0(dataFromHexString);
  }
}];
interface MyGroupType extends EventRow {
  avatar: string;
  name: string;
  cidV0Digest?: string;
  cidV0?: string
}
const query = new CirclesQuery<MyGroupType>(circlesRpc, queryDefinition, calculatedColumns);

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));
}
circles_queryrpc method

Create Base Groups for your community

Base Groups are capable of following:

  • They can set membership conditions to define who can be part of the group

  • They can register short names with a nonce

  • They can trust other avatars in batch with conditions

Base Group Creation Process

To create a base group, you would:

  1. Initialize the SDK with the proper configuration

  2. Use the baseGroupFactory property to call the factory contract's creation methods

  3. After creation, get the base group avatar using sdk.getAvatar()

import { Sdk } from '@circles-sdk/sdk';
import { cidV0ToUint8Array } from '@circles-sdk/utils';
import { ethers } from 'ethers';

// Initialize the SDK
const sdk = new Sdk(contractRunner, config);

// Define the group profile (symbol is required)
const groupProfile = {
  name: "My Base Group",
  symbol: "MBG",
  description: "A base group for community coordination",
  imageUrl: "",             // optional, can be uploaded via SDK
  previewImageUrl: "",      // optional, used for previews
};

// Define base group setup options
const serviceAddress = "0xService...";      // Replace with actual service address
const feeCollection = "0xFeeCollection..."; // Replace with actual treasury address
const initialConditions = [
  "0xAddress1...",
  "0xAddress2..."
  // Add more addresses if needed
];

// Step 1: Create the group profile (CID will be returned)
const profileCID = await sdk.profiles.create(groupProfile);
if (!profileCID) throw new Error("Failed to create profile CID");

// Step 2: Create the base group using the factory
const tx = await sdk.baseGroupFactory.createBaseGroup(
  senderAddress,           // Usually wallet address of the sender
  serviceAddress,
  feeCollection,
  initialConditions,
  groupProfile.name,
  groupProfile.symbol,
  cidV0ToUint8Array(profileCID)  // Convert CID to bytes
);

// Wait for transaction confirmation
const receipt = await tx.wait();

// Step 3: Extract the group address from emitted events
const groupAddress = ethers.stripZerosLeft(receipt.logs[9].topics[1]);

// Step 4: Get the avatar for the created group
const baseGroupAvatar = await sdk.getAvatar(groupAddress.toLowerCase());

console.log("Base group created at:", groupAddress);
console.log("Group avatar:", baseGroupAvatar);

Working with Base Groups

After creating a base group, you can interact with it using the BaseGroupAvatar class, which provides methods for:

  1. Membership Management:

    • setMembershipCondition(condition, enabled) - Sets a membership condition

    • getMembershipConditions() - Gets the current membership conditions

  2. Trust Management:

    • trust(avatar, expiry) - Trusts another avatar with optional expiry

    • untrust(avatar) - Revokes trust from an avatar

    • trustBatchWithConditions(members, expiry) - Trusts multiple avatars at once with conditions

  3. Group Administration:

    • setOwner(owner) - Changes the group owner

    • setService(service) - Sets the service address

    • setFeeCollection(feeCollection) - Sets the fee collection address

    • registerShortNameWithNonce(nonce) - Registers a short name for the group

Quickstart Guide for Circles SDK

This guide will help you get started with the Circles SDK. It shows how to use the Circles SDK with MetaMask.

Prerequisites

  • Browser wallet such as Metamask or Rabby Wallet

  • Setup or add Gnosis Chain (Mainnet) as your network for wallet. Check out Gnosis Chain docs here.

  • Some xDAI token for paying gas fees. Check out Mainnet Faucet

Circles SDK Installation

If you have all prerequisites in place, start by installing the Circles SDK package and ethers v6 in your project using npm.

npm i @circles-sdk/sdk @circles-sdk/data @circles-sdk/utils @circles-sdk/profiles @circles-sdk/adapter-ethers ethers

1. Add imports

Then, import the necessary interfaces from the Circles SDK and Ethers.

import { circlesConfig, Sdk } from '@circles-sdk/sdk';
import {BrowserProviderContractRunner} from "@circles-sdk/adapter-ethers"
  • circlesConfig: Contains predefined configurations, such as contract addresses for different environments (production version).

  • Sdk: The main Circles SDK class, which provides methods to interact with the protocol, including token transfers, trust relationships, and contract interactions.

Since we are using browser-based wallets like Rabby and MetaMask, we will import the BrowserProviderContractRunner adapter, which connects the Circles SDK with Ethers.js, enabling smart contract interactions through a browser-based Ethereum provider.

2. Add CirclesConfig for SDK

CirclesConfig defines the configuration settings needed to set up the SDK. You provide an object that follows this structure when initializing the SDK.

Circles is available on Gnosis Chain for production and sandbox version. You need to specify the correct contract addresses and service endpoints for each environment.

Circles contracts are deployed on Gnosis Chain mainnet. The below config is for applications that would be built in production environment.

import type {CirclesConfig} from "@circles-sdk/sdk";

export const GnosisChainConfig: CirclesConfig = {
    circlesRpcUrl: "https://rpc.aboutcircles.com/",
    pathfinderUrl: "https://pathfinder.aboutcircles.com",
    profileServiceUrl: "https://rpc.aboutcircles.com/profiles/",
    v1HubAddress: "0x29b9a7fbb8995b2423a71cc17cf9810798f6c543",
    v2HubAddress: "0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8",
    nameRegistryAddress: "0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474",
    migrationAddress: "0xD44B8dcFBaDfC78EA64c55B705BFc68199B56376",
    standardTreasury: "0x08F90aB73A515308f03A718257ff9887ED330C6e",
    baseGroupMintPolicy: "0xcCa27c26CF7BAC2a9928f42201d48220F0e3a549",
    coreMembersGroupDeployer: "0xFEca40Eb02FB1f4F5F795fC7a03c1A27819B1Ded",
    baseGroupFactory: "0xD0B5Bd9962197BEaC4cbA24244ec3587f19Bd06d"
};

RINGS is a sandbox version of Circles protocol. If you are a builder or developer who is building on Circles for fun and want to see how the overall mechanics work - then this would be your place to begin.


import type {CirclesConfig} from "@circles-sdk/sdk";

export const circlesConfig: CirclesConfig = {
    circlesRpcUrl: 'https://static.94.138.251.148.clients.your-server.de/rpc/',
    pathfinderUrl: 'https://pathfinder.aboutcircles.com',
    profileServiceUrl: 'https://static.94.138.251.148.clients.your-server.de/profiles/',
    v1HubAddress: '0x29b9a7fbb8995b2423a71cc17cf9810798f6c543',
    v2HubAddress: '0x3D61f0A272eC69d65F5CFF097212079aaFDe8267',
    nameRegistryAddress: '0x8D1BEBbf5b8DFCef0F7E2039e4106A76Cb66f968',
    migrationAddress: '0x28141b6743c8569Ad8B20Ac09046Ba26F9Fb1c90',
    baseGroupMintPolicy: '0x79Cbc9C7077dF161b92a745345A6Ade3fC626A60',
    standardTreasury: '0x3545955Bc3900bda704261e4991f239BBd99ecE5',
    coreMembersGroupDeployer: '0x7aD59c08A065738e34f13Ac94542867528a1D328',
    baseGroupFactory:'0x452C116060cBB484eeDD70F32F08aD4F0685B5D2'
};
Property
Description

v2PathfinderUrl

The URL for the V2 Pathfinder service (if using V2).

pathfinderUrl

The URL for the Pathfinder service (used in V1).

circlesRpcUrl

The URL for the Circles RPC service

profileServiceUrl

The URL for the profile service that manages user profiles in Circles.

v1HubAddress

The contract address for the Circles V1 Hub.

v2HubAddress?

The contract address for the Circles V2 Hub.

nameRegistryAddress

The address of the name registry contract.

migrationAddress

The address used for migrating avatars and tokens from V1 to V2.

baseGroupMintPolicy

The address of the minting policy used for group avatars in Circles.

coreMemberGroupDeployer

The address for groups that are deployed using core members instance

baseGroupFactory

The address for factory contract that will be used for groups deployment

3. Using Circles SDK Configuration

Circles contracts are deployed on the Gnosis Chain mainnet. The following configuration is intended for production-ready applications.

If you are building dApps on Circles SDK for hackathon or want to check sandbox deployments, then follow this segment to setup sandbox configuration for using the SDK.

You can seamlessly import the production-ready smart contract addresses directly from the Circles SDK, as they are already hardcoded within the SDK.

import { circlesConfig } from '@circles-sdk/sdk';

The circlesConfig object provides predefined contract addresses and service endpoints required for seamless integration with Circles on Gnosis Chain. It adheres to the CirclesConfig type from the Circles SDK.

Here's the configuration if you use CirclesConfig type from Circles SDK along with deployed contracts:

import type {CirclesConfig} from "@circles-sdk/sdk";

export const GnosisChainConfig: CirclesConfig = {
    circlesRpcUrl: "https://rpc.aboutcircles.com/",
    pathfinderUrl: "https://pathfinder.aboutcircles.com",
    profileServiceUrl: "https://rpc.aboutcircles.com/profiles/",
    v1HubAddress: "0x29b9a7fbb8995b2423a71cc17cf9810798f6c543",
    v2HubAddress: "0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8",
    nameRegistryAddress: "0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474",
    v1NameRegistryAddress: "0x1eaD7F904F6fFC619c58B85e04F890b394E08172",
    migrationAddress: "0xD44B8dcFBaDfC78EA64c55B705BFc68199B56376",
    baseGroupMintPolicy: "0xcCa27c26CF7BAC2a9928f42201d48220F0e3a549",
    standardTreasury: "0x08F90aB73A515308f03A718257ff9887ED330C6e",
    coreMembersGroupDeployer: "0xFEca40Eb02FB1f4F5F795fC7a03c1A27819B1Ded",
    baseGroupFactory: "0xD0B5Bd9962197BEaC4cbA24244ec3587f19Bd06d"
    };

Using the sandbox version of Circles SDK for builders

RINGS is a sandbox version of the Circles protocol designed for testing the Circles SDK without worrying about production requirements. If you are a builder or developer working on Circles for a hackathon and want to understand how the overall mechanics function, this is the place to start.

The only change you need to make to your codebase is updating the Circles configuration addresses to the sandbox contract addresses.

import type {CirclesConfig} from "@circles-sdk/sdk";

export const circlesConfig: CirclesConfig = {
    circlesRpcUrl: 'https://static.94.138.251.148.clients.your-server.de/rpc/',
    pathfinderUrl: 'https://pathfinder.aboutcircles.com',
    profileServiceUrl: 'https://static.94.138.251.148.clients.your-server.de/profiles/',
    v1HubAddress: '0x29b9a7fbb8995b2423a71cc17cf9810798f6c543',
    v2HubAddress: '0x3D61f0A272eC69d65F5CFF097212079aaFDe8267',
    nameRegistryAddress: '0x8D1BEBbf5b8DFCef0F7E2039e4106A76Cb66f968',
    migrationAddress: '0x28141b6743c8569Ad8B20Ac09046Ba26F9Fb1c90',
    baseGroupMintPolicy: '0x79Cbc9C7077dF161b92a745345A6Ade3fC626A60',
    standardTreasury: '0x3545955Bc3900bda704261e4991f239BBd99ecE5',
    coreMembersGroupDeployer: '0x7aD59c08A065738e34f13Ac94542867528a1D328',
    baseGroupFactory:'0x452C116060cBB484eeDD70F32F08aD4F0685B5D2'
};

Once you have configured the sandbox addresses in your config.ts ,you can proceed with setting up the provider and signer as mentioned below.

4. Setup Provider and Signer

To setup provider and signer, we would utilize the Circles Adapter that is built to support transactions via ethers. Once you have already imported the BrowserProviderContractRunner , you would need to initialize it.

const adapter = new BrowserProviderContractRunner();
await adapter.init();

5. Initialize the Circles SDK

To initialize the CirclesSDK, we will pass on the circlesConfig and Adapter to SDK instance.

const sdk = new Sdk (adapter,circlesConfig); 
// or GnosisChainConfig as named in config

Once you have successfully created a SDK instance, you are all set to use Circles in your dApp.

Summary for the setup of Circles SDK

To quickly summarize how the entire setup of Circles SDK would look like if you are writing a script etc.

Installation

npm i @circles-sdk/sdk @circles-sdk/data @circles-sdk/utils @circles-sdk/profiles @circles-sdk/adapter-ethers ethers

Import the packages and setup script

import { circlesConfig, Sdk } from '@circles-sdk/sdk';
// or use the type import and then set up Circles contracts in configurations
// import type {CirclesConfig} from "@circles-sdk/sdk";
import {BrowserProviderContractRunner} from "@circles-sdk/adapter-ethers"

const adapter = new BrowserProviderContractRunner();
await adapter.init();

const sdk = new Sdk (adapter,circlesConfig); 
// or GnosisChainConfig as named in config
Optional : Setup deployed contracts based on production or sandbox version of Circles Protocol

Production version:

import type {CirclesConfig} from "@circles-sdk/sdk";

export const GnosisChainConfig: CirclesConfig = {
circlesRpcUrl: "https://rpc.aboutcircles.com/",
pathfinderUrl: "https://pathfinder.aboutcircles.com",
v1HubAddress: "0x29b9a7fbb8995b2423a71cc17cf9810798f6c543",
v2HubAddress: "0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8",
nameRegistryAddress: "0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474",
migrationAddress: "0xD44B8dcFBaDfC78EA64c55B705BFc68199B56376",
profileServiceUrl: "https://rpc.aboutcircles.com/profiles/",
};

Sandbox version:

// For sandbox version
import type {CirclesConfig} from "@circles-sdk/sdk";

export const circlesConfig: CirclesConfig = {
    circlesRpcUrl: "https://static.94.138.251.148.clients.your-server.de/rpc/",
    v1HubAddress: "0x29b9a7fbb8995b2423a71cc17cf9810798f6c543",
    v2HubAddress: "0x3D61f0A272eC69d65F5CFF097212079aaFDe8267",
    migrationAddress: "0x28141b6743c8569Ad8B20Ac09046Ba26F9Fb1c90",
    nameRegistryAddress: "0x8D1BEBbf5b8DFCef0F7E2039e4106A76Cb66f968",
    baseGroupMintPolicy: "0x79Cbc9C7077dF161b92a745345A6Ade3fC626A60",
    profileServiceUrl: "https://static.94.138.251.148.clients.your-server.de/profiles/",
};

Voila 🎉 you're done with Circles SDK setup. Now, you can support Circles profiles and choose the Avatars that you would like to integrate and support their additional functions.

Choose which Avatar would you like to build on


Personal / Human Avatars

ERC-1155 standard avatars, which allows you to mint your personal Circles token (CRC) every hour, accumulating 24 CRC per day with an applied demurrage of 7%.

Group Avatars

Created by an owner, these avatars allow groups to trust human avatars within the group. Group tokens are utilized by collateralizing personal tokens, following the ERC-1155 standard.

Organization Avatars

As an organization, you are an avatar without any minting of new tokens. With your name and metadata file, which will be used for identification and can trust other avatars to receive Circles, with all owned Circles earned by avatars rather than minted.

Circles Events Types

Base Event: CirclesBaseEvent

This is the base type for all Circles events. It contains common metadata for all events.

  • $event: CirclesEventType — The event type, defining which event occurred.

  • blockNumber: number — The block number in which the event was logged.

  • timestamp: number (optional) — The timestamp when the event occurred.

  • transactionIndex: number — Index of the transaction in the block.

  • logIndex: number — Index of the log within the transaction.

  • transactionHash: string (optional) — The hash of the transaction that emitted this event.


CrcV1_HubTransfer

Triggered when a transfer of Circles tokens happens via the Circles Hub.

  • $event: 'CrcV1_HubTransfer'

  • from: string (optional) — Address sending the tokens.

  • to: string (optional) — Address receiving the tokens.

  • amount: bigint (optional) — Amount of tokens transferred.


CrcV1_Signup

Triggered when a new user signs up in the Circles system.

  • $event: 'CrcV1_Signup'

  • user: string (optional) — Address of the new user.

  • token: string (optional) — The token assigned to the user.


CrcV1_OrganizationSignup

Triggered when an organization signs up.

  • $event: 'CrcV1_OrganizationSignup'

  • organization: string (optional) — Address of the organization.


CrcV1_Trust

Emitted when a trust relationship is created.

  • $event: 'CrcV1_Trust'

  • canSendTo: string (optional) — The address that can receive tokens from the user.

  • user: string (optional) — The user creating the trust.

  • limit: bigint (optional) — The limit up to which the user can send tokens.


CrcV1_Transfer

Triggered when a token transfer occurs in the Circles V1 system.

  • $event: 'CrcV1_Transfer'

  • tokenAddress: string (optional) — Address of the token.

  • from: string (optional) — Address sending the tokens.

  • to: string (optional) — Address receiving the tokens.

  • amount: bigint (optional) — Amount of tokens transferred.


CrcV2_InviteHuman

Triggered when a human is invited to Circles.

  • $event: 'CrcV2_InviteHuman'

  • inviter: string (optional) — Address of the inviter.

  • invited: string (optional) — Address of the invited human.


CrcV2_PersonalMint

Triggered when a personal minting event occurs.

  • $event: 'CrcV2_PersonalMint'

  • human: string (optional) — Address of the human minting tokens.

  • amount: bigint (optional) — Amount of tokens minted.

  • startPeriod: bigint (optional) — Start of the minting period.

  • endPeriod: bigint (optional) — End of the minting period.


CrcV2_RegisterGroup

Triggered when a group is registered.

  • $event: 'CrcV2_RegisterGroup'

  • group: string (optional) — Address of the group.

  • mint: string (optional) — Address of the mint.

  • treasury: string (optional) — Address of the treasury.

  • name: string (optional) — Name of the group.

  • symbol: string (optional) — Symbol for the group.


CrcV2_RegisterHuman

Triggered when a human registers in Circles.

  • $event: 'CrcV2_RegisterHuman'

  • avatar: string (optional) — Avatar of the registered human.

  • inviter: string (optional) — Address of the inviter.


CrcV2_RegisterOrganization

Triggered when an organization is registered.

  • $event: 'CrcV2_RegisterOrganization'

  • organization: string (optional) — Address of the organization.

  • name: string (optional) — Name of the organization.


CrcV2_Stopped

Triggered when an avatar stops its activity.

  • $event: 'CrcV2_Stopped'

  • avatar: string (optional) — Avatar that stopped.


CrcV2_Trust

Triggered when a trust relationship is established in Circles V2.

  • $event: 'CrcV2_Trust'

  • truster: string (optional) — The address of the truster.

  • trustee: string (optional) — The address of the trustee.

  • expiryTime: bigint (optional) — Expiry time of the trust relationship.


CrcV2_TransferSingle

Triggered during a single token transfer in Circles V2.

  • $event: 'CrcV2_TransferSingle'

  • operator: string (optional) — Address of the operator.

  • from: string (optional) — Address sending the token.

  • to: string (optional) — Address receiving the token.

  • id: bigint (optional) — ID of the token being transferred.

  • value: bigint (optional) — Value of the token transferred.


CrcV2_URI

Triggered when a token's URI is updated.

  • $event: 'CrcV2_URI'

  • value: string (optional) — The new URI value.

  • id: bigint (optional) — ID of the token with the updated URI.


CrcV2_ApprovalForAll

Triggered when an account gives or revokes permission to an operator.

  • $event: 'CrcV2_ApprovalForAll'

  • account: string (optional) — The account giving or revoking permission.

  • operator: string (optional) — The operator being granted or revoked permission.

  • approved: boolean (optional) — Whether the approval was granted (true) or revoked (false).


CrcV2_TransferBatch

Triggered during a batch transfer in Circles V2.

  • $event: 'CrcV2_TransferBatch'

  • batchIndex: number — Index of the batch.

  • operator: string (optional) — Address of the operator.

  • from: string (optional) — Address sending the tokens.

  • to: string (optional) — Address receiving the tokens.

  • id: bigint (optional) — ID of the token being transferred.

  • value: bigint (optional) — Value of the tokens transferred.


CrcV2_RegisterShortName

Triggered when a short name is registered to an avatar.

  • $event: 'CrcV2_RegisterShortName'

  • avatar: string (optional) — Avatar registering the short name.

  • shortName: bigint (optional) — The registered short name.

  • nonce: bigint (optional) — The nonce of the registration.


CrcV2_UpdateMetadataDigest

Triggered when an avatar's metadata digest is updated.

  • $event: 'CrcV2_UpdateMetadataDigest'

  • avatar: string (optional) — Avatar updating the metadata.

  • metadataDigest: Uint8Array (optional) — The new metadata digest.


CrcV2_CidV0

Triggered when an avatar's CID (Content Identifier) for metadata is updated.

  • $event: 'CrcV2_CidV0'

  • avatar: string (optional) — Avatar updating the CID.

  • cidV0Digest: Uint8Array (optional) — The new CID v0 digest.


CrcV2_StreamCompleted

Triggered when a streaming payment or data transfer is completed.

  • $event: 'CrcV2_StreamCompleted'

  • operator: string (optional) — Address of the operator.

  • from: string (optional) — Address sending the streamed payment.

  • to: string (optional) — Address receiving the streamed payment.

  • id: bigint (optional) — ID of the streamed token.

  • amount: bigint (optional) — Total amount streamed.


CrcV2_CreateVault

Triggered when a vault is created.

  • $event: 'CrcV2_CreateVault'

  • vault: string (optional) — Address of the vault.

  • token: string (optional) — Address of the token stored in the vault.

The Circles Stack

Developers Hub for building with Circles.

Our developer documentation portal provides comprehensive guide to build using Circles SDK, SDK references, contract addresses, and code examples to help you integrate Circles into your applications and build upon our ecosystem.

Circles SDK

If you want to develop a server or client application that utilizes Circles, and allow you to utilize trust connection and personal/group currencies, then Circles SDK would be your entry point. Based on your need, you can pick to develop any avatar post initialization of SDK.

  • Circles SDK package on npm

  • Circles SDK source code

Circles Infrastructure

Circles Hub Contracts

Circles relies on hub contracts for V1 and V2 that you can utilize directly within applications. These deployed contracts exist on Gnosis Chain and are required by the SDK for configuration and initialization.

Here are the deployed addresses for V1 hub and V2 hub that you should consider for configuration or building tools on Circles protocol:

Contract Name
Deployed addresses

V1 hub contract

0x29b9a7fbb8995b2423a71cc17cf9810798f6c543

V2 hub contract

0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8

Name registry

0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474

Migration contract

0xD44B8dcFBaDfC78EA64c55B705BFc68199B56376

Base mint policy

0xcCa27c26CF7BAC2a9928f42201d48220F0e3a549

If you want to skip directly to setting up Circles SDK in your application, you can jump to the SDK Configuration Guide which covers all the setup parameters.

Join the Technical Community

To collaborate with fellow developers, ask questions, and share your insights, join our technical community channels on Discord, GitHub, and other platforms.

Join Telegram Group as a Hacker or a Developer.

Quickstart Guide for Circles SDK

Pathfinder

Finds liquid paths between two accounts in the trust network. These paths are used as input for the contract's transfer methods.

Learn more about Pathfinder

Circles Nethermind Plug-in

Provides access to the Gnosis Chain and indexes Circles events for a seamless experience.

Learn more about Circles Nethermind Plug-in

Circles V1 contract source code

Review the codebase for Circles Contracts V1, including all core features and specifications related to Hub Contract and minting.

Circles V2 contract source code

Review the codebase for Circles contracts V2 which follows ERC1155 standard, and manages personal, group and organisation avatars.

Circles V2 Reference docs

Explore the latest updates and functionalities of Circles v2.0 Contracts with detailed documentation.

https://github.com/circlesubi/circles-contracts/
https://github.com/aboutcircles/circles-contracts-v2
https://aboutcircles.github.io/circles-contracts-v2/

Get **v1** Circles total balance of an address

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getTotalBalance","params":["0xde374ece6fa50e781e81aac78e811b33d16912c7",true]}
and
Responses
200
Balance string
application/json
Responseall of
and
post
POST //circles_getTotalBalance HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 120

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getTotalBalance",
  "params": [
    "0xde374ece6fa50e781e81aac78e811b33d16912c7",
    true
  ]
}
200

Balance string

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "99999999999999999999999999999999999"
}

Get **v2** Circles total balance of an address

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circlesV2_getTotalBalance","params":["0xcadd4ea3bcc361fc4af2387937d7417be8d7dfc2",true]}
and
Responses
200
Balance string
application/json
Responseall of
and
post
POST //circlesV2_getTotalBalance HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 122

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circlesV2_getTotalBalance",
  "params": [
    "0xcadd4ea3bcc361fc4af2387937d7417be8d7dfc2",
    true
  ]
}
200

Balance string

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "99999999999999999999999999999999999"
}

Token-level balance breakdown (on-chain)

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getTokenBalances","params":["0xc6d075112b96b75460e543e3bf70be9ab45b62d9"]}
and
Responses
200
Array of token balances
application/json
post
POST //circles_getTokenBalances HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 116

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getTokenBalances",
  "params": [
    "0xc6d075112b96b75460e543e3bf70be9ab45b62d9"
  ]
}
200

Array of token balances

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Fast indexed balance breakdown for an avatar

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getBalanceBreakdown","params":["0x14b31a052964143b4c455e3650164ff6c91f81be"]}
and
Responses
200
Balance map per token
application/json
post
POST //circles_getBalanceBreakdown HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 119

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getBalanceBreakdown",
  "params": [
    "0x14b31a052964143b4c455e3650164ff6c91f81be"
  ]
}
200

Balance map per token

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

List trust relations (in + out) for an avatar

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getTrustRelations","params":["0xde374ece6fa50e781e81aac78e811b33d16912c7"]}
and
Responses
200
Array of trust edges
application/json
post
POST //circles_getTrustRelations HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 117

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getTrustRelations",
  "params": [
    "0xde374ece6fa50e781e81aac78e811b33d16912c7"
  ]
}
200

Array of trust edges

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Common outgoing trustees of two avatars

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getCommonTrust","params":["0xde374ece6fa50e781e81aac78e811b33d16912c7","0xe8fc7a2d0573e5164597b05f14fa9a7fca7b215c"]}
and
Responses
200
Intersection of trustees
application/json
post
POST //circles_getCommonTrust HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 159

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getCommonTrust",
  "params": [
    "0xde374ece6fa50e781e81aac78e811b33d16912c7",
    "0xe8fc7a2d0573e5164597b05f14fa9a7fca7b215c"
  ]
}
200

Intersection of trustees

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Path-finding with target flow (Circles v2)

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":0,"method":"circlesV2_findPath","params":[{"Source":"0x749c930256b47049cb65adcd7c25e72d5de44b3b","Sink":"0xde374ece6fa50e781e81aac78e811b33d16912c7","TargetFlow":"99999999999999999999999999999999999"}]}
and
Responses
200
Path with flow allocations
application/json
post
POST //circlesV2_findPath HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 224

{
  "jsonrpc": "2.0",
  "id": 0,
  "method": "circlesV2_findPath",
  "params": [
    {
      "Source": "0x749c930256b47049cb65adcd7c25e72d5de44b3b",
      "Sink": "0xde374ece6fa50e781e81aac78e811b33d16912c7",
      "TargetFlow": "99999999999999999999999999999999999"
    }
  ]
}
200

Path with flow allocations

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

SQL-like indexed query

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_query","params":[{"Namespace":"V_CrcV2","Table":"TrustRelations","Columns":[],"Filter":[{"Type":"Conjunction","ConjunctionType":"Or","Predicates":[{"Type":"FilterPredicate","FilterType":"Equals","Column":"truster","Value":"0xae3a29a9ff24d0e936a5579bae5c4179c4dff565"},{"Type":"FilterPredicate","FilterType":"Equals","Column":"trustee","Value":"0xae3a29a9ff24d0e936a5579bae5c4179c4dff565"}]}],"Order":[]}]}
and
Responses
200
Tabular result set
application/json
post
POST //circles_query HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 447

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_query",
  "params": [
    {
      "Namespace": "V_CrcV2",
      "Table": "TrustRelations",
      "Columns": [],
      "Filter": [
        {
          "Type": "Conjunction",
          "ConjunctionType": "Or",
          "Predicates": [
            {
              "Type": "FilterPredicate",
              "FilterType": "Equals",
              "Column": "truster",
              "Value": "0xae3a29a9ff24d0e936a5579bae5c4179c4dff565"
            },
            {
              "Type": "FilterPredicate",
              "FilterType": "Equals",
              "Column": "trustee",
              "Value": "0xae3a29a9ff24d0e936a5579bae5c4179c4dff565"
            }
          ]
        }
      ],
      "Order": []
    }
  ]
}
200

Tabular result set

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Stream / log event query

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_events","params":["0xde374ece6fa50e781e81aac78e811b33d16912c7",38000000,null,["CrcV1_Trust"],null,false]}
and
Responses
200
Array of event objects
application/json
post
POST //circles_events HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 147

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_events",
  "params": [
    "0xde374ece6fa50e781e81aac78e811b33d16912c7",
    38000000,
    null,
    [
      "CrcV1_Trust"
    ],
    null,
    false
  ]
}
200

Array of event objects

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

System health probe

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_health","params":[]}
and
Responses
200
Health status
application/json
post
POST //circles_health HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 62

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_health",
  "params": []
}
200

Health status

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

List namespaces & tables

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":0,"method":"circles_tables","params":[]}
and
Responses
200
Namespace/table catalogue
application/json
post
POST //circles_tables HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 62

{
  "jsonrpc": "2.0",
  "id": 0,
  "method": "circles_tables",
  "params": []
}
200

Namespace/table catalogue

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Batch avatar metadata

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getAvatarInfoBatch","params":[["0xde374ece6fa50e781e81aac78e811b33d16912c7"]]}
and
Responses
200
Array of avatar objects
application/json
post
POST //circles_getAvatarInfoBatch HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 120

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getAvatarInfoBatch",
  "params": [
    [
      "0xde374ece6fa50e781e81aac78e811b33d16912c7"
    ]
  ]
}
200

Array of avatar objects

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Profile by CID

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getProfileByCid","params":["Qmb2s3hjxXXcFqWvDDSPCd1fXXa9gcFJd8bzdZNNAvk9W"]}
and
Responses
200
Profile data
application/json
post
POST //circles_getProfileByCid HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 118

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getProfileByCid",
  "params": [
    "Qmb2s3hjxXXcFqWvDDSPCd1fXXa9gcFJd8bzdZNNAvk9W"
  ]
}
200

Profile data

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Profiles by CID (batch)

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getProfileByCidBatch","params":[["Qmb2s3hjxXXcFqWvDDSPCd1fXXa9gcFJd8bzdZNNAvk9W",null,"QmZuR1Jkhs9RLXVY28eTTRSnqbxLTBSoggp18Yde858xCM","QmanRNbDjbiSFdxcYT9S9wpk3gaCVnM81MVAHkmJj6AqE5"]]}
and
Responses
200
Array of profiles / nulls
application/json
post
POST //circles_getProfileByCidBatch HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 228

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getProfileByCidBatch",
  "params": [
    [
      "Qmb2s3hjxXXcFqWvDDSPCd1fXXa9gcFJd8bzdZNNAvk9W",
      null,
      "QmZuR1Jkhs9RLXVY28eTTRSnqbxLTBSoggp18Yde858xCM",
      "QmanRNbDjbiSFdxcYT9S9wpk3gaCVnM81MVAHkmJj6AqE5"
    ]
  ]
}
200

Array of profiles / nulls

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Profile by avatar address

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getProfileByAddress","params":["0x5d033356cf431207ac72f3b48a86db0ebbcd6fdf"]}
and
Responses
200
Profile object or null
application/json
post
POST //circles_getProfileByAddress HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 119

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getProfileByAddress",
  "params": [
    "0x5d033356cf431207ac72f3b48a86db0ebbcd6fdf"
  ]
}
200

Profile object or null

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Profiles by address (batch)

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getProfileByAddressBatch","params":[["0x5d033356cf431207ac72f3b48a86db0ebbcd6fdf","0x0e50fc4e7d629bc5edd69b6dddb3c22c6e60704b","0xf712d3b31de494b5c0ea51a6a407460ca66b12e8",null,"0xde374ece6fa50e781e81aac78e811b33d16912c7","0xde374ece6fa50e781e81aac78e811b33d16912c7"]]}
and
Responses
200
Array of profile objects / nulls
application/json
post
POST //circles_getProfileByAddressBatch HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 311

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getProfileByAddressBatch",
  "params": [
    [
      "0x5d033356cf431207ac72f3b48a86db0ebbcd6fdf",
      "0x0e50fc4e7d629bc5edd69b6dddb3c22c6e60704b",
      "0xf712d3b31de494b5c0ea51a6a407460ca66b12e8",
      null,
      "0xde374ece6fa50e781e81aac78e811b33d16912c7",
      "0xde374ece6fa50e781e81aac78e811b33d16912c7"
    ]
  ]
}
200

Array of profile objects / nulls

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Download full trust & balance snapshot

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_getNetworkSnapshot","params":[]}
and
Responses
200
Snapshot archive / manifest
application/json
post
POST //circles_getNetworkSnapshot HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 74

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_getNetworkSnapshot",
  "params": []
}
200

Snapshot archive / manifest

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}

Text search over profiles

post
Body
all ofOptionalExample: {"jsonrpc":"2.0","id":1,"method":"circles_searchProfiles","params":["Ben",10,0]}
and
Responses
200
Paged profile search hits
application/json
post
POST //circles_searchProfiles HTTP/1.1
Host: rpc.aboutcircles.com
Content-Type: application/json
Accept: */*
Content-Length: 80

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "circles_searchProfiles",
  "params": [
    "Ben",
    10,
    0
  ]
}
200

Paged profile search hits

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}