Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…nto master
  • Loading branch information
andreespirela committed Jan 6, 2022
2 parents 6c963b9 + 8c8ae25 commit 715af3d
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 9 deletions.
122 changes: 122 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,128 @@ fetchRandomArtworkWithUser().then((result) => {
})
```

### Fetching random communities without full metadata

**Signature**:
`fetchRandomCommunities = async (): Promise<TokenMetadataLookUp>`

**Usage**:
```typescript
import { fetchRandomCommunities } from 'verto-cache-interface';

fetchRandomCommunities().then((result) => {
const communities = result.entities;
communities.forEach((com) => {
console.log(com.contractId);
console.log(com.type);
console.log(com.lister);
console.log(com.id);
})
})
```

### Fetching random communities with full metadata

**Signature**:
`fetchRandomCommunitiesWithMetadata = async (): Promise<Array<RandomCommunities>>`

**Usage**:
```typescript
import { fetchRandomCommunitiesWithMetadata } from 'verto-cache-interface';

fetchRandomCommunitiesWithMetadata().then((result) => {
result.forEach((com) => {
console.log(com.id);
console.log(com.name);
console.log(com.ticker);
console.log(com.logo);
console.log(com.description);
})
})
```

### Fetching top communities with full metadata

**Signature**:
`fetchTopCommunities = async (): Promise<Array<RandomCommunities>>`

**Usage**:
```typescript
import { fetchTopCommunities } from 'verto-cache-interface';

fetchTopCommunities().then((result) => {
result.forEach((com) => {
console.log(com.id);
console.log(com.name);
console.log(com.ticker);
console.log(com.logo);
console.log(com.description);
})
})
```

### Fetching full metadata for given communities

**Signature**:
`fetchCommunitiesMetadata = async (communityContractIds: Array<string> | string): Promise<Array<RandomCommunities>>`

**Usage**:
```typescript
import { fetchCommunitiesMetadata } from 'verto-cache-interface';

fetchCommunitiesMetadata(["MY-community-id1", "MY-community-id2"]).then((result) => {
result.forEach((com) => {
console.log(com.id);
console.log(com.name);
console.log(com.ticker);
console.log(com.logo);
console.log(com.description);
})
})
```

### Fetching artwork metadata

**Signature**:
`fetchArtworkMetadata = async (): Promise<ArtworkMetadata | undefined>`

**Usage**:
```typescript
import { fetchArtworkMetadata } from 'verto-cache-interface';

fetchArtworkMetadata().then((result) => {
console.log(result.id);
console.log(result.name);
console.log(result.lister); // Object (username, name, addresses, bio, links, image)
console.log(result.lister.addresses);
console.log(result.lister.bio);
console.log(result.lister.links);
})
```

### Fetching token by id and optional filtering

**Signature**:
`fetchTokenById = async (tokenId: string, filter?: (val: CommunityContractToken) => boolean): Promise<CommunityContractToken | undefined>`

**Usage**:
```typescript
import { fetchTokenById } from 'verto-cache-interface';

fetchTokenById("ABC").then((result) => {
console.log(result.id);
console.log(result.type);
console.log(result.lister);
});


