Check if error contains expected message for failing transactions
This commit is contained in:
parent
394f015a5e
commit
837d9691ec
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
91
src/index.ts
91
src/index.ts
@ -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;
|
||||||
|
|
||||||
try {
|
|
||||||
result = await this._submitRecordTx(params, senderAddress, transactionPrivateKey, fee);
|
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,8 +110,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -135,10 +121,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createMessageSend(this._chain, sender, fee, '', params)
|
const msg = createMessageSend(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account } = await this.getAccount(address);
|
const { account } = await this.getAccount(address);
|
||||||
const accountObj = account.base_account;
|
const accountObj = account.base_account;
|
||||||
|
|
||||||
const nextSeq = parseInt(accountObj.sequence, 10) + 1;
|
const nextSeq = parseInt(accountObj.sequence, 10) + 1;
|
||||||
result = sha256(`${accountObj.address}:${accountObj.account_number}:${nextSeq}`);
|
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,8 +158,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -195,10 +169,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgCreateBond(this._chain, sender, fee, '', params)
|
const msg = createTxMsgCreateBond(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -208,8 +178,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -221,10 +189,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgRefillBond(this._chain, sender, fee, '', params)
|
const msg = createTxMsgRefillBond(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -234,8 +198,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -247,10 +209,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgWithdrawBond(this._chain, sender, fee, '', params)
|
const msg = createTxMsgWithdrawBond(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -260,8 +218,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -273,10 +229,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgCancelBond(this._chain, sender, fee, '', params)
|
const msg = createTxMsgCancelBond(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -286,8 +238,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -299,10 +249,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgReserveAuthority(this._chain, sender, fee, '', params)
|
const msg = createTxMsgReserveAuthority(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -316,8 +262,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -329,10 +273,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgSetAuthorityBond(this._chain, sender, fee, '', params)
|
const msg = createTxMsgSetAuthorityBond(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -353,8 +293,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -366,10 +304,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgSetName(this._chain, sender, fee, '', params)
|
const msg = createTxMsgSetName(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
@ -386,8 +320,6 @@ 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;
|
||||||
|
|
||||||
try {
|
|
||||||
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
const sender = {
|
const sender = {
|
||||||
@ -399,10 +331,6 @@ export class Registry {
|
|||||||
|
|
||||||
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
|
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
|
||||||
result = await this._submitTx(msg, privateKey, sender);
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
} catch (err: any) {
|
|
||||||
const error = err[0] || err;
|
|
||||||
throw new Error(Registry.processWriteError(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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.');
|
||||||
});
|
});
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user