Check if error contains expected message for failing transactions

This commit is contained in:
nabarun 2022-04-11 12:28:14 +05:30 committed by Ashwin Phatak
parent 394f015a5e
commit 837d9691ec
5 changed files with 109 additions and 169 deletions

View File

@ -39,7 +39,7 @@
"tiny-secp256k1": "^2.2.1" "tiny-secp256k1": "^2.2.1"
}, },
"scripts": { "scripts": {
"test": "jest --runInBand", "test": "jest --runInBand --verbose",
"build": "tsc" "build": "tsc"
} }
} }

View File

@ -13,7 +13,7 @@ import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, cr
import { RegistryClient } from "./registry-client"; import { RegistryClient } from "./registry-client";
import { Account } from "./account"; import { Account } from "./account";
import { createTransaction } from "./txbuilder"; import { createTransaction } from "./txbuilder";
import { createTxMsgDeleteName, createTxMsgReserveAuthority, createTxMsgSetAuthorityBond, createTxMsgSetName, createTxMsgSetRecord, MessageMsgDeleteName, MessageMsgReserveAuthority, MessageMsgSetAuthorityBond, MessageMsgSetName, MessageMsgSetRecord } from './messages/nameservice'; import { createTxMsgDeleteName, createTxMsgReserveAuthority, createTxMsgSetAuthorityBond, createTxMsgSetName, createTxMsgSetRecord, MessageMsgDeleteName, MessageMsgReserveAuthority, MessageMsgSetAuthorityBond, MessageMsgSetName, MessageMsgSetRecord, NAMESERVICE_ERRORS } from './messages/nameservice';
import { Payload, Record } from './types'; import { Payload, Record } from './types';
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.'; const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
@ -42,18 +42,12 @@ export class Registry {
_chain: Chain _chain: Chain
_client: RegistryClient _client: RegistryClient
static processWriteError(error: Error) { static processWriteError(error: string) {
/** // error string a stacktrace containing the message.
Example: // https://gist.github.com/nikugogoi/de55d390574ded3466abad8bffd81952#file-txresponse-js-L7
const errorMessage = NAMESERVICE_ERRORS.find(message => error.includes(message))
{ return errorMessage || DEFAULT_WRITE_ERROR;
message: '{"code":18,"data":null,"log":"invalid request: Name already reserved.: failed to execute message; message index: 0","info":"","gasWanted":"200000","gasUsed":"86717","events":[],"codespace":"sdk"}',
path: [ 'submit' ]
}g
*/
console.error(error)
const message = JSON.parse(error.message);
return message.log || DEFAULT_WRITE_ERROR;
} }
constructor(restUrl: string, gqlUrl: string, cosmosChainId = DEFAULT_CHAIN_ID) { constructor(restUrl: string, gqlUrl: string, cosmosChainId = DEFAULT_CHAIN_ID) {
@ -106,13 +100,7 @@ export class Registry {
fee: Fee fee: Fee
) { ) {
let result; let result;
result = await this._submitRecordTx(params, senderAddress, transactionPrivateKey, fee);
try {
result = await this._submitRecordTx(params, senderAddress, transactionPrivateKey, fee);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
}
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -122,24 +110,18 @@ export class Registry {
*/ */
async sendCoins(params: MessageSendParams, senderAddress: string, privateKey: string, fee: Fee) { async sendCoins(params: MessageSendParams, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createMessageSend(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createMessageSend(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -148,17 +130,11 @@ export class Registry {
*/ */
async getNextBondId(address: string) { async getNextBondId(address: string) {
let result; let result;
const { account } = await this.getAccount(address);
const accountObj = account.base_account;
try { const nextSeq = parseInt(accountObj.sequence, 10) + 1;
const { account } = await this.getAccount(address); result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`);
const accountObj = account.base_account;
const nextSeq = parseInt(accountObj.sequence, 10) + 1;
result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
}
return result; return result;
} }
@ -182,24 +158,18 @@ export class Registry {
*/ */
async createBond(params: MessageMsgCreateBond, senderAddress: string, privateKey: string, fee: Fee) { async createBond(params: MessageMsgCreateBond, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgCreateBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgCreateBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -208,24 +178,18 @@ export class Registry {
*/ */
async refillBond(params: MessageMsgRefillBond, senderAddress: string, privateKey: string, fee: Fee) { async refillBond(params: MessageMsgRefillBond, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgRefillBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgRefillBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -234,24 +198,18 @@ export class Registry {
*/ */
async withdrawBond(params: MessageMsgWithdrawBond, senderAddress: string, privateKey: string, fee: Fee) { async withdrawBond(params: MessageMsgWithdrawBond, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgWithdrawBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgWithdrawBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -260,24 +218,18 @@ export class Registry {
*/ */
async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) { async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgCancelBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgCancelBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -286,24 +238,18 @@ export class Registry {
*/ */
async reserveAuthority(params: MessageMsgReserveAuthority, senderAddress: string, privateKey: string, fee: Fee) { async reserveAuthority(params: MessageMsgReserveAuthority, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgReserveAuthority(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgReserveAuthority(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -316,24 +262,18 @@ export class Registry {
*/ */
async setAuthorityBond(params: MessageMsgSetAuthorityBond, senderAddress: string, privateKey: string, fee: Fee) { async setAuthorityBond(params: MessageMsgSetAuthorityBond, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgSetAuthorityBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgSetAuthorityBond(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -353,24 +293,18 @@ export class Registry {
*/ */
async setName(params: MessageMsgSetName, senderAddress: string, privateKey: string, fee: Fee) { async setName(params: MessageMsgSetName, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgSetName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgSetName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -386,24 +320,18 @@ export class Registry {
*/ */
async deleteName(params: MessageMsgDeleteName, senderAddress: string, privateKey: string, fee: Fee) { async deleteName(params: MessageMsgDeleteName, senderAddress: string, privateKey: string, fee: Fee) {
let result; let result;
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
try { const sender = {
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); accountAddress: accountInfo.address,
sequence: accountInfo.sequence,
const sender = { accountNumber: accountInfo.account_number,
accountAddress: accountInfo.address, pubkey: accountInfo.pub_key.key,
sequence: accountInfo.sequence,
accountNumber: accountInfo.account_number,
pubkey: accountInfo.pub_key.key,
}
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
} catch (err: any) {
const error = err[0] || err;
throw new Error(Registry.processWriteError(error));
} }
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
result = await this._submitTx(msg, privateKey, sender);
return parseTxResponse(result); return parseTxResponse(result);
} }
@ -478,6 +406,13 @@ export class Registry {
// Submit Tx to chain. // Submit Tx to chain.
const { tx_response: response } = await this._client.submit(tx); const { tx_response: response } = await this._client.submit(tx);
if (response.code !== 0) {
// Throw error when transaction is not successful.
// https://docs.starport.com/guide/nameservice/05-play.html#buy-name-transaction-details
throw new Error(Registry.processWriteError(response.raw_log))
}
return response; return response;
} }
} }

View File

@ -67,6 +67,12 @@ const MSG_DELETE_NAME_TYPES = {
], ],
} }
export const NAMESERVICE_ERRORS = [
'Name already reserved.',
'Authority bond not found.',
'Name authority not found.'
]
export interface MessageMsgReserveAuthority { export interface MessageMsgReserveAuthority {
name: string name: string
owner: string owner: string

View File

@ -76,7 +76,7 @@ const namingTests = () => {
expect(Number(record.height)).toBe(0); expect(Number(record.height)).toBe(0);
}); });
xtest('Reserve already reserved authority', async () => { test('Reserve already reserved authority', async () => {
await expect(registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee)).rejects.toThrow('Name already reserved.'); await expect(registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee)).rejects.toThrow('Name already reserved.');
}); });
@ -116,7 +116,7 @@ const namingTests = () => {
expect(Number(record.height)).toBeGreaterThan(0); expect(Number(record.height)).toBeGreaterThan(0);
}); });
xtest('Set name for unbonded authority', async () => { test('Set name for unbonded authority', async () => {
wrn = `wrn://${authorityName}/app/test`; wrn = `wrn://${authorityName}/app/test`;
assert(watcherId) assert(watcherId)
await expect(registry.setName({ wrn, cid: watcherId }, accountAddress, privateKey, fee)).rejects.toThrow('Authority bond not found.'); await expect(registry.setName({ wrn, cid: watcherId }, accountAddress, privateKey, fee)).rejects.toThrow('Authority bond not found.');
@ -197,7 +197,7 @@ const namingTests = () => {
expect(oldRecord.height).toBeDefined(); expect(oldRecord.height).toBeDefined();
}); });
xtest('Set name without reserving authority', async () => { test('Set name without reserving authority', async () => {
await expect(registry.setName({ wrn: 'wrn://not-reserved/app/test', cid: watcherId }, accountAddress, privateKey, fee)) await expect(registry.setName({ wrn: 'wrn://not-reserved/app/test', cid: watcherId }, accountAddress, privateKey, fee))
.rejects.toThrow('Name authority not found.'); .rejects.toThrow('Name authority not found.');
}); });

View File

@ -83,7 +83,6 @@ export class Util {
* Get record content ID. * Get record content ID.
*/ */
static async getContentId(record: any) { static async getContentId(record: any) {
console.log(record)
const content = dagCBOR.util.serialize(record); const content = dagCBOR.util.serialize(record);
const cid = await dagCBOR.util.cid(content); const cid = await dagCBOR.util.cid(content);