fetchTokenById("ABC", (filterData) => filterData.type === "community").then((result) => {
console.log(result.id);
console.log(result.type);
console.log(result.lister);
});
```

## Hooks
Hooks are a way to invoke functions and then invoke certain behaviors inside the cache system.

Expand Down
26 changes: 26 additions & 0 deletions src/calls/fetch-artwork-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {fetchTokenMetadata} from "./fetch-token-metadata";
import {fetchUserByUsername} from "./fetch-user-by-username";
import { fetchContract } from "./fetch-contract";
import {CollectionState} from "./types/collection-state";
import {ArtworkMetadata} from "./types/artwork-metadata";

/**
* Fetches the metadata for a given artwork
* @param tokenId
*/
export const fetchArtworkMetadata = async (tokenId: string): Promise<ArtworkMetadata | undefined > => {
const fetchMetadata = await fetchTokenMetadata(tokenId, true);
if(!fetchMetadata || fetchMetadata.type.toLowerCase() !== "art") { return undefined; }

const fetchLister = await fetchUserByUsername(fetchMetadata.lister);
if(!fetchLister) { return undefined; }

const tokenContract = await fetchContract<CollectionState>(fetchMetadata.id!, false, true);
if(!tokenContract) { return undefined; }

return {
id: tokenId,
name: tokenContract.state.name,
lister: fetchLister
};
}
11 changes: 11 additions & 0 deletions src/calls/fetch-communities-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {fetchCommunityMetadata} from "./fetch-random-communities-with-metadata";

/**
* Fetches the metadata for one (string) or more (array) communities.
* This returns an array with (id, name, ticker, logo, description)
* @param communityContractIds Single string or array of string containing the ids of the community as listed in the community contract
*/
export const fetchCommunitiesMetadata = async (communityContractIds: Array<string> | string) => {
const contractIds = Array.isArray(communityContractIds) ? [...communityContractIds] : [communityContractIds];
return (await fetchCommunityMetadata(contractIds));
}
6 changes: 3 additions & 3 deletions src/calls/fetch-random-artwork.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {cacheApiBaseRequest} from "./cache-api-base-request";
import {RandomArtworkResult, TokenMetadata} from "./types/token-metadata";
import {TokenMetadataLookUp, TokenMetadata} from "./types/token-metadata";

/**
* Fetches random art work (tokens with type = 'collection' or 'art').
* @param limit Limit of results to be returned
*/
export const fetchRandomArtwork = async (limit: number = 4) => {
return (await cacheApiBaseRequest<RandomArtworkResult>(`token/artwork/random?limit=${limit}`))?.data || {
return (await cacheApiBaseRequest<TokenMetadataLookUp>(`token/artwork/random?limit=${limit}`))?.data || {
entities: [],
resultsStatus: 'NOT_FOUND'
} as RandomArtworkResult;
} as TokenMetadataLookUp;
}
40 changes: 40 additions & 0 deletions src/calls/fetch-random-communities-with-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {RandomCommunities} from "./types/community-contract-state";
import {fetchRandomCommunities} from "./fetch-random-communities";
import {fetchContract} from "./fetch-contract";

/**
* Fetches random communities with included metadata such as name, ticker, logo and description.
* @param limit
*/
export const fetchRandomCommunitiesWithMetadata = async (limit?: number): Promise<Array<RandomCommunities>> => {
const randomCommunities = await fetchRandomCommunities(limit || 4);
const lookupEntities = randomCommunities.entities;

if(randomCommunities.resultsStatus === "NOT_FOUND" || lookupEntities?.length <= 0) {
return [];
} else {
const contractIds = lookupEntities.map((item) => item.contractId);
return fetchCommunityMetadata(contractIds);
}
}

export const fetchCommunityMetadata = async (contractIds: Array<string>) => {
const communities: Array<RandomCommunities> = [];
for (const communitiesKey of contractIds) {
const contract = await fetchContract(communitiesKey, false, true);
if(contract) {
const contractState = contract.state;
const settings: Array<string> = (contractState.settings || []).flat();
const logoIndex = settings.findIndex(item => item === "communityLogo");
const descriptionIndex = settings.findIndex(item => item === "communityDescription");
communities.push({
id: communitiesKey,
name: contractState.name,
ticker: contractState.ticker,
logo: settings[logoIndex + 1],
description: settings[descriptionIndex + 1],
})
}
}
return communities;
}
13 changes: 13 additions & 0 deletions src/calls/fetch-random-communities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {cacheApiBaseRequest} from "./cache-api-base-request";
import {TokenMetadataLookUp, TokenMetadata} from "./types/token-metadata";

/**
* Fetches random communities (tokens with type = 'community').
* @param limit Limit of results to be returned
*/
export const fetchRandomCommunities = async (limit: number = 4) => {
return (await cacheApiBaseRequest<TokenMetadataLookUp>(`token/communities/random?limit=${limit}`))?.data || {
entities: [],
resultsStatus: 'NOT_FOUND'
} as TokenMetadataLookUp;
}
12 changes: 12 additions & 0 deletions src/calls/fetch-token-by-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {fetchTokens} from "./fetch-tokens";
import {CommunityContractToken} from "./types/community-contract-state";

/**
* Fetch a token given an id an optionally a predicate
* @param tokenId Id for token to look up
* @param filter Predicate for token
*/
export const fetchTokenById = async (tokenId: string, filter?: (val: CommunityContractToken) => boolean): Promise<CommunityContractToken | undefined> => {
const allTokens = await fetchTokens();
return allTokens.find((token) => token.id === tokenId && (filter ? filter(token) : true));
}
5 changes: 2 additions & 3 deletions src/calls/fetch-token-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {cacheApiBaseRequest} from "./cache-api-base-request";
import {TokenMetadata} from "./types/token-metadata";
import {fetchTokens} from "./fetch-tokens";
import {fetchTokenById} from "./fetch-token-by-id";

/**
* Returns the metadata of a token (contractId, type, lister)
Expand All @@ -9,8 +9,7 @@ import {fetchTokens} from "./fetch-tokens";
*/
export const fetchTokenMetadata = async (tokenId: string, fromContract?: boolean) => {
if(fromContract) {
const allTokens = await fetchTokens();
return allTokens.find((token) => token.id === tokenId);
return fetchTokenById(tokenId);
} else {
const getTokenMetadata = await cacheApiBaseRequest<TokenMetadata>(`token/metadata/${tokenId}`);

Expand Down
16 changes: 16 additions & 0 deletions src/calls/fetch-top-communities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {fetchTokens} from "./fetch-tokens";
import {cacheApiBaseRequest} from "./cache-api-base-request";
import {CommunityBalancesRaw} from "./types/community-contract-state";
import {LookUp} from "./types/lookup";
import {fetchCommunityMetadata} from "./fetch-random-communities-with-metadata";

/**
* Fetches the communities with the top balance amount per contract.
* Returns metadata containing: (id, name, ticker, logo, description)
* @param limit: Max to fetch
*/
export const fetchTopCommunities = async (limit?: number) => {
const cacheRequest = (await (cacheApiBaseRequest<LookUp<CommunityBalancesRaw>>(`token/communities/top?limit=${limit || 4}`)))?.data?.entities || [];
const contractIds = cacheRequest.map((item) => item.contractId);
return (await fetchCommunityMetadata(contractIds));
}
7 changes: 7 additions & 0 deletions src/calls/types/artwork-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {CommunityContractPeople} from "./community-contract-state";

export interface ArtworkMetadata {
id: string;
name: string;
lister: CommunityContractPeople;
}
13 changes: 13 additions & 0 deletions src/calls/types/community-contract-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,16 @@ export interface CommunityContractState {
people: Array<CommunityContractPeople>
tokens: Array<CommunityContractToken>;
}

export interface RandomCommunities {
id: string;
name: string;
ticker: string;
logo: string;
description: string;
}

export interface CommunityBalancesRaw {
contractId: string;
balanceLength: number;
}
6 changes: 6 additions & 0 deletions src/calls/types/lookup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {TokenMetadata} from "./token-metadata";

export interface LookUp<T = any> {
entities: Array<T>;
resultsStatus: string;
}
6 changes: 3 additions & 3 deletions src/calls/types/token-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {LookUp} from "./lookup";

export interface TokenMetadata {
contractId: string;
type: string;
lister: string;
id?: string;
}

export interface RandomArtworkResult {
entities: Array<TokenMetadata>;
resultsStatus: string;
export interface TokenMetadataLookUp extends LookUp<TokenMetadata> {
}
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@ export * from './calls/fetch-users';
export * from './calls/fetch-balance-by-username';
export * from './calls/fetch-user-by-username';
export * from './calls/fetch-random-artwork-with-user';
export * from './calls/fetch-random-communities';
export * from './calls/fetch-random-communities-with-metadata';
export * from './calls/fetch-top-communities';
export * from './calls/fetch-communities-metadata';
export * from './calls/fetch-artwork-metadata';
export * from './calls/fetch-token-by-id';
export * from './hooks/cache-contract-hook';
24 changes: 24 additions & 0 deletions src/tests/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {fetchBalancesForAddress} from "../calls/fetch-balances-for-address";
import {fetchTokenStateMetadata} from "../calls/fetch-token-state-metadata";
import {fetchBalancesByUsername} from "../calls/fetch-balance-by-username";
import {fetchRandomArtworkWithUser} from "../calls/fetch-random-artwork-with-user";
import {fetchArtworkMetadata} from "../calls/fetch-artwork-metadata";
import {fetchRandomCommunitiesWithMetadata} from "../calls/fetch-random-communities-with-metadata";
import {fetchTopCommunities} from "../calls/fetch-top-communities";

describe("API test", () => {
test("Fetch Contract", async () => {
Expand Down Expand Up @@ -145,6 +148,27 @@ describe("API test", () => {
}
expect(tokenArtwork!.owner.username).not.toBeUndefined();
});

test("Fetch artwork metadata", async () => {
const artworkMetadata = await fetchArtworkMetadata("oanaZYYB7DmWFPb2fFOxSJA1Xy7ffu1msId2Ii7olqM");
expect(artworkMetadata).toStrictEqual({"id":"oanaZYYB7DmWFPb2fFOxSJA1Xy7ffu1msId2Ii7olqM","name":"ArCoNFT-01 Edition 43","lister":{"username":"t8","name":"Tate Berenbaum","addresses":["pvPWBZ8A5HLpGSEfhEmK1A3PfMgB_an8vVS6L14Hsls"],"bio":"Founder of Verto","links":{"twitter":"TateBerenbaum","github":"t8"},"image":"UGu1pI3ObS3wzdQ_GZwOr0DoWShTj4EPFgyHfDaHFgI"}});
})

test("Fetch community metadata", async () => {
const communities = await fetchRandomCommunitiesWithMetadata();
expect(communities.length).toBeGreaterThanOrEqual(4);
expect(communities[0].id).not.toBeUndefined();
expect(communities[0].name).not.toBeUndefined();
expect(communities[0].ticker).not.toBeUndefined();
})

test("Fetch top communities", async () => {
const topComs = await fetchTopCommunities();
expect(topComs.length).toBeGreaterThanOrEqual(4);
expect(topComs[0].id).not.toBeUndefined();
expect(topComs[0].name).not.toBeUndefined();
expect(topComs[0].ticker).not.toBeUndefined();
})
});


0 comments on commit 715af3d

Please sign in to comment.