[fix] update a lot and add test fixtures for transaction

dev
neeboo 6 years ago
parent 225500b64a
commit ce86e56a63
  1. 2
      package.json
  2. 4
      packages/harmony-account/src/account.ts
  3. 17
      packages/harmony-account/src/utils.ts
  4. 2
      packages/harmony-account/tsconfig.test.json
  5. 0
      packages/harmony-contract/test/abiCoder.test.ts
  6. 0
      packages/harmony-contract/test/fixtures/abiv2.ts
  7. 2
      packages/harmony-contract/tsconfig.test.json
  8. 0
      packages/harmony-core/test/blockchain.test.ts
  9. 2
      packages/harmony-core/tsconfig.test.json
  10. 0
      packages/harmony-crypto/test/base58.test.ts
  11. 0
      packages/harmony-crypto/test/base58fixture.ts
  12. 2
      packages/harmony-crypto/tsconfig.test.json
  13. 2
      packages/harmony-network/tsconfig.test.json
  14. 4
      packages/harmony-transaction/src/factory.ts
  15. 50
      packages/harmony-transaction/src/transaction.ts
  16. 1
      packages/harmony-transaction/src/types.ts
  17. 114
      packages/harmony-transaction/src/utils.ts
  18. 97
      packages/harmony-transaction/test/testSign.test.ts
  19. 15824
      packages/harmony-transaction/test/transactions.fixture.json
  20. 0
      packages/harmony-transaction/test/tsconfig.json
  21. 0
      packages/harmony-utils/test/fixture.ts
  22. 3
      packages/harmony-utils/test/tsconfig.json
  23. 0
      packages/harmony-utils/test/validators.test.ts
  24. 33
      scripts/jest/jest.src.config.js
  25. 3
      tsconfig.test.json

@ -13,6 +13,7 @@
"bootstrap": "lerna bootstrap", "bootstrap": "lerna bootstrap",
"build": "yarn build:proto && yarn build:ts", "build": "yarn build:proto && yarn build:ts",
"build:ts": "tsc -b tsconfig.json", "build:ts": "tsc -b tsconfig.json",
"build:test":"tsc -b tsconfig.test.json",
"bundle": "ts-node -P scripts/tsconfig.json scripts/bundle.ts umd,esm", "bundle": "ts-node -P scripts/tsconfig.json scripts/bundle.ts umd,esm",
"clean": "lerna clean --yes && lerna run clean && rimraf includes", "clean": "lerna clean --yes && lerna run clean && rimraf includes",
"schema": "ts-node -P scripts/tsconfig.json scripts/typings/schema.ts core", "schema": "ts-node -P scripts/tsconfig.json scripts/typings/schema.ts core",
@ -75,6 +76,7 @@
"dotenv": "^6.0.0", "dotenv": "^6.0.0",
"fancy-log": "^1.3.2", "fancy-log": "^1.3.2",
"fbjs-scripts": "^0.8.3", "fbjs-scripts": "^0.8.3",
"ganache-cli": "^6.4.3",
"glob": "^7.1.3", "glob": "^7.1.3",
"glob-parent": "^3.1.0", "glob-parent": "^3.1.0",
"gulp": "^4.0.0", "gulp": "^4.0.0",

