Skip to content

Commit

Permalink
0.3.3:
Browse files Browse the repository at this point in the history
* add profile cid to avatarRow
* add CirclesData.getTokenInfo()
* add Avatar.updateMetadata() to update the profile
  • Loading branch information
jaensen committed Jul 3, 2024
1 parent 184a8e6 commit 29cbcca
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/abi-v1/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@circles-sdk/abi-v1",
"version": "0.3.0",
"version": "0.3.3",
"description": "",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/abi-v2/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@circles-sdk/abi-v2",
"version": "0.3.0",
"version": "0.3.3",
"description": "",
"type": "module",
"main": "./dist/index.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/data/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@circles-sdk/data",
"version": "0.3.0",
"version": "0.3.3",
"description": "",
"type": "module",
"main": "./dist/index.js",
Expand All @@ -17,7 +17,7 @@
"build": "rollup -c"
},
"dependencies": {
"@circles-sdk/utils": "0.3.0"
"@circles-sdk/utils": "0.3.3"
},
"keywords": [],
"author": "",
Expand Down
43 changes: 42 additions & 1 deletion packages/data/src/circlesData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { PagedQueryParams } from './pagedQuery/pagedQueryParams';
import { Filter } from './rpcSchema/filter';
import { GroupMembershipRow } from './rows/groupMembershipRow';
import { GroupRow } from './rows/groupRow';
import { TokenInfoRow } from './rows/tokenInfoRow';

export class CirclesData implements CirclesDataInterface {
readonly rpc: CirclesRpc;
Expand Down Expand Up @@ -183,6 +184,10 @@ export class CirclesData implements CirclesDataInterface {
});
}

