Add tests for bond refill, withdraw and cancel

This commit is contained in:
nabarun 2022-04-04 15:50:20 +05:30 committed by Ashwin Phatak
parent 7fe5bcda83
commit df5619932d
4 changed files with 337 additions and 7 deletions

View File

@ -37,6 +37,25 @@ const MSG_REFILL_BOND_TYPES = {
],
}
const MSG_WITHDRAW_BOND_TYPES = {
MsgValue: [
{ name: 'id', type: 'string' },
{ name: 'signer', type: 'string' },
{ name: 'coins', type: 'TypeCoins[]' },
],
TypeCoins: [
{ name: 'denom', type: 'string' },
{ name: 'amount', type: 'string' },
],
}
const MSG_CANCEL_BOND_TYPES = {
MsgValue: [
{ name: 'id', type: 'string' },
{ name: 'signer', type: 'string' },
]
}
export interface MessageMsgCreateBond {
amount: string
denom: string
@ -48,6 +67,16 @@ export interface MessageMsgRefillBond {
denom: string
}
export interface MessageMsgWithdrawBond {
id: string
amount: string
denom: string
}
export interface MessageMsgCancelBond {
id: string
}
export function createTxMsgCreateBond(
chain: Chain,
sender: Sender,
@ -168,6 +197,124 @@ export function createTxMsgRefillBond(
}
}
export function createTxMsgWithdrawBond(
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgWithdrawBond,
) {
// EIP712
const feeObject = generateFee(
fee.amount,
fee.denom,
fee.gas,
sender.accountAddress,
)
const types = generateTypes(MSG_WITHDRAW_BOND_TYPES)
const msg = createMsgWithdrawBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
)
const messages = generateMessage(
sender.accountNumber.toString(),
sender.sequence.toString(),
chain.cosmosChainId,
memo,
feeObject,
msg,
)
const eipToSign = createEIP712(types, chain.chainId, messages)
// Cosmos
const msgCosmos = protoCreateMsgWithdrawBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
)
const tx = createTransaction(
msgCosmos,
memo,
fee.amount,
fee.denom,
parseInt(fee.gas, 10),
'ethsecp256',
sender.pubkey,
sender.sequence,
sender.accountNumber,
chain.cosmosChainId,
)
return {
signDirect: tx.signDirect,
legacyAmino: tx.legacyAmino,
eipToSign,
}
}
export function createTxMsgCancelBond(
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgCancelBond,
) {
// EIP712
const feeObject = generateFee(
fee.amount,
fee.denom,
fee.gas,
sender.accountAddress,
)
const types = generateTypes(MSG_CANCEL_BOND_TYPES)
const msg = createMsgCancelBond(
params.id,
sender.accountAddress
)
const messages = generateMessage(
sender.accountNumber.toString(),
sender.sequence.toString(),
chain.cosmosChainId,
memo,
feeObject,
msg,
)
const eipToSign = createEIP712(types, chain.chainId, messages)
// Cosmos
const msgCosmos = protoCreateMsgCancelBond(
params.id,
sender.accountAddress
)
const tx = createTransaction(
msgCosmos,
memo,
fee.amount,
fee.denom,
parseInt(fee.gas, 10),
'ethsecp256',
sender.pubkey,
sender.sequence,
sender.accountNumber,
chain.cosmosChainId,
)
return {
signDirect: tx.signDirect,
legacyAmino: tx.legacyAmino,
eipToSign,
}
}
function createMsgCreateBond(
signer: string,
amount: string,
@ -251,3 +398,75 @@ const protoCreateMsgRefillBond = (
path: 'vulcanize.bond.v1beta1.MsgRefillBond',
}
}
function createMsgWithdrawBond(
id: string,
signer: string,
amount: string,
denom: string,
) {
return {
type: 'bond/MsgWithdrawBond',
value: {
id,
coins: [
{
amount,
denom,
},
],
signer
},
}
}
const protoCreateMsgWithdrawBond = (
id: string,
signer: string,
amount: string,
denom: string,
) => {
const value = new coin.cosmos.base.v1beta1.Coin({
denom,
amount,
})
const withdrawBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgWithdrawBond({
id,
signer,
coins: [value]
})
return {
message: withdrawBondMessage,
path: 'vulcanize.bond.v1beta1.MsgWithdrawBond',
}
}
function createMsgCancelBond(
id: string,
signer: string
) {
return {
type: 'bond/MsgCancelBond',
value: {
id,
signer
},
}
}
const protoCreateMsgCancelBond = (
id: string,
signer: string
) => {
const cancelBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgCancelBond({
id,
signer
})
return {
message: cancelBondMessage,
path: 'vulcanize.bond.v1beta1.MsgCancelBond',
}
}

