Add tests for bond refill, withdraw and cancel
This commit is contained in:
parent
7fe5bcda83
commit
df5619932d
219
src/bond.ts
219
src/bond.ts
@ -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',
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
81
src/index.ts
81
src/index.ts
@ -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.
|
||||
*/
|
||||
|
@ -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))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user