forked from cerc-io/registry-sdk
Add tests for querying bond
This commit is contained in:
parent
19d5405087
commit
7fe5bcda83
@ -25,6 +25,7 @@
|
||||
"axios": "^0.26.1",
|
||||
"ethers": "^5.6.1",
|
||||
"evmosjs": "^0.2.2",
|
||||
"graphql.js": "^0.6.8",
|
||||
"is-url": "^1.2.4",
|
||||
"js-sha256": "^0.9.0",
|
||||
"ripemd160": "^2.0.2",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Registry } from './index';
|
||||
import { getConfig } from './testing/helper';
|
||||
import { getConfig, wait } from './testing/helper';
|
||||
|
||||
const { mockServer, chibaClonk: { chainId, endpoint, privateKey, accountAddress, fee } } = getConfig();
|
||||
const { mockServer, chibaClonk: { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } } = getConfig();
|
||||
|
||||
jest.setTimeout(90 * 1000);
|
||||
|
||||
@ -9,15 +9,41 @@ const bondTests = () => {
|
||||
let registry: Registry;
|
||||
let bondId1: string;
|
||||
|
||||
let bondOwner: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
registry = new Registry(endpoint, chainId);
|
||||
registry = new Registry(restEndpoint, gqlEndpoint, chainId);
|
||||
});
|
||||
|
||||
test('Create bond.', async () => {
|
||||
bondId1 = await registry.getNextBondId(accountAddress);
|
||||
expect(bondId1).toBeDefined();
|
||||
await registry.createBond({ denom: 'aphoton', amount: '100' }, accountAddress, privateKey, fee);
|
||||
await wait(5000)
|
||||
})
|
||||
|
||||
test('Get bond by ID.', async () => {
|
||||
const [bond] = await registry.getBondsByIds([bondId1]);
|
||||
expect(bond).toBeDefined();
|
||||
expect(bond.id).toBe(bondId1);
|
||||
expect(bond.balance).toHaveLength(1);
|
||||
expect(bond.balance[0]).toEqual({ type: 'aphoton', quantity: '100' });
|
||||
bondOwner = bond.owner;
|
||||
});
|
||||
|
||||
test('Query bonds.', async () => {
|
||||
const bonds = await registry.queryBonds();
|
||||
expect(bonds).toBeDefined();
|
||||
const bond = bonds.filter((bond: any) => bond.id === bondId1);
|
||||
expect(bond).toBeDefined();
|
||||
});
|
||||
|
||||
test('Query bonds by owner.', async () => {
|
||||
const bonds = await registry.queryBonds({ owner: bondOwner });
|
||||
expect(bonds).toBeDefined();
|
||||
const bond = bonds.filter((bond: any) => bond.id === bondId1);
|
||||
expect(bond).toBeDefined();
|
||||
});
|
||||
};
|
||||
|
||||
if (mockServer) {
|
||||
|
1
src/graphql.d.ts
vendored
Normal file
1
src/graphql.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module 'graphql.js'
|
30
src/index.ts
30
src/index.ts
@ -53,13 +53,17 @@ export class Registry {
|
||||
return message.log || DEFAULT_WRITE_ERROR;
|
||||
}
|
||||
|
||||
constructor(url: string, cosmosChainId = DEFAULT_CHAIN_ID) {
|
||||
if (!isUrl(url)) {
|
||||
throw new Error('Path to a registry GQL endpoint should be provided.');
|
||||
constructor(restUrl: string, gqlUrl: string, cosmosChainId = DEFAULT_CHAIN_ID) {
|
||||
if (!isUrl(restUrl)) {
|
||||
throw new Error('Path to a REST endpoint should be provided.');
|
||||
}
|
||||
|
||||
this._endpoint = url;
|
||||
this._client = new RegistryClient(url);
|
||||
if (!isUrl(gqlUrl)) {
|
||||
throw new Error('Path to a GQL endpoint should be provided.');
|
||||
}
|
||||
|
||||
this._endpoint = restUrl;
|
||||
this._client = new RegistryClient(restUrl, gqlUrl);
|
||||
|
||||
this._chain = {
|
||||
chainId: 9000,
|
||||
@ -85,7 +89,7 @@ export class Registry {
|
||||
const accountObj = account.base_account;
|
||||
|
||||
const nextSeq = parseInt(accountObj.sequence, 10) + 1;
|
||||
result = sha256(`${accountObj.address}:${accountObj.number}:${nextSeq}`);
|
||||
result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`);
|
||||
} catch (err: any) {
|
||||
const error = err[0] || err;
|
||||
throw new Error(Registry.processWriteError(error));
|
||||
@ -94,6 +98,20 @@ export class Registry {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bonds by ids.
|
||||
*/
|
||||
async getBondsByIds(ids: string[]) {
|
||||
return this._client.getBondsByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query bonds by attributes.
|
||||
*/
|
||||
async queryBonds(attributes = {}) {
|
||||
return this._client.queryBonds(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create bond.
|
||||
*/
|
||||
|
@ -1,22 +1,43 @@
|
||||
import assert from 'assert';
|
||||
import axios from 'axios';
|
||||
import graphqlClient from 'graphql.js'
|
||||
import { generateEndpointAccount, generateEndpointBroadcast, generatePostBodyBroadcast } from '@tharsis/provider';
|
||||
|
||||
import { Util } from './util';
|
||||
|
||||
/**
|
||||
* Registry
|
||||
*/
|
||||
export class RegistryClient {
|
||||
_endpoint: string
|
||||
_restEndpoint: string
|
||||
_graph: any
|
||||
|
||||
/**
|
||||
* Get query result.
|
||||
*/
|
||||
static async getResult(query: any, key: string, modifier?: (rows: any[]) => {}) {
|
||||
const result = await query;
|
||||
if (result && result[key] && result[key].length && result[key][0] !== null) {
|
||||
if (modifier) {
|
||||
return modifier(result[key]);
|
||||
}
|
||||
return result[key];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* New Client.
|
||||
* @param {string} endpoint
|
||||
* @param {object} options
|
||||
*/
|
||||
constructor(endpoint: string) {
|
||||
assert(endpoint);
|
||||
constructor(restEndpoint: string, gqlEndpoint: string) {
|
||||
assert(restEndpoint);
|
||||
|
||||
this._endpoint = endpoint;
|
||||
this._restEndpoint = restEndpoint;
|
||||
|
||||
this._graph = graphqlClient(gqlEndpoint, {
|
||||
method: 'POST',
|
||||
asJSON: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,11 +46,58 @@ export class RegistryClient {
|
||||
async getAccount(address: string) {
|
||||
assert(address);
|
||||
|
||||
let { data } = await axios.get(`${this._endpoint}${generateEndpointAccount(address)}`)
|
||||
let { data } = await axios.get(`${this._restEndpoint}${generateEndpointAccount(address)}`)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bonds by ids.
|
||||
*/
|
||||
async getBondsByIds(ids: string[]) {
|
||||
assert(ids);
|
||||
assert(ids.length);
|
||||
|
||||
const query = `query ($ids: [String!]) {
|
||||
getBondsByIds(ids: $ids) {
|
||||
id
|
||||
owner
|
||||
balance {
|
||||
type
|
||||
quantity
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const variables = {
|
||||
ids
|
||||
};
|
||||
|
||||
return RegistryClient.getResult(this._graph(query)(variables), 'getBondsByIds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get records by attributes.
|
||||
*/
|
||||
async queryBonds(attributes = {}) {
|
||||
const query = `query ($attributes: [KeyValueInput!]) {
|
||||
queryBonds(attributes: $attributes) {
|
||||
id
|
||||
owner
|
||||
balance {
|
||||
type
|
||||
quantity
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const variables = {
|
||||
attributes: Util.toGQLAttributes(attributes)
|
||||
};
|
||||
|
||||
return RegistryClient.getResult(this._graph(query)(variables), 'queryBonds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit transaction.
|
||||
*/
|
||||
@ -38,7 +106,7 @@ export class RegistryClient {
|
||||
|
||||
// Broadcast transaction.
|
||||
const { data } = await axios.post(
|
||||
`${this._endpoint}${generateEndpointBroadcast()}`,
|
||||
`${this._restEndpoint}${generateEndpointBroadcast()}`,
|
||||
tx
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
const DEFAULT_PRIVATE_KEY = '0451f0bd95c855d52e76cdc8dd06f29097b944bfef26d3455725157f9133f4e0';
|
||||
const DEFAULT_ADDRESS = 'ethm19n3je0lhuk0w9kmkftsuw4etn8lmpu3jjfayeh'
|
||||
const DEFAULT_PRIVATE_KEY = '794ce0bf3c75571416001c3415e69059aeba54038bcac8ce5b9792259e6d193b';
|
||||
const DEFAULT_ADDRESS = 'ethm10atmndy7sm46829rc3yr7cxqucgrz5e9jg58xp'
|
||||
|
||||
export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time))
|
||||
|
||||
export const getConfig = () => ({
|
||||
mockServer: process.env.MOCK_SERVER || false,
|
||||
@ -7,7 +9,8 @@ export const getConfig = () => ({
|
||||
chainId: process.env.CHIBA_CLONK_CHAIN_ID || 'ethermint_9000-1',
|
||||
privateKey: DEFAULT_PRIVATE_KEY,
|
||||
accountAddress: DEFAULT_ADDRESS,
|
||||
endpoint: process.env.CHIBA_CLONK_ENDPOINT || 'http://localhost:1317',
|
||||
restEndpoint: process.env.CHIBA_CLONK_REST_ENDPOINT || 'http://localhost:1317',
|
||||
gqlEndpoint: process.env.CHIBA_CLONK_GQL_ENDPOINT || 'http://localhost:9473/api',
|
||||
fee: {
|
||||
amount: '20',
|
||||
denom: 'aphoton',
|
||||
|
79
src/util.ts
Normal file
79
src/util.ts
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Utils
|
||||
*/
|
||||
export class Util {
|
||||
/**
|
||||
* Sorts JSON object.
|
||||
*/
|
||||
static sortJSON(object: any) {
|
||||
if (object instanceof Array) {
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
object[i] = Util.sortJSON(object[i]);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
if (typeof object !== 'object' || object === null) return object;
|
||||
|
||||
let keys = Object.keys(object);
|
||||
keys = keys.sort();
|
||||
const newObject: {[key: string]: any} = {};
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
newObject[keys[i]] = Util.sortJSON(object[keys[i]]);
|
||||
}
|
||||
return newObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshal object into gql 'attributes' variable.
|
||||
*/
|
||||
static toGQLAttributes(object: any) {
|
||||
const vars: any[] = [];
|
||||
|
||||
Object.keys(object).forEach(key => {
|
||||
let type: string = typeof object[key];
|
||||
if (object[key] === null) {
|
||||
vars.push({ key, value: { 'null': true } });
|
||||
} else if (type === 'number') {
|
||||
type = (object[key] % 1 === 0) ? 'int' : 'float';
|
||||
vars.push({ key, value: { [type]: object[key] } });
|
||||
} else if (type === 'string') {
|
||||
vars.push({ key, value: { 'string': object[key] } });
|
||||
} else if (type === 'boolean') {
|
||||
vars.push({ key, value: { 'boolean': object[key] } });
|
||||
} else if (type === 'object') {
|
||||
const nestedObject = object[key];
|
||||
if (nestedObject['/'] !== undefined) {
|
||||
vars.push({ key, value: { 'reference': { id: nestedObject['/'] } } });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshal attributes array to object.
|
||||
*/
|
||||
static fromGQLAttributes(attributes: any[] = []) {
|
||||
const res: {[key: string]: any} = {};
|
||||
|
||||
attributes.forEach(attr => {
|
||||
if (attr.value.null) {
|
||||
res[attr.key] = null;
|
||||
} else if (attr.value.json) {
|
||||
res[attr.key] = JSON.parse(attr.value.json);
|
||||
} else if (attr.value.reference) {
|
||||
// Convert GQL reference to IPLD style link.
|
||||
const ref = attr.value.reference;
|
||||
res[attr.key] = { '/': ref.id };
|
||||
} else {
|
||||
const { values, null: n, ...types } = attr.value;
|
||||
const value = Object.values(types).find(v => v !== null);
|
||||
res[attr.key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
@ -2220,6 +2220,11 @@ graceful-fs@^4.2.9:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
||||
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||
|
||||
graphql.js@^0.6.8:
|
||||
version "0.6.8"
|
||||
resolved "https://registry.yarnpkg.com/graphql.js/-/graphql.js-0.6.8.tgz#5c2e57311b5e74c6665ff9394394bc76f273542f"
|
||||
integrity sha512-y1OxsvPCfBell00yb2T1E+JQjFXzbmqDT3hsf7Ckof80DlRuQ3SrmLL7KC04Up81vlBj+l9opYJjDLf9OgMH3w==
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
|
Loading…
Reference in New Issue
Block a user