/**
* Gets all trust relations of an avatar and groups mutual trust relations together.
* @param avatarAddress The address to get the trust relations for.
*/
async getAggregatedTrustRelations(avatarAddress: string): Promise<TrustRelationRow[]> {
const pageSize = 1000;
const trustsQuery = this.getTrustRelations(avatarAddress, pageSize);
Expand Down Expand Up @@ -253,7 +258,8 @@ export class CirclesData implements CirclesDataInterface {
'version',
'type',
'avatar',
'tokenId'
'tokenId',
'cidV0Digest'
],
filter: [
{
Expand Down Expand Up @@ -293,6 +299,41 @@ export class CirclesData implements CirclesDataInterface {
return returnValue;
}

/**
* Gets the token info for a given token address.
* @param address The address of the token.
* @returns The token info or undefined if the token is not found.
*/
async getTokenInfo(address: string): Promise<TokenInfoRow | undefined> {
const circlesQuery = new CirclesQuery<TokenInfoRow>(this.rpc, {
namespace: 'V_Crc',
table: 'Avatars',
columns: [
'blockNumber',
'timestamp',
'transactionIndex',
'logIndex',
'transactionHash',
'version',
'type',
'avatar',
'tokenId'
],
filter: [
{
Type: 'FilterPredicate',
FilterType: 'Equals',
Column: 'tokenId',
Value: address.toLowerCase()
}
],
sortOrder: 'ASC',
limit: 1
});

return await circlesQuery.getSingleRow();
}

/**
* Subscribes to Circles events.
* @param avatar The avatar to subscribe to. If not provided, all events are subscribed to.
Expand Down
8 changes: 8 additions & 0 deletions packages/data/src/circlesDataInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CirclesEvent } from './events/events';
import { InvitationRow } from './rows/invitationRow';
import { GroupRow } from './rows/groupRow';
import { GroupMembershipRow } from './rows/groupMembershipRow';
import { TokenInfoRow } from './rows/tokenInfoRow';

export interface GroupQueryParams {
nameStartsWith?: string;
Expand All @@ -26,6 +27,13 @@ export interface CirclesDataInterface {
*/
getAvatarInfo(avatar: string): Promise<AvatarRow | undefined>;

/**
* Gets the token info for a given token address.
* @param address The address of the token.
* @returns The token info or undefined if the token is not found.
*/
getTokenInfo(address: string): Promise<TokenInfoRow | undefined>;

/**
* Gets the total CRC v1 balance of an address.
* @param avatar The address to get the CRC balance for.
Expand Down
48 changes: 44 additions & 4 deletions packages/data/src/rows/avatarRow.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,55 @@
import { EventRow } from '../pagedQuery/eventRow';

/**
* Contains basic information about a Circles avatar.
*/
export interface AvatarRow extends EventRow {
/**
* The timestamp of the last change to the avatar.
*/
timestamp: number;
/**
* The hash of the transaction that last changed the avatar.
*/
transactionHash: string;
/**
* If the avatar is currently active in version 1 or 2.
*
* Note: An avatar that's active in v2 can still have a v1 token. See `hasV1` and `v1Token`.
*/
version: number;
type: string;
/**
* The type of the avatar.
*/
type: 'human' | 'organization' | 'group';
/**
* The address of the avatar.
*/
avatar: string;
tokenId: string;
/**
* The personal or group token address.
*
* Note: v1 tokens are erc20 and thus have a token address. v2 tokens are erc1155 and have a tokenId.
* The v2 tokenId is always an encoded version of the avatar address.
*/
tokenId?: string;
/**
* If the avatar is signed up at v1.
*/
hasV1: boolean;
v1Token: string;
/**
* If the avatar has a v1 token, this is the token address.
*/
v1Token?: string;
/**
* The CIDv0 of the avatar's metadata (profile).
*/
cidV0Digest?: string;

// Currently only set in avatar initialization
/**
* If the avatar is stopped in v1.
*
* Note: This is only set during `Avatar` initialization.
*/
v1Stopped?: boolean;
}
10 changes: 10 additions & 0 deletions packages/data/src/rows/tokenInfoRow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EventRow } from '../pagedQuery/eventRow';

export interface TokenInfoRow extends EventRow {
timestamp: number;
transactionHash: string;
version: number;
type: "human" | "group";
avatar: string;
tokenId: string;
}
8 changes: 4 additions & 4 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@circles-sdk/sdk",
"version": "0.3.0",
"version": "0.3.3",
"description": "",
"type": "module",
"main": "./dist/index.js",
Expand All @@ -17,9 +17,9 @@
"author": "",
"license": "ISC",
"dependencies": {
"@circles-sdk/abi-v1": "0.3.0",
"@circles-sdk/abi-v2": "0.3.0",
"@circles-sdk/data": "0.3.0",
"@circles-sdk/abi-v1": "0.3.3",
"@circles-sdk/abi-v2": "0.3.3",
"@circles-sdk/data": "0.3.3",
"ethers": "^6.11.1",
"multihashes": "^4.0.3"
},
Expand Down
6 changes: 6 additions & 0 deletions packages/sdk/src/AvatarInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,10 @@ export interface AvatarInterfaceV2 extends AvatarInterface {
* @param avatar The avatar's avatar.
*/
inviteHuman(avatar: string): Promise<ContractTransactionReceipt>;

/**
* Updates the avatar's metadata (profile).
* @param cid The IPFS CID of the metadata.
*/
updateMetadata(cid: string): Promise<ContractTransactionReceipt>;
}
90 changes: 90 additions & 0 deletions packages/sdk/src/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,28 @@ export class Avatar implements AvatarInterfaceV2 {
private _avatarInfo: AvatarRow | undefined;
private _sdk: Sdk;

/**
* After initialization, this property contains the avatar's basic information.
*/
get avatarInfo(): AvatarRow | undefined {
return this._avatarInfo;
}

private _tokenEventSubscription?: () => void = undefined;

/**
* Creates a new Avatar instance that controls a Circles avatar at the given address.
* @param sdk The SDK instance to use.
* @param avatarAddress The address of the avatar to control.
*/
constructor(sdk: Sdk, avatarAddress: string) {
this.address = avatarAddress.toLowerCase();
this._sdk = sdk;
}

/**
* The events observable for this avatar.
*/
public get events(): Observable<CirclesEvent> {
if (!this._events) {
throw new Error('Not initialized');
Expand Down Expand Up @@ -104,18 +115,97 @@ export class Avatar implements AvatarInterfaceV2 {
return func(<AvatarInterfaceV2>this._avatar);
}

/**
* `human` avatars can mint 24 personal Circles per day. This method returns the amount of Circles that can be minted.
*
* Note: v2 avatars can mint at max. 14 days * 24 Circles = 336 Circles.
* v1 avatars on the other hand will stop minting after 90 days without minting.
* @returns The amount of Circles that can be minted.
*/
getMintableAmount = (): Promise<bigint> => this.onlyIfInitialized(() => this._avatar!.getMintableAmount());
/**
* Mints the available personal Circles for the avatar. Check `getMintableAmount()` to see how many Circles can be minted.
* @returns The transaction receipt.
*/
personalMint = (): Promise<ContractTransactionReceipt> => this.onlyIfInitialized(() => this._avatar!.personalMint());
/**
* Stops the avatar's token. This will prevent any future `personalMint()` calls and is not reversible.
*/
stop = (): Promise<ContractTransactionReceipt> => this.onlyIfInitialized(() => this._avatar!.stop());
/**
* Utilizes the pathfinder to find the maximum Circles amount that can be transferred from this Avatar to the other avatar.
* @param to The address to transfer the Circles to.
* @returns The maximum Circles amount that can be transferred.
*/
getMaxTransferableAmount = (to: string): Promise<bigint> => this.onlyIfInitialized(() => this._avatar!.getMaxTransferableAmount(to));
/**
* Transfers Circles to another avatar.
*
* Note: The max. transferable amount can be lower than the avatar's balance depending on its trust relations and token holdings.
* Use the `getMaxTransferableAmount()` method to calculate the max. transferable amount if you need to know it beforehand.
* @param to The address of the avatar to transfer to.
* @param amount The amount to transfer.
*/
transfer = (to: string, amount: bigint): Promise<ContractTransactionReceipt> => this.onlyIfInitialized(() => this._avatar!.transfer(to, amount));
/**
* Trusts another avatar. Trusting an avatar means you're willing to accept Circles that have been issued by this avatar.
* @param avatar The address of the avatar to trust.
* @returns The transaction receipt.
*/
trust = (avatar: string): Promise<ContractTransactionReceipt> => this.onlyIfInitialized(() => this._avatar!.trust(avatar));
/**
* Revokes trust from another avatar. This means you will no longer accept Circles issued by this avatar. This will not affect already received Circles.
* @param avatar The address of the avatar to untrust.
* @returns The transaction receipt.
*/
untrust = (avatar: string): Promise<ContractTransactionReceipt> => this.onlyIfInitialized(() => this._avatar!.untrust(avatar));
/**
* Gets the trust relations of the avatar.
* @returns An array of trust relations in this form: avatar1 - [trusts|trustedBy|mutuallyTrusts] -> avatar2.
*/
getTrustRelations = (): Promise<TrustRelationRow[]> => this.onlyIfInitialized(() => this._avatar!.getTrustRelations());
/**
* Gets the Circles transaction history of the avatar. The history contains incoming/outgoing transactions and minting of personal Circles and Group Circles.
* @param pageSize The maximum number of transactions per page.
* @returns A query object that can be used to iterate over the transaction history.
*/
getTransactionHistory = (pageSize: number): Promise<CirclesQuery<TransactionHistoryRow>> => this.onlyIfInitialized(() => this._avatar!.getTransactionHistory(pageSize));
/**
* Gets the avatar's total Circles balance.
*
* Note: This queries either the v1 or the v2 balance of an avatar. Check the `avatarInfo` property to see which version your avatar uses.
* Token holdings in v1 can be migrated to v2. Check out `Sdk.migrateAvatar` or `Sdk.migrateAllV1Tokens` for more information.
*/
getTotalBalance = (): Promise<number> => this.onlyIfInitialized(() => this._avatar!.getTotalBalance());
/**
* Use collateral, trusted by the group, to mint new Group Circles.
* @param group The group which Circles to mint.
* @param collateral The collateral tokens to use for minting.
* @param amounts The amounts of the collateral tokens to use.
* @param data Additional data for the minting operation.
* @returns The transaction receipt.
*/
groupMint = (group: string, collateral: string[], amounts: bigint[], data: Uint8Array): Promise<ContractTransactionReceipt> => this.onlyIfV2((avatar) => avatar.groupMint(group, collateral, amounts, data));
/**
* Wraps the specified amount of personal Circles into demurraged ERC20 tokens for use outside the Circles protocol.
* Note: This kind of token can be incompatible with services since it's demurraged and thus the balance changes over time.
* @param amount The amount of Circles to wrap.
*/
wrapDemurrageErc20 = (amount: bigint): Promise<ContractTransactionReceipt> => this.onlyIfV2((avatar) => avatar.wrapDemurrageErc20(amount));
/**
* Wraps the specified amount of inflation Circles into ERC20 tokens for use outside the Circles protocol.
* In contrast to demurraged tokens, these token's balance does not change over time.
* @param amount
*/
wrapInflationErc20 = (amount: bigint): Promise<ContractTransactionReceipt> => this.onlyIfV2((avatar) => avatar.wrapInflationErc20(amount));
/**
* Invite a human avatar to join Circles.
* @param avatar The address of any human controlled wallet.
*/
inviteHuman = (avatar: string): Promise<ContractTransactionReceipt> => this.onlyIfV2((_avatar) => _avatar.inviteHuman(avatar));
/**
* Updates the avatar's metadata (profile).
* @param cid The IPFS content identifier of the metadata (Qm....).
*/
updateMetadata = (cid: string): Promise<ContractTransactionReceipt> => this.onlyIfV2((_avatar) => _avatar.updateMetadata(cid));
}
1 change: 1 addition & 0 deletions packages/sdk/src/chainConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export interface ChainConfig {
readonly circlesRpcUrl: string;
readonly v1HubAddress: string;
readonly v2HubAddress?: string;
readonly nameRegistryAddress?: string;
readonly migrationAddress?: string;
}
3 changes: 2 additions & 1 deletion packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export { V1Person } from './v1/v1Person';
export { ChainConfig } from './chainConfig';
export { AvatarRow, TrustListRow, TrustRelationRow } from '@circles-sdk/data';
export { AvatarInterface } from './AvatarInterface';
export { parseError } from './errors';
export { parseError } from './errors';
export { Pathfinder, TransferPath, TransferStep } from './v1/pathfinder';
Loading

0 comments on commit 29cbcca

Please sign in to comment.