From 837d9691ec76daa029a0f3639565a5e84784ef9e Mon Sep 17 00:00:00 2001 From: nabarun Date: Mon, 11 Apr 2022 12:28:14 +0530 Subject: [PATCH] Check if error contains expected message for failing transactions --- package.json | 2 +- src/index.ts | 263 ++++++++++++++---------------------- src/messages/nameservice.ts | 6 + src/naming.test.ts | 6 +- src/util.ts | 1 - 5 files changed, 109 insertions(+), 169 deletions(-) diff --git a/package.json b/package.json index 9c95d7b..da6f713 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "tiny-secp256k1": "^2.2.1" }, "scripts": { - "test": "jest --runInBand", + "test": "jest --runInBand --verbose", "build": "tsc" } } diff --git a/src/index.ts b/src/index.ts index 16477b2..454399b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,7 @@ import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, cr import { RegistryClient } from "./registry-client"; import { Account } from "./account"; 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'; const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.'; @@ -42,18 +42,12 @@ export class Registry { _chain: Chain _client: RegistryClient - static processWriteError(error: Error) { - /** - Example: + static processWriteError(error: string) { + // error string a stacktrace containing the message. + // https://gist.github.com/nikugogoi/de55d390574ded3466abad8bffd81952#file-txresponse-js-L7 + const errorMessage = NAMESERVICE_ERRORS.find(message => error.includes(message)) - { - 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; + return errorMessage || DEFAULT_WRITE_ERROR; } constructor(restUrl: string, gqlUrl: string, cosmosChainId = DEFAULT_CHAIN_ID) { @@ -106,13 +100,7 @@ export class Registry { fee: Fee ) { let result; - - try { - result = await this._submitRecordTx(params, senderAddress, transactionPrivateKey, fee); - } catch (err: any) { - const error = err[0] || err; - throw new Error(Registry.processWriteError(error)); - } + result = await this._submitRecordTx(params, senderAddress, transactionPrivateKey, fee); return parseTxResponse(result); } @@ -122,24 +110,18 @@ export class Registry { */ async sendCoins(params: MessageSendParams, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -148,17 +130,11 @@ export class Registry { */ async getNextBondId(address: string) { let result; + const { account } = await this.getAccount(address); + const accountObj = account.base_account; - try { - const { account } = await this.getAccount(address); - 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)); - } + const nextSeq = parseInt(accountObj.sequence, 10) + 1; + result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`); return result; } @@ -182,24 +158,18 @@ export class Registry { */ async createBond(params: MessageMsgCreateBond, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -208,24 +178,18 @@ export class Registry { */ async refillBond(params: MessageMsgRefillBond, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -234,24 +198,18 @@ export class Registry { */ async withdrawBond(params: MessageMsgWithdrawBond, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -260,24 +218,18 @@ export class Registry { */ async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -286,24 +238,18 @@ export class Registry { */ async reserveAuthority(params: MessageMsgReserveAuthority, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -316,24 +262,18 @@ export class Registry { */ async setAuthorityBond(params: MessageMsgSetAuthorityBond, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -353,24 +293,18 @@ export class Registry { */ async setName(params: MessageMsgSetName, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -386,24 +320,18 @@ export class Registry { */ async deleteName(params: MessageMsgDeleteName, senderAddress: string, privateKey: string, fee: Fee) { let result; + const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - try { - const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress); - - const sender = { - accountAddress: accountInfo.address, - 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 sender = { + accountAddress: accountInfo.address, + 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); + return parseTxResponse(result); } @@ -478,6 +406,13 @@ export class Registry { // Submit Tx to chain. 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; } } diff --git a/src/messages/nameservice.ts b/src/messages/nameservice.ts index 6da7a6f..24b8381 100644 --- a/src/messages/nameservice.ts +++ b/src/messages/nameservice.ts @@ -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 { name: string owner: string diff --git a/src/naming.test.ts b/src/naming.test.ts index 780fa0d..ea75cf8 100644 --- a/src/naming.test.ts +++ b/src/naming.test.ts @@ -76,7 +76,7 @@ const namingTests = () => { 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.'); }); @@ -116,7 +116,7 @@ const namingTests = () => { 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`; assert(watcherId) 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(); }); - 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)) .rejects.toThrow('Name authority not found.'); }); diff --git a/src/util.ts b/src/util.ts index d87982f..527fe98 100644 --- a/src/util.ts +++ b/src/util.ts @@ -83,7 +83,6 @@ export class Util { * Get record content ID. */ static async getContentId(record: any) { - console.log(record) const content = dagCBOR.util.serialize(record); const cid = await dagCBOR.util.cid(content);