Changes from review
This commit is contained in:
parent
252665512d
commit
58227b68be
2
.env.example
Normal file
2
.env.example
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ACCOUNT_ADDRESS='ethm17mfhntjckgrapl5yru2sfq5hmvn7qe6zhc06px'
|
||||||
|
PRIVATE_KEY='75f719e613d05efab06a3f1dde5250b497723b13d4afa4f8ed80145764e40cf7'
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
dist
|
dist
|
||||||
|
.env
|
||||||
|
24
DEVELOPMENT.md
Normal file
24
DEVELOPMENT.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Development
|
||||||
|
|
||||||
|
## Protobuf
|
||||||
|
|
||||||
|
Run following scripts when [proto files](./proto/) are updated.
|
||||||
|
|
||||||
|
1. Install dependencies
|
||||||
|
```bash
|
||||||
|
yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Generate typescript code for the proto files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./create-proto-files.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Remove GRPC code from generated code
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./remove-grpc.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Reference: https://github.com/tharsis/evmosjs/tree/main/packages/proto#note
|
18
README.md
18
README.md
@ -1,6 +1,6 @@
|
|||||||
# chiba-clonk-client
|
# chiba-clonk-client
|
||||||
|
|
||||||
## Development
|
## Tests
|
||||||
|
|
||||||
Follow these steps to run the tests:
|
Follow these steps to run the tests:
|
||||||
|
|
||||||
@ -10,13 +10,9 @@ Follow these steps to run the tests:
|
|||||||
yarn
|
yarn
|
||||||
```
|
```
|
||||||
|
|
||||||
- Clone the [chiba-clonk repo](https://github.com/deep-stack/chiba-clonk) and change to repo directory.
|
- Copy [.env.example](./.env.example) file and create a `.env` file.
|
||||||
|
|
||||||
- Checkout to appropriate branch for running tests.
|
- Clone the [chiba-clonk repo](https://github.com/vulcanize/chiba-clonk) and change to repo directory.
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout ng-v12-chiba-clonk-client
|
|
||||||
```
|
|
||||||
|
|
||||||
- Run the chain using `./init.sh`.
|
- Run the chain using `./init.sh`.
|
||||||
|
|
||||||
@ -25,7 +21,7 @@ Follow these steps to run the tests:
|
|||||||
ethermintd keys list
|
ethermintd keys list
|
||||||
```
|
```
|
||||||
|
|
||||||
- Use the address of key `mykey` and assign it to `DEFAULT_ADDRESS` in the [test helper file](./src/testing/helper.ts).
|
- Use the address of key `mykey` and assign it to `ACCOUNT_ADDRESS` in the `.env` file.
|
||||||
|
|
||||||
- To export the private key run:
|
- To export the private key run:
|
||||||
|
|
||||||
@ -33,10 +29,14 @@ Follow these steps to run the tests:
|
|||||||
ethermintd keys export mykey --unarmored-hex --unsafe
|
ethermintd keys export mykey --unarmored-hex --unsafe
|
||||||
```
|
```
|
||||||
|
|
||||||
- Copy the private key and assign it to variable `DEFAULT_PRIVATE_KEY` in the [test helper file](./src/testing/helper.ts).
|
- Copy the private key and assign it to variable `PRIVATE_KEY` in the `.env` file.
|
||||||
|
|
||||||
- Run the test in chiba-clonk-client repo:
|
- Run the test in chiba-clonk-client repo:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn test
|
yarn test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
[README](./DEVELOPMENT.md)
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
preset: 'ts-jest',
|
preset: 'ts-jest',
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
|
setupFiles: ["dotenv/config"]
|
||||||
};
|
};
|
||||||
|
15
package.json
15
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "chiba-clonk-client",
|
"name": "chiba-clonk-client",
|
||||||
"version": "1.0.0",
|
"version": "0.1.0",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"repository": "git@github.com:vulcanize/chiba-clonk-client.git",
|
"repository": "git@github.com:vulcanize/chiba-clonk-client.git",
|
||||||
@ -9,31 +9,24 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/is-url": "^1.2.30",
|
"@types/is-url": "^1.2.30",
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
"@types/ripemd160": "^2.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"@types/secp256k1": "^4.0.3",
|
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"protoc-gen-ts": "^0.8.2",
|
"protoc-gen-ts": "^0.8.2",
|
||||||
"ts-jest": "^27.1.3",
|
"ts-jest": "^27.1.3",
|
||||||
"ts-node": "^10.7.0",
|
|
||||||
"typescript": "^4.6.2"
|
"typescript": "^4.6.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@cosmjs/amino": "^0.28.1",
|
||||||
"@cosmjs/crypto": "^0.28.1",
|
"@cosmjs/crypto": "^0.28.1",
|
||||||
"@cosmjs/encoding": "^0.28.1",
|
"@cosmjs/encoding": "^0.28.1",
|
||||||
"@cosmjs/proto-signing": "^0.28.0",
|
|
||||||
"@cosmjs/stargate": "^0.28.0",
|
|
||||||
"@metamask/eth-sig-util": "^4.0.0",
|
"@metamask/eth-sig-util": "^4.0.0",
|
||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"bech32": "^2.0.0",
|
|
||||||
"bip32": "^3.0.1",
|
"bip32": "^3.0.1",
|
||||||
"bip39": "^3.0.4",
|
"bip39": "^3.0.4",
|
||||||
"ethers": "^5.6.1",
|
"evmosjs": "^0.2.5",
|
||||||
"evmosjs": "^0.2.2",
|
|
||||||
"graphql.js": "^0.6.8",
|
"graphql.js": "^0.6.8",
|
||||||
"is-url": "^1.2.4",
|
"is-url": "^1.2.4",
|
||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
"ripemd160": "^2.0.2",
|
|
||||||
"secp256k1": "^4.0.3",
|
|
||||||
"tiny-secp256k1": "^2.2.1"
|
"tiny-secp256k1": "^2.2.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -4,7 +4,7 @@ import * as ecc from 'tiny-secp256k1';
|
|||||||
import * as bip39 from 'bip39';
|
import * as bip39 from 'bip39';
|
||||||
import { MessageTypes, signTypedData, SignTypedDataVersion } from '@metamask/eth-sig-util';
|
import { MessageTypes, signTypedData, SignTypedDataVersion } from '@metamask/eth-sig-util';
|
||||||
import { Ripemd160, Secp256k1 } from "@cosmjs/crypto";
|
import { Ripemd160, Secp256k1 } from "@cosmjs/crypto";
|
||||||
import { toBech32, toHex } from '@cosmjs/encoding';
|
import { toBech32 } from '@cosmjs/encoding';
|
||||||
import { rawSecp256k1PubkeyToRawAddress } from "@cosmjs/amino";
|
import { rawSecp256k1PubkeyToRawAddress } from "@cosmjs/amino";
|
||||||
|
|
||||||
const HDPATH = "m/44'/60'/0'/0";
|
const HDPATH = "m/44'/60'/0'/0";
|
||||||
@ -22,14 +22,13 @@ interface TypedMessageDomain {
|
|||||||
/**
|
/**
|
||||||
* Registry account.
|
* Registry account.
|
||||||
*/
|
*/
|
||||||
// TODO(egor): This is a wrapper around the private key and doesn't have any account related stuff (e.g. account number/sequence). Maybe rename to Key?
|
|
||||||
export class Account {
|
export class Account {
|
||||||
_privateKey: Buffer
|
_privateKey: Buffer
|
||||||
_publicKey?: Uint8Array
|
_publicKey?: Uint8Array
|
||||||
_cosmosAddress?: string
|
_cosmosAddress?: string
|
||||||
_formattedCosmosAddress?: string
|
_formattedCosmosAddress?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate bip39 mnemonic.
|
* Generate bip39 mnemonic.
|
||||||
*/
|
*/
|
||||||
static generateMnemonic() {
|
static generateMnemonic() {
|
||||||
@ -53,7 +52,6 @@ export class Account {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* New Account.
|
* New Account.
|
||||||
* @param {buffer} privateKey
|
|
||||||
*/
|
*/
|
||||||
constructor(privateKey: Buffer) {
|
constructor(privateKey: Buffer) {
|
||||||
assert(privateKey);
|
assert(privateKey);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Registry } from './index';
|
import { Registry } from './index';
|
||||||
import { getConfig, wait } from './testing/helper';
|
import { getConfig } from './testing/helper';
|
||||||
|
|
||||||
const TX_WAIT_TIME = 5000; // in milliseconds.
|
const TX_WAIT_TIME = 5000; // in milliseconds.
|
||||||
|
|
||||||
const { mockServer, chibaClonk: { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } } = getConfig();
|
const { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } = getConfig();
|
||||||
|
|
||||||
jest.setTimeout(90 * 1000);
|
jest.setTimeout(90 * 1000);
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ const bondTests = () => {
|
|||||||
bondId1 = await registry.getNextBondId(accountAddress);
|
bondId1 = await registry.getNextBondId(accountAddress);
|
||||||
expect(bondId1).toBeDefined();
|
expect(bondId1).toBeDefined();
|
||||||
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
||||||
await wait(TX_WAIT_TIME)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Get bond by ID.', async () => {
|
test('Get bond by ID.', async () => {
|
||||||
@ -49,7 +48,6 @@ const bondTests = () => {
|
|||||||
|
|
||||||
test('Refill bond.', async () => {
|
test('Refill bond.', async () => {
|
||||||
await registry.refillBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
|
await registry.refillBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
|
||||||
await wait(TX_WAIT_TIME);
|
|
||||||
|
|
||||||
const [bond] = await registry.getBondsByIds([bondId1]);
|
const [bond] = await registry.getBondsByIds([bondId1]);
|
||||||
expect(bond).toBeDefined();
|
expect(bond).toBeDefined();
|
||||||
@ -60,7 +58,6 @@ const bondTests = () => {
|
|||||||
|
|
||||||
test('Withdraw bond.', async () => {
|
test('Withdraw bond.', async () => {
|
||||||
await registry.withdrawBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
|
await registry.withdrawBond({ id: bondId1, denom: 'aphoton', amount: '500' }, accountAddress, privateKey, fee);
|
||||||
await wait(TX_WAIT_TIME);
|
|
||||||
|
|
||||||
const [bond] = await registry.getBondsByIds([bondId1]);
|
const [bond] = await registry.getBondsByIds([bondId1]);
|
||||||
expect(bond).toBeDefined();
|
expect(bond).toBeDefined();
|
||||||
@ -71,7 +68,6 @@ const bondTests = () => {
|
|||||||
|
|
||||||
test('Cancel bond.', async () => {
|
test('Cancel bond.', async () => {
|
||||||
await registry.cancelBond({ id: bondId1 }, accountAddress, privateKey, fee);
|
await registry.cancelBond({ id: bondId1 }, accountAddress, privateKey, fee);
|
||||||
await wait(TX_WAIT_TIME);
|
|
||||||
|
|
||||||
const [bond] = await registry.getBondsByIds([bondId1]);
|
const [bond] = await registry.getBondsByIds([bondId1]);
|
||||||
expect(bond.id).toBe("");
|
expect(bond.id).toBe("");
|
||||||
@ -80,9 +76,4 @@ const bondTests = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mockServer) {
|
describe('Bonds', bondTests);
|
||||||
// Required as jest complains if file has no tests.
|
|
||||||
test('skipping bond tests', () => {});
|
|
||||||
} else {
|
|
||||||
describe('Bonds', bondTests);
|
|
||||||
}
|
|
||||||
|
12
src/index.ts
12
src/index.ts
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import isUrl from 'is-url';
|
import isUrl from 'is-url';
|
||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
import { generatePostBodyBroadcast } from '@tharsis/provider';
|
import { generatePostBodyBroadcast, BroadcastMode } from '@tharsis/provider';
|
||||||
import {
|
import {
|
||||||
Chain,
|
Chain,
|
||||||
Sender,
|
Sender,
|
||||||
@ -10,11 +10,11 @@ import {
|
|||||||
MessageSendParams
|
MessageSendParams
|
||||||
} from '@tharsis/transactions'
|
} from '@tharsis/transactions'
|
||||||
|
|
||||||
import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, createTxMsgWithdrawBond, MessageMsgCancelBond, MessageMsgCreateBond, MessageMsgRefillBond, MessageMsgWithdrawBond } from "./bond";
|
import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, createTxMsgWithdrawBond, MessageMsgCancelBond, MessageMsgCreateBond, MessageMsgRefillBond, MessageMsgWithdrawBond } from "./messages/bond";
|
||||||
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 { createTxMsgReserveAuthority, MessageMsgReserveAuthority } from './nameservice';
|
import { createTxMsgReserveAuthority, MessageMsgReserveAuthority } from './messages/nameservice';
|
||||||
|
|
||||||
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
||||||
|
|
||||||
@ -82,10 +82,6 @@ export class Registry {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send coins.
|
* Send coins.
|
||||||
* @param {object[]} amount
|
|
||||||
* @param {string} toAddress
|
|
||||||
* @param {string} privateKey
|
|
||||||
* @param {object} fee
|
|
||||||
*/
|
*/
|
||||||
async sendCoins(params: MessageSendParams, senderAddress: string, privateKey: string, fee: Fee) {
|
async sendCoins(params: MessageSendParams, senderAddress: string, privateKey: string, fee: Fee) {
|
||||||
let result;
|
let result;
|
||||||
@ -296,7 +292,7 @@ export class Registry {
|
|||||||
// Generate signed Tx.
|
// Generate signed Tx.
|
||||||
const transaction = createTransaction(message, account, sender, this._chain);
|
const transaction = createTransaction(message, account, sender, this._chain);
|
||||||
|
|
||||||
const tx = generatePostBodyBroadcast(transaction)
|
const tx = generatePostBodyBroadcast(transaction, BroadcastMode.Block)
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
createEIP712,
|
|
||||||
generateFee,
|
|
||||||
generateMessage,
|
|
||||||
generateTypes,
|
generateTypes,
|
||||||
} from '@tharsis/eip712'
|
} from '@tharsis/eip712'
|
||||||
import {
|
import {
|
||||||
@ -9,10 +6,10 @@ import {
|
|||||||
Sender,
|
Sender,
|
||||||
Fee,
|
Fee,
|
||||||
} from '@tharsis/transactions'
|
} from '@tharsis/transactions'
|
||||||
import { createTransaction } from '@tharsis/proto'
|
|
||||||
|
|
||||||
import * as bondTx from './proto/vulcanize/bond/v1beta1/tx'
|
import * as bondTx from '../proto/vulcanize/bond/v1beta1/tx'
|
||||||
import * as coin from './proto/cosmos/base/v1beta1/coin'
|
import * as coin from '../proto/cosmos/base/v1beta1/coin'
|
||||||
|
import { createTx } from './util'
|
||||||
|
|
||||||
const MSG_CREATE_BOND_TYPES = {
|
const MSG_CREATE_BOND_TYPES = {
|
||||||
MsgValue: [
|
MsgValue: [
|
||||||
@ -84,13 +81,6 @@ export function createTxMsgCreateBond(
|
|||||||
memo: string,
|
memo: string,
|
||||||
params: MessageMsgCreateBond,
|
params: MessageMsgCreateBond,
|
||||||
) {
|
) {
|
||||||
// EIP712
|
|
||||||
const feeObject = generateFee(
|
|
||||||
fee.amount,
|
|
||||||
fee.denom,
|
|
||||||
fee.gas,
|
|
||||||
sender.accountAddress,
|
|
||||||
)
|
|
||||||
const types = generateTypes(MSG_CREATE_BOND_TYPES)
|
const types = generateTypes(MSG_CREATE_BOND_TYPES)
|
||||||
|
|
||||||
const msg = createMsgCreateBond(
|
const msg = createMsgCreateBond(
|
||||||
@ -99,41 +89,13 @@ export function createTxMsgCreateBond(
|
|||||||
params.denom
|
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 = protoCreateMsgCreateBond(
|
const msgCosmos = protoCreateMsgCreateBond(
|
||||||
sender.accountAddress,
|
sender.accountAddress,
|
||||||
params.amount,
|
params.amount,
|
||||||
params.denom
|
params.denom
|
||||||
)
|
)
|
||||||
|
|
||||||
const tx = createTransaction(
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
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 createTxMsgRefillBond(
|
export function createTxMsgRefillBond(
|
||||||
@ -143,13 +105,6 @@ export function createTxMsgRefillBond(
|
|||||||
memo: string,
|
memo: string,
|
||||||
params: MessageMsgRefillBond,
|
params: MessageMsgRefillBond,
|
||||||
) {
|
) {
|
||||||
// EIP712
|
|
||||||
const feeObject = generateFee(
|
|
||||||
fee.amount,
|
|
||||||
fee.denom,
|
|
||||||
fee.gas,
|
|
||||||
sender.accountAddress,
|
|
||||||
)
|
|
||||||
const types = generateTypes(MSG_REFILL_BOND_TYPES)
|
const types = generateTypes(MSG_REFILL_BOND_TYPES)
|
||||||
|
|
||||||
const msg = createMsgRefillBond(
|
const msg = createMsgRefillBond(
|
||||||
@ -159,17 +114,6 @@ export function createTxMsgRefillBond(
|
|||||||
params.denom
|
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 = protoCreateMsgRefillBond(
|
const msgCosmos = protoCreateMsgRefillBond(
|
||||||
params.id,
|
params.id,
|
||||||
sender.accountAddress,
|
sender.accountAddress,
|
||||||
@ -177,24 +121,7 @@ export function createTxMsgRefillBond(
|
|||||||
params.denom
|
params.denom
|
||||||
)
|
)
|
||||||
|
|
||||||
const tx = createTransaction(
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
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 createTxMsgWithdrawBond(
|
export function createTxMsgWithdrawBond(
|
||||||
@ -204,13 +131,6 @@ export function createTxMsgWithdrawBond(
|
|||||||
memo: string,
|
memo: string,
|
||||||
params: MessageMsgWithdrawBond,
|
params: MessageMsgWithdrawBond,
|
||||||
) {
|
) {
|
||||||
// EIP712
|
|
||||||
const feeObject = generateFee(
|
|
||||||
fee.amount,
|
|
||||||
fee.denom,
|
|
||||||
fee.gas,
|
|
||||||
sender.accountAddress,
|
|
||||||
)
|
|
||||||
const types = generateTypes(MSG_WITHDRAW_BOND_TYPES)
|
const types = generateTypes(MSG_WITHDRAW_BOND_TYPES)
|
||||||
|
|
||||||
const msg = createMsgWithdrawBond(
|
const msg = createMsgWithdrawBond(
|
||||||
@ -220,17 +140,6 @@ export function createTxMsgWithdrawBond(
|
|||||||
params.denom
|
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(
|
const msgCosmos = protoCreateMsgWithdrawBond(
|
||||||
params.id,
|
params.id,
|
||||||
sender.accountAddress,
|
sender.accountAddress,
|
||||||
@ -238,24 +147,7 @@ export function createTxMsgWithdrawBond(
|
|||||||
params.denom
|
params.denom
|
||||||
)
|
)
|
||||||
|
|
||||||
const tx = createTransaction(
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
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(
|
export function createTxMsgCancelBond(
|
||||||
@ -265,13 +157,6 @@ export function createTxMsgCancelBond(
|
|||||||
memo: string,
|
memo: string,
|
||||||
params: MessageMsgCancelBond,
|
params: MessageMsgCancelBond,
|
||||||
) {
|
) {
|
||||||
// EIP712
|
|
||||||
const feeObject = generateFee(
|
|
||||||
fee.amount,
|
|
||||||
fee.denom,
|
|
||||||
fee.gas,
|
|
||||||
sender.accountAddress,
|
|
||||||
)
|
|
||||||
const types = generateTypes(MSG_CANCEL_BOND_TYPES)
|
const types = generateTypes(MSG_CANCEL_BOND_TYPES)
|
||||||
|
|
||||||
const msg = createMsgCancelBond(
|
const msg = createMsgCancelBond(
|
||||||
@ -279,40 +164,12 @@ export function createTxMsgCancelBond(
|
|||||||
sender.accountAddress
|
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(
|
const msgCosmos = protoCreateMsgCancelBond(
|
||||||
params.id,
|
params.id,
|
||||||
sender.accountAddress
|
sender.accountAddress
|
||||||
)
|
)
|
||||||
|
|
||||||
const tx = createTransaction(
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
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(
|
function createMsgCreateBond(
|
@ -1,7 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
createEIP712,
|
|
||||||
generateFee,
|
|
||||||
generateMessage,
|
|
||||||
generateTypes,
|
generateTypes,
|
||||||
} from '@tharsis/eip712'
|
} from '@tharsis/eip712'
|
||||||
import {
|
import {
|
||||||
@ -9,9 +6,9 @@ import {
|
|||||||
Sender,
|
Sender,
|
||||||
Fee,
|
Fee,
|
||||||
} from '@tharsis/transactions'
|
} from '@tharsis/transactions'
|
||||||
import { createTransaction } from '@tharsis/proto'
|
|
||||||
|
|
||||||
import * as nameserviceTx from './proto/vulcanize/nameservice/v1beta1/tx'
|
import * as nameserviceTx from '../proto/vulcanize/nameservice/v1beta1/tx'
|
||||||
|
import { createTx } from './util'
|
||||||
|
|
||||||
const MSG_RESERVE_AUTHORITY_TYPES = {
|
const MSG_RESERVE_AUTHORITY_TYPES = {
|
||||||
MsgValue: [
|
MsgValue: [
|
||||||
@ -33,13 +30,6 @@ export function createTxMsgReserveAuthority(
|
|||||||
memo: string,
|
memo: string,
|
||||||
params: MessageMsgReserveAuthority,
|
params: MessageMsgReserveAuthority,
|
||||||
) {
|
) {
|
||||||
// EIP712
|
|
||||||
const feeObject = generateFee(
|
|
||||||
fee.amount,
|
|
||||||
fee.denom,
|
|
||||||
fee.gas,
|
|
||||||
sender.accountAddress,
|
|
||||||
)
|
|
||||||
const types = generateTypes(MSG_RESERVE_AUTHORITY_TYPES)
|
const types = generateTypes(MSG_RESERVE_AUTHORITY_TYPES)
|
||||||
|
|
||||||
const msg = createMsgReserveAuthority(
|
const msg = createMsgReserveAuthority(
|
||||||
@ -48,41 +38,13 @@ export function createTxMsgReserveAuthority(
|
|||||||
params.owner
|
params.owner
|
||||||
)
|
)
|
||||||
|
|
||||||
const messages = generateMessage(
|
|
||||||
sender.accountNumber.toString(),
|
|
||||||
sender.sequence.toString(),
|
|
||||||
chain.cosmosChainId,
|
|
||||||
memo,
|
|
||||||
feeObject,
|
|
||||||
msg,
|
|
||||||
)
|
|
||||||
const eipToSign = createEIP712(types, chain.chainId, messages)
|
|
||||||
|
|
||||||
// Cosmos
|
|
||||||
const msgCosmos = protoCreateMsgReserveAuthority(
|
const msgCosmos = protoCreateMsgReserveAuthority(
|
||||||
params.name,
|
params.name,
|
||||||
sender.accountAddress,
|
sender.accountAddress,
|
||||||
params.owner
|
params.owner
|
||||||
)
|
)
|
||||||
|
|
||||||
const tx = createTransaction(
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
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 createMsgReserveAuthority(
|
function createMsgReserveAuthority(
|
79
src/messages/util.ts
Normal file
79
src/messages/util.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { Message } from "google-protobuf";
|
||||||
|
import {
|
||||||
|
createEIP712,
|
||||||
|
generateFee,
|
||||||
|
generateMessage,
|
||||||
|
generateTypes,
|
||||||
|
} from '@tharsis/eip712'
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
Sender,
|
||||||
|
Fee,
|
||||||
|
} from '@tharsis/transactions'
|
||||||
|
import { createTransaction } from '@tharsis/proto'
|
||||||
|
|
||||||
|
interface Msg {
|
||||||
|
type: string
|
||||||
|
value: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MsgCosmos {
|
||||||
|
message: Message
|
||||||
|
path: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Types {
|
||||||
|
[key: string]: Array<{
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createTx = (
|
||||||
|
chain: Chain,
|
||||||
|
sender: Sender,
|
||||||
|
fee: Fee,
|
||||||
|
memo: string,
|
||||||
|
messageTypes: Types,
|
||||||
|
msg: Msg,
|
||||||
|
msgCosmos: MsgCosmos,
|
||||||
|
) => {
|
||||||
|
// EIP712
|
||||||
|
const feeObject = generateFee(
|
||||||
|
fee.amount,
|
||||||
|
fee.denom,
|
||||||
|
fee.gas,
|
||||||
|
sender.accountAddress,
|
||||||
|
)
|
||||||
|
const types = generateTypes(messageTypes)
|
||||||
|
|
||||||
|
const messages = generateMessage(
|
||||||
|
sender.accountNumber.toString(),
|
||||||
|
sender.sequence.toString(),
|
||||||
|
chain.cosmosChainId,
|
||||||
|
memo,
|
||||||
|
feeObject,
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
const eipToSign = createEIP712(types, chain.chainId, messages)
|
||||||
|
|
||||||
|
// Cosmos
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,11 @@ import assert from 'assert';
|
|||||||
|
|
||||||
import { Account } from './account';
|
import { Account } from './account';
|
||||||
import { Registry } from './index';
|
import { Registry } from './index';
|
||||||
import { getConfig, wait } from './testing/helper';
|
import { getConfig } from './testing/helper';
|
||||||
|
|
||||||
jest.setTimeout(120 * 1000);
|
jest.setTimeout(120 * 1000);
|
||||||
|
|
||||||
const { mockServer, chibaClonk: { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } } = getConfig();
|
const { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } = getConfig();
|
||||||
|
|
||||||
const namingTests = () => {
|
const namingTests = () => {
|
||||||
let registry: Registry;
|
let registry: Registry;
|
||||||
@ -21,13 +21,11 @@ const namingTests = () => {
|
|||||||
// Create bond.
|
// Create bond.
|
||||||
bondId = await registry.getNextBondId(accountAddress);
|
bondId = await registry.getNextBondId(accountAddress);
|
||||||
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
||||||
await wait(5000)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Reserve authority.', async () => {
|
test('Reserve authority.', async () => {
|
||||||
authorityName = `dxos-${Date.now()}`;
|
authorityName = `dxos-${Date.now()}`;
|
||||||
await registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee);
|
await registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee);
|
||||||
await wait(5000)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Lookup authority.', async () => {
|
test('Lookup authority.', async () => {
|
||||||
@ -54,7 +52,6 @@ const namingTests = () => {
|
|||||||
test('Reserve sub-authority.', async () => {
|
test('Reserve sub-authority.', async () => {
|
||||||
const subAuthority = `echo.${authorityName}`;
|
const subAuthority = `echo.${authorityName}`;
|
||||||
await registry.reserveAuthority({ name: subAuthority, owner: accountAddress }, accountAddress, privateKey, fee);
|
await registry.reserveAuthority({ name: subAuthority, owner: accountAddress }, accountAddress, privateKey, fee);
|
||||||
await wait(5000)
|
|
||||||
|
|
||||||
const [record] = await registry.lookupAuthorities([subAuthority]);
|
const [record] = await registry.lookupAuthorities([subAuthority]);
|
||||||
expect(record).toBeDefined();
|
expect(record).toBeDefined();
|
||||||
@ -77,11 +74,8 @@ const namingTests = () => {
|
|||||||
assert(otherAccount2.formattedCosmosAddress)
|
assert(otherAccount2.formattedCosmosAddress)
|
||||||
await registry.sendCoins({ denom: 'aphoton', amount: '10', destinationAddress: otherAccount2.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
await registry.sendCoins({ denom: 'aphoton', amount: '10', destinationAddress: otherAccount2.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
await wait(5000)
|
|
||||||
|
|
||||||
const subAuthority = `halo.${authorityName}`;
|
const subAuthority = `halo.${authorityName}`;
|
||||||
await registry.reserveAuthority({ name: subAuthority, owner: otherAccount1.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
await registry.reserveAuthority({ name: subAuthority, owner: otherAccount1.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||||
await wait(5000)
|
|
||||||
|
|
||||||
const [record] = await registry.lookupAuthorities([subAuthority]);
|
const [record] = await registry.lookupAuthorities([subAuthority]);
|
||||||
expect(record).toBeDefined();
|
expect(record).toBeDefined();
|
||||||
@ -92,7 +86,7 @@ const namingTests = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mockServer || process.env.WIRE_AUCTIONS_ENABLED) {
|
if (process.env.AUCTIONS_ENABLED) {
|
||||||
// Required as jest complains if file has no tests.
|
// Required as jest complains if file has no tests.
|
||||||
test('skipping naming tests', () => {});
|
test('skipping naming tests', () => {});
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
const DEFAULT_PRIVATE_KEY = '39e06e1471f69a76491e60d1d22908789bf7801039a9ac2197ed432ad45d2daf';
|
import assert from 'assert';
|
||||||
const DEFAULT_ADDRESS = 'ethm1p9fqwtlypqptuqgndpce5g6wncj4py9z30wfkt'
|
|
||||||
|
|
||||||
export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time))
|
export const getConfig = () => {
|
||||||
|
assert(process.env.PRIVATE_KEY);
|
||||||
|
assert(process.env.ACCOUNT_ADDRESS);
|
||||||
|
|
||||||
export const getConfig = () => ({
|
return {
|
||||||
mockServer: process.env.MOCK_SERVER || false,
|
|
||||||
chibaClonk: {
|
|
||||||
chainId: process.env.CHIBA_CLONK_CHAIN_ID || 'ethermint_9000-1',
|
chainId: process.env.CHIBA_CLONK_CHAIN_ID || 'ethermint_9000-1',
|
||||||
privateKey: DEFAULT_PRIVATE_KEY,
|
privateKey: process.env.PRIVATE_KEY,
|
||||||
accountAddress: DEFAULT_ADDRESS,
|
accountAddress: process.env.ACCOUNT_ADDRESS,
|
||||||
restEndpoint: process.env.CHIBA_CLONK_REST_ENDPOINT || 'http://localhost:1317',
|
restEndpoint: process.env.CHIBA_CLONK_REST_ENDPOINT || 'http://localhost:1317',
|
||||||
gqlEndpoint: process.env.CHIBA_CLONK_GQL_ENDPOINT || 'http://localhost:9473/api',
|
gqlEndpoint: process.env.CHIBA_CLONK_GQL_ENDPOINT || 'http://localhost:9473/api',
|
||||||
fee: {
|
fee: {
|
||||||
@ -17,4 +16,4 @@ export const getConfig = () => ({
|
|||||||
gas: '200000',
|
gas: '200000',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user