@ -11,10 +11,10 @@ import {
} from '@harmony-js/crypto'; } from '@harmony-js/crypto';
import { isPrivateKey, add0xToString, hexToNumber } from '@harmony-js/utils'; import { isPrivateKey, add0xToString, hexToNumber } from '@harmony-js/utils';
import { Transaction } from '@harmony-js/transaction'; import { Transaction, RLPSign } from '@harmony-js/transaction';
import { Messenger, RPCMethod } from '@harmony-js/network'; import { Messenger, RPCMethod } from '@harmony-js/network';
import { Shards } from './types'; import { Shards } from './types';
import { RLPSign, defaultMessenger } from './utils'; import { defaultMessenger } from './utils';
class Account { class Account {
/** /**

@ -1,23 +1,6 @@
import { HttpProvider, Messenger } from '@harmony-js/network'; import { HttpProvider, Messenger } from '@harmony-js/network';
import { Transaction, TxParams } from '@harmony-js/transaction';
import { sign, keccak256, Signature } from '@harmony-js/crypto';
import { ChainType } from '@harmony-js/utils'; import { ChainType } from '@harmony-js/utils';
export const RLPSign = (
transaction: Transaction,
prv: string,
): [Signature, string] => {
const [unsignedTxnHash, raw] = transaction.getRLPUnsigned();
const regroup: TxParams = {
...transaction.txParams,
unsignedTxnHash,
};
transaction.setParams(regroup);
const signature = sign(keccak256(unsignedTxnHash), prv);
const signed = transaction.getRLPSigned(raw, signature);
return [signature, signed];
};
export const defaultMessenger = new Messenger( export const defaultMessenger = new Messenger(
new HttpProvider('http://localhost:8545'), new HttpProvider('http://localhost:8545'),
ChainType.Harmony, ChainType.Harmony,

@ -1,5 +1,5 @@
{ {
"extends": "../../tsconfig.test.json", "extends": "../../tsconfig.test.json",
"include": ["src", "test", "../../typings/**/*.d.ts"], "include": ["src", "__test__", "../../typings/**/*.d.ts"],
"references": [] "references": []
} }

@ -1,5 +1,5 @@
{ {
"extends": "../../tsconfig.test.json", "extends": "../../tsconfig.test.json",
"include": ["src", "test", "../../typings/**/*.d.ts"], "include": ["src", "__test__", "../../typings/**/*.d.ts"],
"references": [] "references": []
} }

@ -1,5 +1,5 @@
{ {
"extends": "../../tsconfig.test.json", "extends": "../../tsconfig.test.json",
"include": ["src", "test", "../../typings/**/*.d.ts"], "include": ["src", "__test__", "../../typings/**/*.d.ts"],
"references": [] "references": []
} }

@ -1,5 +1,5 @@
{ {
"extends": "../../tsconfig.test.json", "extends": "../../tsconfig.test.json",
"include": ["src", "test", "../../typings/**/*.d.ts"], "include": ["src", "__test__", "../../typings/**/*.d.ts"],
"references": [] "references": []
} }

@ -1,5 +1,5 @@
{ {
"extends": "../../tsconfig.test.json", "extends": "../../tsconfig.test.json",
"include": ["src", "test", "../../typings/**/*.d.ts"], "include": ["src", "__test__", "../../typings/**/*.d.ts"],
"references": [] "references": []
} }

