Skip to content

Commit

Permalink
feat: get creation token event id
Browse files Browse the repository at this point in the history
  • Loading branch information
shuffledex committed May 29, 2020
1 parent 2586be8 commit 8e15c62
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 4 deletions.
37 changes: 36 additions & 1 deletion src/Polymesh.ts
Expand Up @@ -20,7 +20,7 @@ import {
} from '~/api/procedures';
import { PolymeshError, TransactionQueue } from '~/base';
import { Context } from '~/context';
import { didsWithClaims } from '~/harvester/queries';
import { didsWithClaims, eventByIndexedArgs } from '~/harvester/queries';
import { Query } from '~/harvester/types';
import {
ClaimData,
Expand All @@ -38,6 +38,7 @@ import {
tickerToString,
valueToDid,
} from '~/utils';
import { MAX_TICKER_LENGTH } from '~/utils/constants';

/**
* Main entry point of the Polymesh SDK
Expand Down Expand Up @@ -436,6 +437,40 @@ export class Polymesh {
});
}

/**
* Retrieve the event id of the token creation transaction
*
* @param args.ticker - Security Token ticker
*/
public async getCreationTokenEventId(args: { ticker: string }): Promise<number | null> {
const {
context: { harvesterClient },
} = this;
const { ticker } = args;

let result: ApolloQueryResult<Pick<Query, 'eventByIndexedArgs'>>;
try {
result = await harvesterClient.query<Query>(
eventByIndexedArgs({
moduleId: 'asset',
eventId: 'AssetCreated',
eventArg1: ticker + '\u0000'.repeat(MAX_TICKER_LENGTH - ticker.length),
})
);
} catch (e) {
throw new PolymeshError({
code: ErrorCode.FatalError,
message: `Error in harvester query: ${e.message}`,
});
}

if (result.data.eventByIndexedArgs) {
return result.data.eventByIndexedArgs.block_id || null;
}

return null;
}

/**
* Retrieve all claims issued by the current identity
*/
Expand Down
93 changes: 92 additions & 1 deletion src/__tests__/Polymesh.ts
Expand Up @@ -7,12 +7,13 @@ import sinon from 'sinon';
import { Identity, TickerReservation } from '~/api/entities';
import { addClaims, reserveTicker, revokeClaims, transferPolyX } from '~/api/procedures';
import { TransactionQueue } from '~/base';
import { didsWithClaims } from '~/harvester/queries';
import { didsWithClaims, eventByIndexedArgs } from '~/harvester/queries';
import { IdentityWithClaims } from '~/harvester/types';
import { Polymesh } from '~/Polymesh';
import { dsMockUtils } from '~/testUtils/mocks';
import { ClaimTargets, ClaimType, SubCallback } from '~/types';
import * as utilsModule from '~/utils';
import { MAX_TICKER_LENGTH } from '~/utils/constants';

jest.mock(
'@polkadot/api',
Expand Down Expand Up @@ -470,6 +471,88 @@ describe('Polymesh Class', () => {
});
});

describe('method: getCreationTokenEventId', () => {
test('should return the event id of the token creation', async () => {
const ticker = 'SOMETICKER';
const blockId = 1234;
const variables = {
moduleId: 'asset',
eventId: 'AssetCreated',
eventArg1: ticker + '\u0000'.repeat(MAX_TICKER_LENGTH - ticker.length),
};
// eslint-disable-next-line @typescript-eslint/camelcase
const fakeResult = { block_id: blockId };

dsMockUtils.configureMocks({ contextOptions: { withSeed: true } });

const polymesh = await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountUri: '//uri',
harvester: {
link: 'someLink',
key: 'someKey',
},
});

dsMockUtils.createApolloQueryStub(eventByIndexedArgs(variables), {
eventByIndexedArgs: fakeResult,
});

const result = await polymesh.getCreationTokenEventId({ ticker });

expect(result).toEqual(blockId);
});

