Skip to content

Commit

Permalink
Merge pull request #21 from aboutcircles/jaensen/crc-253-profile-supp…
Browse files Browse the repository at this point in the history
…ort-1155-metadata-json-on-ipfs

jaensen/crc 253 profile support 1155 metadata json on ipfs
  • Loading branch information
jaensen authored Aug 3, 2024
2 parents f592e4b + 0745601 commit 74fcc38
Show file tree
Hide file tree
Showing 36 changed files with 857 additions and 191 deletions.
51 changes: 36 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
"packages/abi-v2",
"packages/sdk",
"packages/data",
"packages/utils"
"packages/utils",
"packages/profiles"
],
"scripts": {
"test": "jest",
"build": "./generateCode.sh && npm run build -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/utils -w @circles-sdk/data -w @circles-sdk/sdk",
"publish": "npm run build && npm publish -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/data -w @circles-sdk/utils -w @circles-sdk/sdk",
"publish:dry-run": "npm run build && npm publish --dry-run -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/data -w @circles-sdk/sdk -w @circles-sdk/utils"
"build": "./generateCode.sh && npm run build -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/utils -w @circles-sdk/data -w @circles-sdk/profiles -w @circles-sdk/sdk",
"publish": "npm run build && npm publish -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/utils -w @circles-sdk/data -w @circles-sdk/profiles -w @circles-sdk/sdk",
"publish:dry-run": "npm run build && npm publish --dry-run -w @circles-sdk/abi-v1 -w @circles-sdk/abi-v2 -w @circles-sdk/utils -w @circles-sdk/data -w @circles-sdk/profiles -w @circles-sdk/sdk"
},
"devDependencies": {
"@rollup/plugin-json": "^6.1.0",
Expand All @@ -30,5 +31,5 @@
},
"name": "@cirlces-sdk/root",
"license": "MIT",
"version": "0.4.0"
"version": "0.5.0-preview-2"
}
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.4.0",
"version": "0.5.0-preview-2",
"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.4.0",
"version": "0.5.0-preview-2",
"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.4.0",
"version": "0.5.0-preview-2",
"description": "",
"type": "module",
"main": "./dist/index.js",
Expand All @@ -17,7 +17,7 @@
"build": "rollup -c"
},
"dependencies": {
"@circles-sdk/utils": "0.4.0"
"@circles-sdk/utils": "0.5.0-preview-2"
},
"keywords": [],
"author": "",
Expand Down
94 changes: 72 additions & 22 deletions packages/data/src/circlesData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TrustListRow } from './rows/trustListRow';
import { TokenBalanceRow } from './rows/tokenBalanceRow';
import { CirclesRpc } from './circlesRpc';
import { AvatarRow } from './rows/avatarRow';
import { crcToTc } from '@circles-sdk/utils';
import { crcToTc, hexStringToUint8Array, uint8ArrayToCidV0 } from '@circles-sdk/utils';
import { ethers } from 'ethers';
import { TrustRelation, TrustRelationRow } from './rows/trustRelationRow';
import { CirclesDataInterface, GroupQueryParams } from './circlesDataInterface';
Expand All @@ -16,6 +16,7 @@ import { Filter } from './rpcSchema/filter';
import { GroupMembershipRow } from './rows/groupMembershipRow';
import { GroupRow } from './rows/groupRow';
import { TokenInfoRow } from './rows/tokenInfoRow';
import { parseRpcSubscriptionMessage, RcpSubscriptionEvent } from './events/parser';

