Use GQL query getAccounts instead of REST API

This commit is contained in:
nabarun 2022-04-22 15:45:47 +05:30 committed by Ashwin Phatak
parent 349bc650d9
commit 003cfcbf5c
7 changed files with 127 additions and 121 deletions

View File

@ -67,7 +67,7 @@ Follow these steps to run the tests:
- Run tests:
```bash
yarn test:expiry
yarn test:nameservice-expiry
```
## Development
@ -76,11 +76,15 @@ Follow these steps to run the tests:
## Known Issues
- [Util](./src/util.ts) `getContentId` method does not generate same CID compared to that in chiba-clonk.
- Passing a float type value in [watcher attributes](./src/testing/data/watcher.yml) throws error when sending setRecord message.
- Passing a float type value in [watcher attributes](./src/testing/data/watcher.yml) throws error when sending `setRecord` message.
```
failed to execute message; message index: 0: Invalid signature.: unauthorized
```
- When sending setRecord message, an integer value passed in watcher attributes is parsed as float type in chiba-clonk while [unmarshalling json](https://pkg.go.dev/encoding/json#Unmarshal).
- When sending `setRecord` message, an integer value passed in watcher attributes is parsed as float type in chiba-clonk while [unmarshalling json](https://pkg.go.dev/encoding/json#Unmarshal).
- `setRecord` message throws error when fileds in [Record](./src/types.ts) message are not assigned.
```
failed to pack and hash typedData primary type: provided data '<nil>' doesn't match type 'string' [tharsis/ethermint/ethereum/eip712/eip712.go:33]
```
Passing dummy values to work around issue.

View File

@ -43,7 +43,7 @@
"scripts": {
"test": "jest --runInBand --verbose",
"test:auctions": "TEST_AUCTIONS_ENABLED=1 jest --runInBand --verbose src/auction.test.ts",
"test:expiry": "TEST_NAMESERVICE_EXPIRY=1 jest --runInBand --verbose src/nameservice-expiry.test.ts",
"test:nameservice-expiry": "TEST_NAMESERVICE_EXPIRY=1 jest --runInBand --verbose src/nameservice-expiry.test.ts",
"build": "tsc"
}
}

46
src/index.test.ts Normal file
View File

@ -0,0 +1,46 @@
import { Account } from './account';
import { Registry } from './index';
import { getConfig } from './testing/helper';
const { chainId, restEndpoint, gqlEndpoint, privateKey, fee } = getConfig();
jest.setTimeout(90 * 1000);
const registryTests = () => {
let registry: Registry;
beforeAll(async () => {
registry = new Registry(restEndpoint, gqlEndpoint, chainId);
});
test('Get account info.', async() => {
const account = new Account(Buffer.from(privateKey, 'hex'));
const accounts = await registry.getAccounts([account.formattedCosmosAddress]);
expect(accounts).toHaveLength(1)
const [accountObj] = accounts;
expect(accountObj.address).toBe(account.formattedCosmosAddress);
expect(accountObj.pubKey).toBe(account.encodedPubkey);
expect(accountObj.number).toBe('0');
expect(accountObj.sequence).toBeDefined();
expect(accountObj.balance).toHaveLength(1);
const [{ type, quantity }] = accountObj.balance
expect(type).toBe('aphoton');
expect(quantity).toBeDefined();
})
test('Get account balance.', async() => {
const mnenonic1 = Account.generateMnemonic();
const otherAccount = await Account.generateFromMnemonic(mnenonic1);
await registry.sendCoins({ denom: 'aphoton', amount: '10000000000000000000000000', destinationAddress: otherAccount.formattedCosmosAddress }, privateKey, fee);
const [accountObj] = await registry.getAccounts([otherAccount.formattedCosmosAddress]);
expect(accountObj).toBeDefined();
expect(accountObj.address).toBe(otherAccount.formattedCosmosAddress);
const [{ type, quantity }] = accountObj.balance
expect(type).toBe('aphoton');
expect(quantity).toBe('10000000000000000000000000');
})
}
describe('Registry', registryTests);

View File

@ -125,10 +125,10 @@ export class Registry {
}
/**
* Get account by addresses.
* Get accounts by addresses.
*/
async getAccount(address: string) {
return this._client.getAccount(address);
async getAccounts(addresses: string[]) {
return this._client.getAccounts(addresses);
}
/**
@ -166,14 +166,7 @@ export class Registry {
async sendCoins(params: MessageSendParams, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createMessageSend(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -187,10 +180,14 @@ export class Registry {
async getNextBondId(privateKey: string) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountObj } } = await this.getAccount(account.formattedCosmosAddress);
const accounts = await this.getAccounts([account.formattedCosmosAddress]);
if (!accounts.length) {
throw new Error('Account does not exist.');
}
const [accountObj] = accounts;
const nextSeq = parseInt(accountObj.sequence, 10) + 1;
result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`);
result = sha256(`${accountObj.address}:${accountObj.number}:${nextSeq}`);
return result;
}
@ -215,14 +212,7 @@ export class Registry {
async createBond(params: MessageMsgCreateBond, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgCreateBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -236,14 +226,7 @@ export class Registry {
async refillBond(params: MessageMsgRefillBond, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgRefillBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -257,14 +240,7 @@ export class Registry {
async withdrawBond(params: MessageMsgWithdrawBond, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgWithdrawBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -278,14 +254,7 @@ export class Registry {
async cancelBond(params: MessageMsgCancelBond, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgCancelBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -299,14 +268,7 @@ export class Registry {
async reserveAuthority(params: { name: string, owner?: string }, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msgParams = {
name: params.name,
@ -325,14 +287,7 @@ export class Registry {
async setAuthorityBond(params: MessageMsgSetAuthorityBond, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgSetAuthorityBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -346,14 +301,7 @@ export class Registry {
async commitBid(params: MessageMsgCommitBid, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgCommitBid(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -367,14 +315,7 @@ export class Registry {
async revealBid(params: MessageMsgRevealBid, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgRevealBid(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -402,14 +343,7 @@ export class Registry {
async setName(params: MessageMsgSetName, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgSetName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -430,14 +364,7 @@ export class Registry {
async deleteName(params: MessageMsgDeleteName, privateKey: string, fee: Fee) {
let result;
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
@ -483,14 +410,7 @@ export class Registry {
}
const account = new Account(Buffer.from(privateKey, 'hex'));
const { account: { base_account: accountInfo } } = await this.getAccount(account.formattedCosmosAddress);
const sender = {
accountAddress: account.formattedCosmosAddress,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: account.encodedPubkey,
}
const sender = await this._getSender(account);
const msg = createTxMsgSetRecord(this._chain, sender, fee, '', params)
return this._submitTx(msg, privateKey, sender);
@ -499,7 +419,7 @@ export class Registry {
/**
* Submit a generic Tx to the chain.
*/
async _submitTx(message: any, privateKey: string, sender: Sender) {
async _submitTx(message: any, privateKey: string, sender: Sender) {
// Check private key.
if (!isKeyValid(privateKey)) {
throw new Error('Registry privateKey should be a hex string.');
@ -534,6 +454,25 @@ export class Registry {
return Number(ethChainId)
}
/**
* Get sender used for creating message.
*/
async _getSender (account: Account) {
const accounts = await this.getAccounts([account.formattedCosmosAddress]);
if (!accounts.length) {
throw new Error('Account does not exist.');
}
const [{ number, sequence }] = accounts;
return {
accountAddress: account.formattedCosmosAddress,
sequence: sequence,
accountNumber: number,
pubkey: account.encodedPubkey,
}
}
}
export { Account }

View File

@ -86,12 +86,12 @@ const nameserviceExpiryTests = () => {
setTimeout(done, 60 * 1000);
});
test('Check record deleted without balance', async() => {
test('Check record deleted without bond balance', async() => {
const records = await registry.queryRecords({ type: 'watcher', version: watcher.record.version }, true);
expect(records).toHaveLength(0);
})
test('Check authority expired without balance', async() => {
test('Check authority expired without bond balance', async() => {
const [authority] = await registry.lookupAuthorities([authorityName]);
expect(authority.status).toBe('expired');
})
@ -109,7 +109,7 @@ if (!process.env.TEST_NAMESERVICE_EXPIRY) {
Run tests:
yarn test:expiry
yarn test:nameservice-expiry
*/
describe('Nameservice Expiry', nameserviceExpiryTests)

View File

@ -107,7 +107,7 @@ const namingTests = () => {
test('Set name for unbonded authority', async () => {
crn = `crn://${authorityName}/app/test`;
assert(watcherId)
await expect(registry.setName({ crn: crn, cid: watcherId }, privateKey, fee)).rejects.toThrow('Authority bond not found.');
await expect(registry.setName({ crn, cid: watcherId }, privateKey, fee)).rejects.toThrow('Authority bond not found.');
});
test('Set authority bond', async () => {
@ -116,7 +116,7 @@ const namingTests = () => {
test('Set name', async () => {
crn = `crn://${authorityName}/app/test`;
await registry.setName({ crn: crn, cid: watcherId }, privateKey, fee);
await registry.setName({ crn, cid: watcherId }, privateKey, fee);
// Query records should return it (some CRN points to it).
const records = await registry.queryRecords({ type: 'watcher', version: watcher.record.version });
@ -159,7 +159,7 @@ const namingTests = () => {
)
const updatedWatcherId = result.data.id;
await registry.setName({ crn: crn, cid: updatedWatcherId }, privateKey, fee);
await registry.setName({ crn, cid: updatedWatcherId }, privateKey, fee);
const records = await registry.lookupNames([crn], true);
expect(records).toHaveLength(1);
@ -216,7 +216,7 @@ const namingTests = () => {
});
test('Delete name', async () => {
await registry.deleteName({ crn: crn }, privateKey, fee);
await registry.deleteName({ crn }, privateKey, fee);
let records = await registry.lookupNames([crn], true);
expect(records).toBeDefined();
@ -240,7 +240,7 @@ const namingTests = () => {
});
test('Delete already deleted name', async () => {
await registry.deleteName({ crn: crn }, privateKey, fee);
await registry.deleteName({ crn }, privateKey, fee);
const records = await registry.lookupNames([crn], true);
expect(records).toBeDefined();

View File

@ -133,15 +133,32 @@ export class RegistryClient {
});
}
/**
* Fetch Account.
* Fetch Accounts.
*/
async getAccount(address: string) {
assert(address);
async getAccounts(addresses: string[]) {
assert(addresses);
assert(addresses.length);
let { data } = await axios.get(`${this._restEndpoint}${generateEndpointAccount(address)}`)
const query = `query ($addresses: [String!]) {
getAccounts(addresses: $addresses) {
address
pubKey
number
sequence
balance {
type
quantity
}
}
}`;
return data
const variables = {
addresses
};
return RegistryClient.getResult(this._graph(query)(variables), 'getAccounts');
}
/**