Circles SDK interface
Sdk class
Constructor: new Sdk(config?: CirclesConfig, contractRunner?: ContractRunner)
configdefaults tocirclesConfig[100](Gnosis)contractRunnerrequired for any state-changing call (see ContractRunner below)
Top-level properties:
core: low-level contract wrappers (@aboutcircles/sdk-core)rpc: RPC client (@aboutcircles/sdk-rpc)circlesConfig: the resolved config this instance was built withsenderAddress: present when a runner is provideddata: read helpers (see CirclesData)
The IPFS profile helper is internal; use the sdk.profiles.* namespace below instead.
Sdk methods
getAvatar(address)→HumanAvatar | OrganisationAvatar | BaseGroupAvatar
Registration (sdk.register.*)
asHuman(inviter, profile)→HumanAvatarasOrganization(profile)→OrganisationAvatarasGroup(owner, service, feeCollection, initialConditions, name, symbol, profile)→BaseGroupAvatar
Profiles (sdk.profiles.*)
create(profile)→cidget(cid)→Profile | undefined
Tokens (sdk.tokens.*)
getInflationaryWrapper(address)→ wrapper address or zerogetDemurragedWrapper(address)→ wrapper address or zerogetHolders(tokenAddress, limit?)→PagedQuery<TokenHolderRow>(limitdefaults to 100)
Groups (sdk.groups.*)
getType(avatar)→ group type — not implemented; currently throwsSdkError.unsupportedOperationgetMembers(groupAddress, limit?)→PagedQuery<GroupMemberRow>(limitdefaults to 100)getCollateral(groupAddress)→TokenBalance[](group treasury balances)getHolders(groupAddress, limit?)→PagedQuery<GroupTokenHolderRow>(limitdefaults to 100)
Referrals (sdk.referrals.*)
Requires referralsServiceUrl in CirclesConfig; otherwise each call throws a config error.
store(privateKey, inviter)→void— key is validated on-chain;inviteris self-declared for dashboard visibilityretrieve(privateKey)→ referral info (public endpoint, no auth)listMine()→ referrals created by the authenticated user (requires a token provider)
CirclesData (sdk.data)
Read-only convenience interface:
getAvatar(address)→AvatarInfo | undefinedgetTrustRelations(address)→AggregatedTrustRelation[]getBalances(address)→TokenBalance[]getAllInvitations(address, minimumBalance?)→ invitations involving this address;minimumBalancefilters out inviters that can no longer cover the fee
ContractRunner (required for writes)
Minimal contract runner the SDK expects when sending transactions:
address(sender)publicClient(viem client for reads)init(): Promise<void>sendTransaction(txs: TransactionRequest[]): Promise<any>Optional:estimateGas,call,resolveName,sendBatchTransaction.
Avatar interfaces (shared across Human/Organisation/BaseGroup)
Obtained via sdk.getAvatar(address). All mutate calls require a runner.
balances
getTotal()→ total CRCgetTokenBalances()→TokenBalanceRow[]getTotalSupply()→ BigInt (not implemented for all types)
trust
add(avatar | avatar[], expiry?)remove(avatar | avatar[])isTrusting(address)/isTrustedBy(address)getAll()→AggregatedTrustRelation[]
profile
get()→Profile | undefinedupdate(profile)→cidupdateMetadata(cid)→ tx receiptregisterShortName(nonce)→ tx receipt
history
getTransactions(limit?)→PagedQuery<TransactionRow>(limitdefaults to 50; cursor-based pagination viaqueryNextPage())
transfer
direct(to, amount, tokenAddress?, txData?)→ tx receiptadvanced(to, amount, options?)→ tx receipt (pathfinding + unwrap/rewrap)getMaxAmount(to)/getMaxAmountAdvanced(to, options?)→bigint
wrap
asDemurraged(avatarAddress, amount)→ tx receiptasInflationary(avatarAddress, amount)→ tx receiptunwrapDemurraged(wrapperAddress, amount)→ tx receiptunwrapInflationary(wrapperAddress, amount)→ tx receipt
events
subscribeToEvents()→ setsavatar.eventsobservableunsubscribeFromEvents()events→ observable stream of Circles events
Human Avatar specifics
invitation
Invite flows pick their funding source automatically: free invites first (if the avatar is an eligible Gnosis Pay user), then proxy inviters, then farm quota.
getReferralCode()→{ transactions, privateKey }— invite someone who does not have a Safe yet; share the private key with theminvite(invitee)→TransactionRequest[]— invite an address that already has a Safe but is not registered in CirclesgetProxyInviters()→ProxyInviter[]— addresses that trust this avatar, are trusted by the invitation module, and hold enough balance (96 CRC per invite)getClaimableFreeInvites()→bigint— free invites claimable as an eligible Gnosis Pay user;0when not eligiblefindInvitePath(proxyInviterAddress?)→ path from this avatar to the invitation module, optionally routed through a specific proxy invitercomputeAddress(signer)→Address— deterministic CREATE2 Safe address for a signer (synchronous)generateReferrals(count)→{ secrets, signers, transactionReceipt }— batch referrals via the InvitationFarmgetQuota()→bigint— remaining farm invite quotagetInvitationFee()→bigint— invitation fee (96 CRC)getInvitationModule()→Address— invitation module address from the farmlistReferrals(limit?, offset?)→ReferralPreviewList— referrals created by this avatar (limitdefaults to 10,offsetto 0)
group (memberships)
getGroupMemberships(limit?)→PagedQuery<GroupMembershipRow>— groups this avatar belongs to (limitdefaults to 50)getGroupMembershipsWithDetails(limit?)→GroupRow[]— same, enriched with name, symbol, owner, treasury, mint handler and member countproperties— alias ofgroupToken.propertiesbelow
personalToken
getMintableAmount()→{ amount, startPeriod, endPeriod }(mintable CRC + issuance window)mint()→ tx receiptstop()→ tx receipt (irreversible)
groupToken (Human / Organisation)
mint(group, amount)→ pathfound transfer to mint handlergetMaxMintableAmount(group)→bigintredeem(group, amount)→ tx receipt (automatic redemption)properties.owner(group)/properties.mintHandler(group)/properties.treasury(group)/properties.service(group)/properties.feeCollection(group)/properties.getMembershipConditions(group)— read-only (no setters on Human/Organisation)
Organisation Avatar specifics
Same groupToken surface as HumanAvatar; lacks personal minting and the invitation namespace. Its group namespace only aliases groupToken.properties — the membership queries (getGroupMemberships) are Human-only.
BaseGroup Avatar specifics
BaseGroup avatars do not expose a groupToken namespace. They manage their own group through no-arg getters and owner-only setters:
properties (read-only, for this group)
owner()/mintHandler()/service()/feeCollection()getMembershipConditions()→Address[]
setProperties (owner-only writes)
owner(newOwner)→ tx receiptservice(newService)→ tx receiptfeeCollection(newFeeCollection)→ tx receiptmembershipCondition(condition, enabled)→ tx receipt
trust (group-specific addition)
addBatchWithConditions(members, expiry?)→ tx receipt (validates members against membership conditions before trusting)
Notes
Base Groups are the group type the SDK models directly. Other, custom group implementations are possible on the protocol — they use their own mint policies and are not covered by the
BaseGroupAvatarsurface described here.Provide a
ContractRunnerfor any write call; you can useSafeBrowserRunner/SafeContractRunneror your own viem-based runner.Pathfinding options for transfers mirror
FindPathParams(useWrappedBalances, token include/exclude lists,maxTransfers,simulatedBalances, etc.).
Last updated
Was this helpful?