Skip to content

Commit

Permalink
Modified getStrategyHolders in Census3 and using new queue endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
marcvelmer committed Jul 5, 2024
1 parent a496a36 commit 27a2894
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 38 deletions.
73 changes: 51 additions & 22 deletions src/api/census3/strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum Census3StrategyAPIMethods {
VALIDATE_PREDICATE = '/strategies/predicate/validate',
OPERATORS = '/strategies/predicate/operators',
HOLDERS = '/strategies/{id}/holders',
HOLDERS_QUEUE = '/strategies/{id}/holders/queue/{queueId}',
}

export interface ICensus3StrategiesListResponse {
Expand All @@ -29,20 +30,6 @@ export interface ICensus3StrategiesListResponsePaginated extends ICensus3Strateg
pagination: Census3Pagination;
}

export interface ICensus3StrategyHoldersResponse {
/**
* The list of the strategy holders
*/
holders: { [key: string]: string };
}

export interface ICensus3StrategyHoldersResponsePaginated extends ICensus3StrategyHoldersResponse {
/**
* The pagination information
*/
pagination: Census3Pagination;
}

export type Census3Strategy = {
/**
* The strategy identifier
Expand Down Expand Up @@ -183,6 +170,38 @@ export interface ICensus3StrategyImportQueueResponse {
progress: number;
}

export interface ICensus3StrategyHoldersQueueResponse {
/**
* If the queue has been done
*/
done: boolean;

/**
* The error of the queue
*/
error: {
/**
* The code of the error
*/
code: number;

/**
* The string of the error
*/
error: string;
};

/**
* The list of the strategy holders
*/
data: { [key: string]: string };

/**
* The importing progress
*/
progress: number;
}

export interface ICensus3StrategyToken {
/**
* The id (address) of the token.
Expand Down Expand Up @@ -290,16 +309,26 @@ export abstract class Census3StrategyAPI extends Census3API {
*
* @param url - API endpoint URL
* @param id - The identifier of the strategy
* @param pagination - Pagination options
* @returns The queue identifier
*/
public static holders(
url: string,
id: number,
pagination?: Census3Pagination
): Promise<ICensus3StrategyHoldersResponsePaginated> {
public static holders(url: string, id: number): Promise<ICensus3QueueResponse> {
return axios
.get<ICensus3QueueResponse>(url + Census3StrategyAPIMethods.HOLDERS.replace('{id}', String(id)))
.then((response) => response.data)
.catch(this.isApiError);
}

/**
* Returns the information of the strategy holders queue
*
* @param url - API endpoint URL
* @param id - The identifier of the strategy
* @param queueId - The identifier of the strategy holders queue
*/
public static holdersQueue(url: string, id: number, queueId: string): Promise<ICensus3StrategyHoldersQueueResponse> {
return axios
.get<ICensus3StrategyHoldersResponsePaginated>(
url + Census3StrategyAPIMethods.HOLDERS.replace('{id}', String(id)) + this.serializePagination(pagination)
.get<ICensus3StrategyHoldersQueueResponse>(
url + Census3StrategyAPIMethods.HOLDERS_QUEUE.replace('{id}', String(id)).replace('{queueId}', queueId)
)
.then((response) => response.data)
.catch(this.isApiError);
Expand Down
39 changes: 29 additions & 10 deletions src/census3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,14 @@ import {
} from './api';
import invariant from 'tiny-invariant';
import { isAddress } from '@ethersproject/address';
import { TokenCensus } from './types';
import { TokenCensus, StrategyCensus } from './types';
import { delay } from './util/common';
import { Census3Pagination } from './api/census3/api';
import { StrategyCensus } from './types/census/census3/strategy';

export type Token = Omit<Census3Token, 'tags'> & { tags: string[] };
export type TokenSummary = Omit<Census3SummaryToken, 'tags'> & { tags: string[] };
export type Strategy = Census3Strategy;
export type StrategyHolder = { holder: string; weight: bigint };
export type StrategyHolders = { holders: StrategyHolder[]; pagination: Census3Pagination };
export type StrategyHolders = StrategyHolder[];
export type StrategyToken = Census3CreateStrategyToken;
export type Census3Census = ICensus3CensusResponse;
export type SupportedChain = ICensus3SupportedChain;
Expand Down Expand Up @@ -187,14 +185,35 @@ export class VocdoniCensus3Client {
* Returns the strategy holders
*
* @param id - The id of the strategy
* @param pagination - Pagination options
* @returns The list strategy holders
*/
getStrategyHolders(id: number, pagination: Census3Pagination = { pageSize: -1 }): Promise<StrategyHolders> {
return Census3StrategyAPI.holders(this.url, id, pagination).then((response) => ({
holders: Object.entries(response.holders).map(([key, value]) => ({ holder: key, weight: BigInt(value) })) ?? [],
pagination: response.pagination,
}));
getStrategyHolders(id: number): Promise<StrategyHolders> {
invariant(id, 'No id set');
const waitForQueue = (queueId: string, wait?: number, attempts?: number): Promise<StrategyHolders> => {
const waitTime = wait ?? this.queueWait?.retryTime;
const attemptsNum = attempts ?? this.queueWait?.attempts;
invariant(waitTime, 'No queue wait time set');
invariant(attemptsNum >= 0, 'No queue attempts set');

return attemptsNum === 0
? Promise.reject('Time out waiting for queue with id: ' + queueId)
: Census3StrategyAPI.holdersQueue(this.url, id, queueId).then((queue) => {
switch (true) {
case queue.done && queue.error?.code?.toString().length > 0:
return Promise.reject(new Error('Could not get the strategy holders'));
case queue.done:
return Promise.resolve(
Object.entries(queue.data).map(([key, value]) => ({ holder: key, weight: BigInt(value) })) ?? []
);
default:
return delay(waitTime).then(() => waitForQueue(queueId, waitTime, attemptsNum - 1));
}
});
};

return Census3StrategyAPI.holders(this.url, id)
.then((queueResponse) => queueResponse.queueID)
.then((queueId) => waitForQueue(queueId));
}

/**
Expand Down
9 changes: 3 additions & 6 deletions test/census3/integration/strategy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,13 @@ describe('Census3 strategies integration tests', () => {
const client = new VocdoniCensus3Client({ env: EnvOptions.DEV });
const strategies = await client.getStrategies();
if (strategies.length > 1) {
const holders = await client.getStrategyHolders(strategies[1].ID, { pageSize: 10 });
holders.holders.forEach((holder) => {
const holders = await client.getStrategyHolders(strategies[1].ID);
holders.forEach((holder) => {
expect(isAddress(holder.holder)).toBe(true);
expect(typeof holder.weight).toBe('bigint');
});
expect(holders.pagination.pageSize).toBe(10);
expect(isAddress(holders.pagination.nextCursor)).toBe(true);
expect(isAddress(holders.pagination.prevCursor)).toBe(true);
}
}, 5000);
}, 85000);
it('should return the given strategy', async () => {
const client = new VocdoniCensus3Client({ env: EnvOptions.DEV });
const strategies = await client.getStrategies();
Expand Down

0 comments on commit 27a2894

Please sign in to comment.