View File

@ -1,6 +1,8 @@
import { Registry } from './index';
import { getConfig, wait } from './testing/helper';
const TX_WAIT_TIME = 5000; // in milliseconds.
const { mockServer, chibaClonk: { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } } = getConfig();
jest.setTimeout(90 * 1000);
@ -18,8 +20,8 @@ const bondTests = () => {
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)
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
await wait(TX_WAIT_TIME)
})
test('Get bond by ID.', async () => {
@ -27,7 +29,7 @@ const bondTests = () => {
expect(bond).toBeDefined();
expect(bond.id).toBe(bondId1);
expect(bond.balance).toHaveLength(1);
expect(bond.balance[0]).toEqual({ type: 'aphoton', quantity: '100' });
expect(bond.balance[0]).toEqual({ type: 'aphoton', quantity: '1000000000' });
bondOwner = bond.owner;
});
@ -44,6 +46,38 @@ const bondTests = () => {
const bond = bonds.filter((bond: any) => bond.id === bondId1);
expect(bond).toBeDefined();
});
test('Refill bond.', async () => {
await registry.refillBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
await wait(TX_WAIT_TIME);
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: '1000000500' });
});
test('Withdraw bond.', async () => {
await registry.withdrawBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
await wait(TX_WAIT_TIME);
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: '1000000000' });
});
test('Cancel bond.', async () => {
await registry.cancelBond({ id: bondId1 }, accountAddress, privateKey, fee);
await wait(TX_WAIT_TIME);
const [bond] = await registry.getBondsByIds([bondId1]);
expect(bond.id).toBe("");
expect(bond.owner).toBe("");
expect(bond.balance).toHaveLength(0);
});
};
if (mockServer) {

View File

@ -8,7 +8,7 @@ import {
Fee,
} from '@tharsis/transactions'
import { createTxMsgCreateBond, MessageMsgCreateBond } from "./bond";
import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, createTxMsgWithdrawBond, MessageMsgCancelBond, MessageMsgCreateBond, MessageMsgRefillBond, MessageMsgWithdrawBond } from "./bond";
import { RegistryClient } from "./registry-client";
import { Account } from "./account";
import { createTransaction } from "./txbuilder";
@ -21,7 +21,6 @@ export const DEFAULT_CHAIN_ID = 'ethermint_9000-1';
export const parseTxResponse = (result: any) => {
const { txhash: hash, height, ...txResponse } = result;
txResponse.data = txResponse.data && Buffer.from(txResponse.data, 'base64').toString('utf8');
txResponse.log = JSON.parse(txResponse.raw_log);
txResponse.events.forEach((event:any) => {
event.attributes = event.attributes.map(({ key, value }: { key: string, value: string }) => ({
@ -138,6 +137,84 @@ export class Registry {
return parseTxResponse(result);
}
/**
* Refill bond.
*/
async refillBond(params: MessageMsgRefillBond, senderAddress: string, privateKey: string, fee: Fee) {
let result;
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));
}
return parseTxResponse(result);
}
/**
* Withdraw (from) bond.
*/
async withdrawBond(params: MessageMsgWithdrawBond, senderAddress: string, privateKey: string, fee: Fee) {
let result;
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));
}
return parseTxResponse(result);
}
/**
* Cancel bond.
*/
async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) {
let result;
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));
}
return parseTxResponse(result);
}
/**
* Submit a generic Tx to the chain.
*/

View File

@ -1,5 +1,5 @@
const DEFAULT_PRIVATE_KEY = '794ce0bf3c75571416001c3415e69059aeba54038bcac8ce5b9792259e6d193b';
const DEFAULT_ADDRESS = 'ethm10atmndy7sm46829rc3yr7cxqucgrz5e9jg58xp'
const DEFAULT_PRIVATE_KEY = '3d8e23810daecb66ec4ca97805f6bbfc102015c3f22cdda1a783b1d074c43bdd';
const DEFAULT_ADDRESS = 'ethm1lrdrh056ce23h9d9d5rx34tp0uwj0u9zumynx3'
export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time))