@ -3,7 +3,7 @@ import { Messenger } from '@harmony-js/network';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
import { TxParams, TxStatus } from './types'; import { TxParams, TxStatus } from './types';
class TransactionFactory { export class TransactionFactory {
static getContractAddress(tx: Transaction) { static getContractAddress(tx: Transaction) {
const { from, nonce } = tx.txParams; const { from, nonce } = tx.txParams;
return getContractAddress(from, Number.parseInt(`${nonce}`, 10)); return getContractAddress(from, Number.parseInt(`${nonce}`, 10));
@ -39,5 +39,3 @@ class TransactionFactory {
return newTxn; return newTxn;
} }
} }
export { TransactionFactory };

@ -7,7 +7,7 @@ import {
Signature, Signature,
splitSignature, splitSignature,
} from '@harmony-js/crypto'; } from '@harmony-js/crypto';
import { add0xToString, numberToHex } from '@harmony-js/utils'; import { add0xToString, numberToHex, ChainType } from '@harmony-js/utils';
import { import {
Messenger, Messenger,
RPCMethod, RPCMethod,
@ -24,6 +24,8 @@ import {
sleep, sleep,
TransactionEvents, TransactionEvents,
defaultMessenger, defaultMessenger,
transactionFieldsETH,
recoverETH,
} from './utils'; } from './utils';
class Transaction { class Transaction {
@ -38,6 +40,7 @@ class Transaction {
private from: string; private from: string;
private nonce: number | string; private nonce: number | string;
private to: string; private to: string;
private shardID: number | string;
private gasLimit: BN; private gasLimit: BN;
private gasPrice: BN; private gasPrice: BN;
private data: string; private data: string;
@ -49,7 +52,7 @@ class Transaction {
// constructor // constructor
constructor( constructor(
params?: TxParams, params?: TxParams | any,
messenger: Messenger = defaultMessenger, messenger: Messenger = defaultMessenger,
txStatus = TxStatus.INTIALIZED, txStatus = TxStatus.INTIALIZED,
) { ) {
@ -63,6 +66,7 @@ class Transaction {
this.nonce = params ? params.nonce : 0; this.nonce = params ? params.nonce : 0;
this.gasPrice = params ? params.gasPrice : new BN(0); this.gasPrice = params ? params.gasPrice : new BN(0);
this.gasLimit = params ? params.gasLimit : new BN(0); this.gasLimit = params ? params.gasLimit : new BN(0);
this.shardID = params ? params.shardID : 0;
this.to = params ? params.to : '0x'; this.to = params ? params.to : '0x';
this.value = params ? params.value : new BN(0); this.value = params ? params.value : new BN(0);
this.data = params ? params.data : '0x'; this.data = params ? params.data : '0x';
@ -88,7 +92,13 @@ class Transaction {
getRLPUnsigned(): [string, any[]] { getRLPUnsigned(): [string, any[]] {
const raw: Array<string | Uint8Array> = []; const raw: Array<string | Uint8Array> = [];
transactionFields.forEach((field: any) => { // temp setting to be compatible with eth
const fields =
this.messenger.chainType === ChainType.Harmony
? transactionFields
: transactionFieldsETH;
fields.forEach((field: any) => {
let value = (<any>this.txParams)[field.name] || []; let value = (<any>this.txParams)[field.name] || [];
value = arrayify( value = arrayify(
hexlify( hexlify(
@ -126,9 +136,11 @@ class Transaction {
} }
getRLPSigned(raw: any[], signature: Signature): string { getRLPSigned(raw: any[], signature: Signature): string {
// temp setting to be compatible with eth
const rawLength = this.messenger.chainType === ChainType.Harmony ? 10 : 9;
const sig = splitSignature(signature); const sig = splitSignature(signature);
let v = 27 + (sig.recoveryParam || 0); let v = 27 + (sig.recoveryParam || 0);
if (raw.length === 9) { if (raw.length === rawLength) {
raw.pop(); raw.pop();
raw.pop(); raw.pop();
raw.pop(); raw.pop();
@ -143,7 +155,12 @@ class Transaction {
} }
recover(txnHash: string): Transaction { recover(txnHash: string): Transaction {
this.setParams(recover(txnHash)); // temp setting to be compatible with eth
const recovered =
this.messenger.chainType === ChainType.Harmony
? recover(txnHash)
: recoverETH(txnHash);
this.setParams(recovered);
return this; return this;
} }
// use when using eth_sendTransaction // use when using eth_sendTransaction
@ -151,6 +168,7 @@ class Transaction {
return { return {
from: this.txParams.from || '0x', from: this.txParams.from || '0x',
to: this.txParams.to || '0x', to: this.txParams.to || '0x',
shardID: this.txParams.shardID ? numberToHex(this.shardID) : '0x',
gas: this.txParams.gasLimit ? numberToHex(this.txParams.gasLimit) : '0x', gas: this.txParams.gasLimit ? numberToHex(this.txParams.gasLimit) : '0x',
gasPrice: this.txParams.gasPrice gasPrice: this.txParams.gasPrice
? numberToHex(this.txParams.gasPrice) ? numberToHex(this.txParams.gasPrice)
@ -168,6 +186,7 @@ class Transaction {
nonce: this.nonce || 0, nonce: this.nonce || 0,
gasPrice: this.gasPrice || new BN(0), gasPrice: this.gasPrice || new BN(0),
gasLimit: this.gasLimit || new BN(0), gasLimit: this.gasLimit || new BN(0),
shardID: this.shardID || 0,
to: this.to || '0x', to: this.to || '0x',
value: this.value || new BN(0), value: this.value || new BN(0),
data: this.data || '0x', data: this.data || '0x',
@ -183,6 +202,7 @@ class Transaction {
this.nonce = params ? params.nonce : 0; this.nonce = params ? params.nonce : 0;
this.gasPrice = params ? params.gasPrice : new BN(0); this.gasPrice = params ? params.gasPrice : new BN(0);
this.gasLimit = params ? params.gasLimit : new BN(0); this.gasLimit = params ? params.gasLimit : new BN(0);
this.shardID = params ? params.shardID : 0;
this.to = params ? params.to : '0x'; this.to = params ? params.to : '0x';
this.value = params ? params.value : new BN(0); this.value = params ? params.value : new BN(0);
this.data = params ? params.data : '0x'; this.data = params ? params.data : '0x';
@ -292,7 +312,7 @@ class Transaction {
} else { } else {
this.txStatus = TxStatus.PENDING; this.txStatus = TxStatus.PENDING;
const currentBlock = await this.getBlockNumber(); const currentBlock = await this.getBlockNumber();
this.blockNumbers.push(currentBlock); this.blockNumbers.push('0x' + currentBlock.toString('hex'));
this.confirmationCheck += 1; this.confirmationCheck += 1;
return false; return false;
} }
@ -315,17 +335,9 @@ class Transaction {
try { try {
const newBlock = await this.getBlockNumber(); const newBlock = await this.getBlockNumber();
// TODO: this is super ugly, must be a better way doing this // TODO: this is super ugly, must be a better way doing this
const nextBlock = const nextBlock = checkBlock.add(new BN(attempt === 0 ? attempt : 1));
'0x' +
new BN(checkBlock.substring(2), 'hex') if (newBlock.gte(nextBlock)) {
.add(new BN(attempt === 0 ? attempt : 1))
.toString('hex');
if (
new BN(newBlock.substring(2), 'hex').gte(
new BN(nextBlock.substring(2), 'hex'),
)
) {
checkBlock = newBlock; checkBlock = newBlock;
if (await this.trackTx(txHash)) { if (await this.trackTx(txHash)) {
this.emitConfirm(this.txStatus); this.emitConfirm(this.txStatus);
@ -416,13 +428,13 @@ class Transaction {
this.emitter.emit(TransactionEvents.confirmation, data); this.emitter.emit(TransactionEvents.confirmation, data);
} }
async getBlockNumber() { async getBlockNumber(): Promise<BN> {
try { try {
const currentBlock = await this.messenger.send(RPCMethod.BlockNumber, []); const currentBlock = await this.messenger.send(RPCMethod.BlockNumber, []);
if (currentBlock.isError()) { if (currentBlock.isError()) {
throw currentBlock.message; throw currentBlock.message;
} }
return currentBlock.result; return new BN(currentBlock.result.replace('0x', ''), 'hex');
} catch (error) { } catch (error) {
throw error; throw error;
} }

@ -6,6 +6,7 @@ export interface TxParams {
nonce: number | string; nonce: number | string;
gasLimit: BN; gasLimit: BN;
gasPrice: BN; gasPrice: BN;
shardID: number | string;
data: string; data: string;
value: BN; value: BN;
chainId: number; chainId: number;

@ -13,11 +13,24 @@ import {
BN, BN,
hexZeroPad, hexZeroPad,
recoverAddress, recoverAddress,
Signature,
sign,
} from '@harmony-js/crypto'; } from '@harmony-js/crypto';
import { HttpProvider, Messenger } from '@harmony-js/network'; import { HttpProvider, Messenger } from '@harmony-js/network';
import { TxParams } from './types'; import { TxParams } from './types';
import { Transaction } from './transaction';
export const transactionFields = [ export const transactionFields = [
{ name: 'nonce', length: 32, fix: false },
{ name: 'gasPrice', length: 32, fix: false, transform: 'hex' },
{ name: 'gasLimit', length: 32, fix: false, transform: 'hex' },
{ name: 'shardID', length: 32, fix: false },
{ name: 'to', length: 20, fix: true },
{ name: 'value', length: 32, fix: false, transform: 'hex' },
{ name: 'data', fix: false },
];
export const transactionFieldsETH = [
{ name: 'nonce', length: 32, fix: false }, { name: 'nonce', length: 32, fix: false },
{ name: 'gasPrice', length: 32, fix: false, transform: 'hex' }, { name: 'gasPrice', length: 32, fix: false, transform: 'hex' },
{ name: 'gasLimit', length: 32, fix: false, transform: 'hex' }, { name: 'gasLimit', length: 32, fix: false, transform: 'hex' },
@ -47,6 +60,91 @@ export const handleAddress = (value: string): string => {
}; };
export const recover = (rawTransaction: string) => { export const recover = (rawTransaction: string) => {
const transaction = decode(rawTransaction);
if (transaction.length !== 10 && transaction.length !== 7) {
throw new Error('invalid rawTransaction');
}
const tx: TxParams = {
id: '0x',
from: '0x',
txnHash: '0x',
unsignedTxnHash: '0x',
nonce: new BN(strip0x(handleNumber(transaction[0]))).toNumber(),
gasPrice: new BN(strip0x(handleNumber(transaction[1]))),
gasLimit: new BN(strip0x(handleNumber(transaction[2]))),
shardID: new BN(strip0x(handleNumber(transaction[3]))).toNumber(),
to: handleAddress(transaction[4]),
value: new BN(strip0x(handleNumber(transaction[5]))),
data: transaction[6],
chainId: 0,
signature: {
r: '',
s: '',
recoveryParam: 0,
v: 0,
},
};
// Legacy unsigned transaction
if (transaction.length === 7) {
tx.unsignedTxnHash = rawTransaction;
return tx;
}
try {
tx.signature.v = new BN(strip0x(handleNumber(transaction[7]))).toNumber();
} catch (error) {
throw error;
}
tx.signature.r = hexZeroPad(transaction[8], 32);
tx.signature.s = hexZeroPad(transaction[9], 32);
if (
new BN(strip0x(handleNumber(tx.signature.r))).isZero() &&
new BN(strip0x(handleNumber(tx.signature.s))).isZero()
) {
// EIP-155 unsigned transaction
tx.chainId = tx.signature.v;
tx.signature.v = 0;
} else {
// Signed Tranasaction
tx.chainId = Math.floor((tx.signature.v - 35) / 2);
if (tx.chainId < 0) {
tx.chainId = 0;
}
let recoveryParam = tx.signature.v - 27;
const raw = transaction.slice(0, 7);
if (tx.chainId !== 0) {
raw.push(hexlify(tx.chainId));
raw.push('0x');
raw.push('0x');
recoveryParam -= tx.chainId * 2 + 8;
}
const digest = keccak256(encode(raw));
try {
tx.from = recoverAddress(digest, {
r: hexlify(tx.signature.r),
s: hexlify(tx.signature.s),
recoveryParam,
});
} catch (error) {
throw error;
}
tx.txnHash = keccak256(rawTransaction);
}
return tx;
};
export const recoverETH = (rawTransaction: string) => {
const transaction = decode(rawTransaction); const transaction = decode(rawTransaction);
if (transaction.length !== 9 && transaction.length !== 6) { if (transaction.length !== 9 && transaction.length !== 6) {
throw new Error('invalid rawTransaction'); throw new Error('invalid rawTransaction');
@ -60,6 +158,7 @@ export const recover = (rawTransaction: string) => {
nonce: new BN(strip0x(handleNumber(transaction[0]))).toNumber(), nonce: new BN(strip0x(handleNumber(transaction[0]))).toNumber(),
gasPrice: new BN(strip0x(handleNumber(transaction[1]))), gasPrice: new BN(strip0x(handleNumber(transaction[1]))),
gasLimit: new BN(strip0x(handleNumber(transaction[2]))), gasLimit: new BN(strip0x(handleNumber(transaction[2]))),
shardID: 0,
to: handleAddress(transaction[3]), to: handleAddress(transaction[3]),
value: new BN(strip0x(handleNumber(transaction[4]))), value: new BN(strip0x(handleNumber(transaction[4]))),
data: transaction[5], data: transaction[5],
@ -146,3 +245,18 @@ export const defaultMessenger = new Messenger(
new HttpProvider('http://localhost:8545'), new HttpProvider('http://localhost:8545'),
ChainType.Harmony, ChainType.Harmony,
); );
export const RLPSign = (
transaction: Transaction,
prv: string,
): [Signature, string] => {
const [unsignedTxnHash, raw] = transaction.getRLPUnsigned();
const regroup: TxParams = {
...transaction.txParams,
unsignedTxnHash,
};
transaction.setParams(regroup);
const signature = sign(keccak256(unsignedTxnHash), prv);
const signed = transaction.getRLPSigned(raw, signature);
return [signature, signed];
};

@ -0,0 +1,97 @@
import { Transaction } from '../src/transaction';
import { RLPSign } from '../src/utils';
import { TxStatus } from '../src/types';
import { HttpProvider, Messenger } from '@harmony-js/network';
import { isAddress, ChainType, hexToBN } from '@harmony-js/utils';
import { getAddressFromPrivateKey, BN } from '@harmony-js/crypto';
import txnVectors from './transactions.fixture.json';
const provider = new HttpProvider('http://localhost:9500');
describe('test sign tranction', () => {
it('should test sign transaction with ETH settings', () => {
const ethMessenger = new Messenger(provider, ChainType.Ethereum);
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < txnVectors.length; i += 1) {
const vector = txnVectors[i];
const address = getAddressFromPrivateKey(vector.privateKey);
expect(isAddress(address)).toEqual(true);
expect(address).toEqual(vector.accountAddress);
const transaction: Transaction = new Transaction(
{
gasLimit:
vector.gasLimit && vector.gasLimit !== '0x'
? hexToBN(vector.gasLimit)
: new BN(0),
gasPrice:
vector.gasPrice && vector.gasPrice !== '0x'
? hexToBN(vector.gasPrice)
: new BN(0),
to: vector.to || '0x',
value:
vector.value && vector.value !== '0x'
? hexToBN(vector.value)
: new BN(0),
data: vector.data || '0x',
nonce:
vector.nonce && vector.nonce !== '0x'
? hexToBN(vector.nonce).toNumber()
: 0,
},
ethMessenger,
TxStatus.INTIALIZED,
);
const unsigned = transaction.getRLPUnsigned();
expect(unsigned[0]).toEqual(vector.unsignedTransaction);
const signed = RLPSign(transaction, vector.privateKey);
expect(signed[0]).toEqual(vector.signedTransaction);
}
});
it('should test recover from ETHSignedtransaction', () => {
const ethMessenger = new Messenger(provider, ChainType.Ethereum);
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < txnVectors.length; i += 1) {
const vector = txnVectors[i];
const transaction: Transaction = new Transaction(
{},
ethMessenger,
TxStatus.INTIALIZED,
);
transaction.recover(vector.signedTransaction);
if (vector.gasLimit && vector.gasLimit !== '0x') {
expect(transaction.txParams.gasLimit.toString()).toEqual(
hexToBN(vector.gasLimit).toString(),
);
}
if (vector.gasPrice && vector.gasPrice !== '0x') {
expect(transaction.txParams.gasPrice.toString()).toEqual(
hexToBN(vector.gasPrice).toString(),
);
}
if (vector.nonce && vector.nonce !== '0x') {
expect(transaction.txParams.nonce).toEqual(
hexToBN(vector.nonce).toNumber(),
);
}
if (vector.data) {
expect(transaction.txParams.data).toEqual(vector.data);
}
if (vector.value && vector.value !== '0x') {
expect(transaction.txParams.value.toString()).toEqual(
hexToBN(vector.value).toString(),
);
}
if (vector.to && vector.to !== '0x') {
expect(transaction.txParams.to).toEqual(vector.to);
}
expect(transaction.txParams.from).toEqual(vector.accountAddress);
}
});
});

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
{
"extends": "../tsconfig.test.json"
}

@ -10,22 +10,22 @@ const config = {
}, },
}, },
testMatch: [ testMatch: [
// '<rootDir>/packages/**/__test__/?(*.)+(spec|test).js', // '<rootDir>/packages/**/test/?(*.)+(spec|test).js',
// '<rootDir>/packages/laksa-account/__test__/?(*.)+(spec|test).js', // '<rootDir>/packages/laksa-account/test/?(*.)+(spec|test).js',
'<rootDir>/packages/harmony-core/__test__/?(*.)+(spec|test).ts', '<rootDir>/packages/harmony-core/test/?(*.)+(spec|test).ts',
// '<rootDir>/packages/laksa-core/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa-core/test/?(*.)+(spec|test).js'
// '<rootDir>/packages/laksa-core-contract/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa-core-contract/test/?(*.)+(spec|test).js'
'<rootDir>/packages/harmony-crypto/__test__/?(*.)+(spec|test).ts', '<rootDir>/packages/harmony-crypto/test/?(*.)+(spec|test).ts',
'<rootDir>/packages/harmony-contract/__test__/?(*.)+(spec|test).ts', '<rootDir>/packages/harmony-contract/test/?(*.)+(spec|test).ts',
// '<rootDir>/packages/laksa-core-messenger/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa-core-messenger/test/?(*.)+(spec|test).js'
// '<rootDir>/packages/laksa-core-provider/__test__/?(*.)+(spec|test).js', // '<rootDir>/packages/laksa-core-provider/test/?(*.)+(spec|test).js',
// '<rootDir>/packages/laksa-core-transaction/__test__/?(*.)+(spec|test).js', '<rootDir>/packages/harmony-transaction/test/?(*.)+(spec|test).ts',
// '<rootDir>/packages/laksa-extend-keystore/__test__/?(*.)+(spec|test).js', // '<rootDir>/packages/laksa-extend-keystore/test/?(*.)+(spec|test).js',
// '<rootDir>/packages/laksa-providers-http/__test__/?(*.)+(spec|test).js', // '<rootDir>/packages/laksa-providers-http/test/?(*.)+(spec|test).js',
// '<rootDir>/packages/laksa-shared/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa-shared/test/?(*.)+(spec|test).js'
'<rootDir>/packages/harmony-utils/__test__/?(*.)+(spec|test).ts', '<rootDir>/packages/harmony-utils/test/?(*.)+(spec|test).ts',
// '<rootDir>/packages/laksa-wallet/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa-wallet/test/?(*.)+(spec|test).js'
// '<rootDir>/packages/laksa/__test__/?(*.)+(spec|test).js' // '<rootDir>/packages/laksa/test/?(*.)+(spec|test).js'
], ],
moduleDirectories: ['src', 'node_modules'], moduleDirectories: ['src', 'node_modules'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
@ -48,6 +48,7 @@ const config = {
'packages/harmony-core/src/**/*.ts', 'packages/harmony-core/src/**/*.ts',
'packages/harmony-utils/src/**/*.ts', 'packages/harmony-utils/src/**/*.ts',
'packages/harmony-crypto/src/**/*.ts', 'packages/harmony-crypto/src/**/*.ts',
'packages/harmony-transaction/src/**/*.ts',
], ],
timers: 'fake', timers: 'fake',
setupFiles: ['<rootDir>/scripts/jest/jest.setup.js'], setupFiles: ['<rootDir>/scripts/jest/jest.setup.js'],

@ -8,6 +8,7 @@
{ "path": "packages/harmony-crypto" }, { "path": "packages/harmony-crypto" },
{ "path": "packages/harmony-utils" }, { "path": "packages/harmony-utils" },
{ "path": "packages/harmony-network" }, { "path": "packages/harmony-network" },
{ "path": "packages/harmony-transaction" } { "path": "packages/harmony-transaction" },
{ "path": "packages/harmony-contract" }
] ]
} }

Loading…
Cancel
Save