export class CirclesData implements CirclesDataInterface {
readonly rpc: CirclesRpc;
Expand Down Expand Up @@ -112,7 +113,7 @@ export class CirclesData implements CirclesDataInterface {
]
}, [{
name: 'timeCircles',
generator: (row: TransactionHistoryRow) => {
generator: async (row: TransactionHistoryRow) => {
if (row.version === 1) {
const timestamp = new Date(row.timestamp * 1000);
return crcToTc(timestamp, BigInt(row.value)).toFixed(2);
Expand All @@ -122,7 +123,7 @@ export class CirclesData implements CirclesDataInterface {
}
}, {
name: 'tokenAddress',
generator: (row: TransactionHistoryRow) => {
generator: async (row: TransactionHistoryRow) => {
// If the id isset, doesn't start with 0x and only consists of digits, it's a BigInt that
// needs to be converted to a ethereum address. The BigInt is actually an encoded byte[20]
// that represents the address.
Expand Down Expand Up @@ -244,8 +245,23 @@ export class CirclesData implements CirclesDataInterface {
* Gets basic information about an avatar.
* This includes the signup timestamp, circles version, avatar type and token address/id.
* @param avatar The address to check.
* @returns The avatar info or undefined if the avatar is not found.
*/
async getAvatarInfo(avatar: string): Promise<AvatarRow | undefined> {
const avatarInfos = await this.getAvatarInfos([avatar]);
return avatarInfos.length > 0 ? avatarInfos[0] : undefined;
}

/**
* Gets basic information about multiple avatars.
* @param avatars The addresses to check.
* @returns An array of avatar info objects.
*/
async getAvatarInfos(avatars: string[]): Promise<AvatarRow[]> {
if (avatars.length === 0) {
return [];
}

const circlesQuery = new CirclesQuery<AvatarRow>(this.rpc, {
namespace: 'V_Crc',
table: 'Avatars',
Expand All @@ -264,39 +280,58 @@ export class CirclesData implements CirclesDataInterface {
filter: [
{
Type: 'FilterPredicate',
FilterType: 'Equals',
FilterType: 'In',
Column: 'avatar',
Value: avatar.toLowerCase()
Value: avatars.map(a => a.toLowerCase())
}
],
sortOrder: 'ASC',
limit: 1000
});
}, [{
name: 'cidV0',
generator: async (row: AvatarRow) => {
try {
if (!row.cidV0Digest) {
return undefined;
}

const dataFromHexString = hexStringToUint8Array(row.cidV0Digest.substring(2));
return uint8ArrayToCidV0(dataFromHexString);
} catch (error) {
console.error('Failed to convert cidV0Digest to CIDv0 string:', error);
return undefined;
}
}
}]);

if (!await circlesQuery.queryNextPage()) {
return undefined;
const results: AvatarRow[] = [];

while (await circlesQuery.queryNextPage()) {
const resultRows = circlesQuery.currentPage?.results ?? [];
if (resultRows.length === 0) break;
results.push(...resultRows);
if (resultRows.length < 1000) break;
}

const result = circlesQuery.currentPage?.results ?? [];
let returnValue: AvatarRow | undefined = undefined;
const avatarMap: { [key: string]: AvatarRow } = {};

for (const avatarRow of result) {
if (returnValue === undefined) {
returnValue = avatarRow;
results.forEach(avatarRow => {
if (!avatarMap[avatarRow.avatar]) {
avatarMap[avatarRow.avatar] = avatarRow;
}

if (avatarRow.version === 1) {
returnValue.hasV1 = true;
returnValue.v1Token = avatarRow.tokenId;
avatarMap[avatarRow.avatar].hasV1 = true;
avatarMap[avatarRow.avatar].v1Token = avatarRow.tokenId;
} else {
returnValue = {
...returnValue,
avatarMap[avatarRow.avatar] = {
...avatarMap[avatarRow.avatar],
...avatarRow
};
}
}
});

return returnValue;
return avatars.map(avatar => avatarMap[avatar.toLowerCase()]).filter(row => row !== undefined);
}

/**
Expand Down Expand Up @@ -342,6 +377,20 @@ export class CirclesData implements CirclesDataInterface {
return this.rpc.subscribe(avatar);
}

/**
* Gets the events for a given avatar in a block range.
* @param avatar The avatar to get the events for.
* @param fromBlock The block number to start from.
* @param toBlock The block number to end at. If not provided, the latest block is used.
*/
async getEvents(avatar: string, fromBlock: number, toBlock?: number): Promise<CirclesEvent[]> {
const response = await this.rpc.call<RcpSubscriptionEvent[]>(
'circles_events',
[avatar, fromBlock, toBlock]
);
return parseRpcSubscriptionMessage(response.result);
}

/**
* Gets the invitations sent by an avatar.
* @param avatar The avatar to get the invitations for.
Expand Down Expand Up @@ -413,8 +462,8 @@ export class CirclesData implements CirclesDataInterface {
*/
findGroups(pageSize: number, params?: GroupQueryParams): CirclesQuery<GroupRow> {
const queryDefintion: PagedQueryParams = {
namespace: 'CrcV2',
table: 'RegisterGroup',
namespace: 'V_CrcV2',
table: 'Groups',
columns: [
'blockNumber',
'timestamp',
Expand All @@ -425,7 +474,8 @@ export class CirclesData implements CirclesDataInterface {
'mint',
'treasury',
'name',
'symbol'
'symbol',
'cidV0Digest',
],
sortOrder: 'DESC',
limit: pageSize
Expand Down
4 changes: 4 additions & 0 deletions packages/data/src/circlesQueryRpcResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type CirclesQueryRpcResult = {
columns: string[];
rows: any[][];
};
10 changes: 0 additions & 10 deletions packages/data/src/circlesRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,4 @@ export class CirclesRpc {
// TODO: Add unsubscribe method to observable
return observable.property;
}
}

export type CirclesQueryRpcResult = {
columns: string[];
rows: any[][];
};

export type RawWebsocketEvent = {
event: string;
values: Record<string, any>;
}
6 changes: 4 additions & 2 deletions packages/data/src/events/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ type EventValues = {
[key: string]: string;
};

type RpcSubscriptionMessage = Array<{
export type RcpSubscriptionEvent = {
event: string;
values: EventValues;
}>;
};

type RpcSubscriptionMessage = RcpSubscriptionEvent[];

const hexToBigInt = (hex: string): bigint => BigInt(hex);
const hexToNumber = (hex: string): number => parseInt(hex, 16);
Expand Down
Loading

0 comments on commit 74fcc38

Please sign in to comment.