test('should return null if the block id does not exist or if the query result is empty', async () => {
const ticker = 'SOMETICKER';
const variables = {
moduleId: 'asset',
eventId: 'AssetCreated',
eventArg1: ticker + '\u0000'.repeat(MAX_TICKER_LENGTH - ticker.length),
};

dsMockUtils.configureMocks({ contextOptions: { withSeed: true } });

const polymesh = await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountUri: '//uri',
harvester: {
link: 'someLink',
key: 'someKey',
},
});

dsMockUtils.createApolloQueryStub(eventByIndexedArgs(variables), {});
let result = await polymesh.getCreationTokenEventId({ ticker });
expect(result).toBeNull();

dsMockUtils.createApolloQueryStub(eventByIndexedArgs(variables), {
eventByIndexedArgs: {},
});
result = await polymesh.getCreationTokenEventId({ ticker });
expect(result).toBeNull();
});

test('should throw if the harvester query fails', async () => {
dsMockUtils.configureMocks({ contextOptions: { withSeed: true } });

const polymesh = await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountUri: '//uri',
harvester: {
link: 'someLink',
key: 'someKey',
},
});

dsMockUtils.throwOnHarvesterQuery();

return expect(polymesh.getCreationTokenEventId({ ticker: 'someTicker' })).rejects.toThrow(
'Error in harvester query: Error'
);
});
});

describe('method: getIssuedClaims', () => {
test('should return a list of issued claims', async () => {
const context = dsMockUtils.getContextInstance();
Expand Down Expand Up @@ -550,6 +633,10 @@ describe('Polymesh Class', () => {
const polymesh = await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountUri: '//uri',
harvester: {
link: 'someLink',
key: 'someKey',
},
});

dsMockUtils.createApolloQueryStub(
Expand All @@ -570,6 +657,10 @@ describe('Polymesh Class', () => {
const polymesh = await Polymesh.connect({
nodeUrl: 'wss://some.url',
accountUri: '//uri',
harvester: {
link: 'someLink',
key: 'someKey',
},
});

dsMockUtils.throwOnHarvesterQuery();
Expand Down
17 changes: 16 additions & 1 deletion src/harvester/__tests__/queries.ts
@@ -1,4 +1,4 @@
import { didsWithClaims } from '../queries';
import { didsWithClaims, eventByIndexedArgs } from '../queries';

describe('didsWithClaims', () => {
test('should verify that the variables are the same that were passed to the query', () => {
Expand All @@ -17,3 +17,18 @@ describe('didsWithClaims', () => {
expect(result.variables).toEqual(variables);
});
});

describe('eventByIndexedArgs', () => {
test('should verify that the variables are the same that were passed to the query', () => {
const variables = {
moduleId: 'someModule',
eventId: 'someEvent',
eventArg0: 'someData',
};

const result = eventByIndexedArgs(variables);

expect(result.query).toBeDefined();
expect(result.variables).toEqual(variables);
});
});
38 changes: 37 additions & 1 deletion src/harvester/queries.ts
@@ -1,7 +1,7 @@
import { DocumentNode } from 'graphql';
import gql from 'graphql-tag';

import { QueryDidsWithClaimsArgs } from '~/harvester/types';
import { QueryDidsWithClaimsArgs, QueryEventsByIndexedArgsArgs } from '~/harvester/types';

export interface GraphqlQuery<VariablesType> {
query: DocumentNode;
Expand Down Expand Up @@ -53,3 +53,39 @@ export function didsWithClaims(
variables,
};
}

/**
* @hidden
*
* Get a single event by any of its indexed arguments
*/
export function eventByIndexedArgs(
variables: QueryEventsByIndexedArgsArgs
): GraphqlQuery<QueryEventsByIndexedArgsArgs> {
const query = gql`
query EventByIndexedArgsQuery(
$moduleId: String!
$eventId: String!
$eventArg0: String
$eventArg1: String
$eventArg2: String
) {
eventByIndexedArgs(
moduleId: $moduleId
eventId: $eventId
eventArg0: $eventArg0
eventArg1: $eventArg1
eventArg2: $eventArg2
) {
block_id
event_idx
extrinsic_idx
}
}
`;

return {
query,
variables,
};
}

0 comments on commit 8e15c62

Please sign in to comment.