/** * @packageDocumentation * @module harmony-transaction * @ignore */ import { TransactionFactory, Transaction, TxStatus } from '../src'; // tslint:disable-next-line: no-implicit-dependencies import { Wallet } from '@harmony-js/account'; import { HttpProvider, Messenger } from '@harmony-js/network'; import { ChainType, ChainID } from '@harmony-js/utils'; import { toChecksumAddress, randomBytes } from '@harmony-js/crypto'; // tslint:disable-next-line: no-implicit-dependencies import fetch from 'jest-fetch-mock'; const http = new HttpProvider('http://mock.com'); // const ws = new WSProvider('ws://mock.com'); const addr = toChecksumAddress('0x' + randomBytes(20)); const msgHttp = new Messenger(http, ChainType.Harmony, ChainID.HmyLocal); // const msgWs = new Messenger(ws, ChainType.Harmony, ChainID.HmyLocal); const walletHttp = new Wallet(msgHttp); // const walletWs = new Wallet(msgWs); describe('test send transaction', () => { beforeEach(() => { // jest.useFakeTimers(); }); afterEach(() => { fetch.resetMocks(); // jest.clearAllTimers(); }); it('should test wallet sign and send', async () => { const responses = [ { jsonrpc: '2.0', id: 1, result: '0x666666666666', }, { jsonrpc: '2.0', id: 1, result: '0x1', }, { jsonrpc: '2.0', id: 1, result: '0x7e1ef610f700805b93cf85b1e55bce84fcbd04373252a968755366a8d2215424', }, ].map((res) => [JSON.stringify(res)] as [string]); fetch.mockResponses(...responses); const factory = new TransactionFactory(msgHttp); const tx: Transaction = factory.newTx( { to: addr, value: '1', gasLimit: '21000', gasPrice: '1', }, false, ); expect(tx.txStatus).toEqual(TxStatus.INTIALIZED); const account: any | Account = await walletHttp.createAccount(); const signed: Transaction = await account.signTransaction(tx, true, 'rlp', 'latest'); expect(signed.txStatus).toEqual(TxStatus.SIGNED); expect(signed.txParams.nonce).toEqual(1); expect(signed.txPayload.nonce).toEqual('0x1'); expect(signed.txParams.signature.r).toBeTruthy(); expect(signed.txParams.signature.s).toBeTruthy(); expect(signed.txParams.signature.v).toBeTruthy(); expect(signed.txParams.rawTransaction).toEqual(signed.getRawTransaction()); const [sent, hash] = await signed.sendTransaction(); expect(sent.txParams.id).toEqual(hash); expect(sent.txStatus).toEqual(TxStatus.PENDING); }); it('should test wallet sign and send shardingTransaction', async () => { const factory = new TransactionFactory(msgHttp); const tx: Transaction = factory.newTx( { to: addr + '-1', value: '1', gasLimit: '21000', gasPrice: '1', }, true, ); expect(tx.cxStatus).toEqual(TxStatus.INTIALIZED); }); it('should reject and confirm tx', async () => { const responses = [ { jsonrpc: '2.0', id: 1, result: [ { current: true, http: 'http://localhost', shardID: 0, ws: 'ws://localhost', }, { current: false, http: 'http://localhost', shardID: 1, ws: 'ws://localhost', }, ], }, { jsonrpc: '2.0', id: 5, result: '0x0', }, { jsonrpc: '2.0', id: 5, result: '0x1', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x1', }, // attemp 1 { jsonrpc: '2.0', id: 5, result: '0x2', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x2', }, // attemp 2 { jsonrpc: '2.0', id: 5, result: '0x3', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x3', }, // attemp 3 { jsonrpc: '2.0', id: 5, result: '0x4', }, { jsonrpc: '2.0', id: 5, result: '0x5', }, { jsonrpc: '2.0', id: 3, result: { blockHash: '0x7ef01c8532dbe8ae9930ebf3d38cf5f3937193c3c90680d4e9d5206552e4f6a6', blockNumber: '0x1d3c0', contractAddress: null, cumulativeGasUsed: '0x5208', from: 'one1z05g55zamqzfw9qs432n33gycdmyvs38xjemyl', gasUsed: '0x5208', logs: [], logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', shardID: 0, status: '0x1', to: 'one1z05g55zamqzfw9qs432n33gycdmyvs38xjemyl', transactionHash: '0x1bb3cadb2031e5ce987b0c557abe134986b9834963dd0d54f75a9c7d966606ce', transactionIndex: '0x0', }, }, { jsonrpc: '2.0', id: 5, result: '0x5', }, ].map((res) => [JSON.stringify(res)] as [string]); fetch.mockResponses(...responses); const hash = '0x7e1ef610f700805b93cf85b1e55bce84fcbd04373252a968755366a8d2215424'; const factory = new TransactionFactory(msgHttp); const shardID = 0; const toShardID = 1; const tx: Transaction = factory.newTx({ shardID, toShardID }, false); expect(tx.cxStatus).toEqual(TxStatus.INTIALIZED); await tx.messenger.setShardingProviders(); await expect(tx.txConfirm(hash, 3, 100, shardID)).rejects.toThrow( 'The transaction is still not confirmed after 3 attempts.', ); const confirmed = await tx.txConfirm(hash, 4, 100, shardID); expect(confirmed.txStatus).toEqual(TxStatus.CONFIRMED); }); it('should reject and confirm cx', async () => { const responses = [ { jsonrpc: '2.0', id: 1, result: [ { current: true, http: 'http://localhost', shardID: 0, ws: 'ws://localhost', }, { current: false, http: 'http://localhost', shardID: 1, ws: 'ws://localhost', }, ], }, { jsonrpc: '2.0', id: 5, result: '0x0', }, { jsonrpc: '2.0', id: 5, result: '0x1', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x1', }, // attemp 1 { jsonrpc: '2.0', id: 5, result: '0x2', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x2', }, // attemp 2 { jsonrpc: '2.0', id: 5, result: '0x3', }, { jsonrpc: '2.0', id: 5, result: null, }, { jsonrpc: '2.0', id: 5, result: '0x3', }, // attemp 3 { jsonrpc: '2.0', id: 5, result: '0x4', }, { jsonrpc: '2.0', id: 5, result: '0x5', }, { jsonrpc: '2.0', id: 6, result: { blockHash: '0xd92f3610d52bde907ab42e064d73c2314c058015a7162ee8a4500bc581903cc2', blockNumber: '0x18465', hash: '0xcff4a3a6fd4eb34b9a7e48e3eca0c8c899de71a1ea21a126cc1048e65b332a72', from: 'one1v5fevthrnfeqjwcl5p0sfq3u34c2gmtqq095at', to: 'one18spwh74s5hkg2nva40scx7hwdjpup28dw4dfsg', shardID: 0, toShardID: 1, value: '0xde0b6b3a7640000', }, }, { jsonrpc: '2.0', id: 5, result: '0x5', }, ].map((res) => [JSON.stringify(res)] as [string]); fetch.mockResponses(...responses); const hash = '0x7e1ef610f700805b93cf85b1e55bce84fcbd04373252a968755366a8d2215424'; const factory = new TransactionFactory(msgHttp); const shardID = 0; const toShardID = 1; const tx: Transaction = factory.newTx({ shardID, toShardID }, false); expect(tx.cxStatus).toEqual(TxStatus.INTIALIZED); await tx.messenger.setShardingProviders(); await expect(tx.cxConfirm(hash, 3, 100, toShardID)).rejects.toThrow( 'The transaction is still not confirmed after 3 attempts.', ); const confirmed = await tx.cxConfirm(hash, 4, 100, toShardID); expect(confirmed.cxStatus).toEqual(TxStatus.CONFIRMED); }); it('should confirm and confirm cx', async () => { const responses = [ { jsonrpc: '2.0', id: 1, result: [ { current: true, http: 'http://localhost', shardID: 0, ws: 'ws://localhost', }, { current: false, http: 'http://localhost', shardID: 1, ws: 'ws://localhost', }, ], }, { jsonrpc: '2.0', id: 5, result: '0x0', }, { jsonrpc: '2.0', id: 5, result: '0x1', }, { jsonrpc: '2.0', id: 3, result: { blockHash: '0x7ef01c8532dbe8ae9930ebf3d38cf5f3937193c3c90680d4e9d5206552e4f6a6', blockNumber: '0x1d3c0', contractAddress: null, cumulativeGasUsed: '0x5208', from: 'one1z05g55zamqzfw9qs432n33gycdmyvs38xjemyl', gasUsed: '0x5208', logs: [], logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', shardID: 0, status: '0x1', to: 'one1z05g55zamqzfw9qs432n33gycdmyvs38xjemyl', transactionHash: '0x1bb3cadb2031e5ce987b0c557abe134986b9834963dd0d54f75a9c7d966606ce', transactionIndex: '0x0', }, }, { jsonrpc: '2.0', id: 5, result: '0x1', }, { jsonrpc: '2.0', id: 5, result: '0x4', }, { jsonrpc: '2.0', id: 5, result: '0x5', }, { jsonrpc: '2.0', id: 6, result: { blockHash: '0xd92f3610d52bde907ab42e064d73c2314c058015a7162ee8a4500bc581903cc2', blockNumber: '0x18465', hash: '0xcff4a3a6fd4eb34b9a7e48e3eca0c8c899de71a1ea21a126cc1048e65b332a72', from: 'one1v5fevthrnfeqjwcl5p0sfq3u34c2gmtqq095at', to: 'one18spwh74s5hkg2nva40scx7hwdjpup28dw4dfsg', shardID: 0, toShardID: 1, value: '0xde0b6b3a7640000', }, }, { jsonrpc: '2.0', id: 5, result: '0x5', }, ].map((res) => [JSON.stringify(res)] as [string]); fetch.mockResponses(...responses); const hash = '0x7e1ef610f700805b93cf85b1e55bce84fcbd04373252a968755366a8d2215424'; const factory = new TransactionFactory(msgHttp); const shardID = 0; const toShardID = 1; const tx: Transaction = factory.newTx({ shardID, toShardID }, false); expect(tx.txStatus).toEqual(TxStatus.INTIALIZED); expect(tx.cxStatus).toEqual(TxStatus.INTIALIZED); await tx.messenger.setShardingProviders(); tx.observed() .on('track', (track) => { expect(track).toBeTruthy(); }) .on('confirmation', (confirmation) => { expect(confirmation).toBeTruthy(); }); const confirmed = await tx.confirm(hash); expect(confirmed.isSigned()).toEqual(false); expect(confirmed.isPending()).toEqual(false); expect(confirmed.isRejected()).toEqual(false); expect(confirmed.isInitialized()).toEqual(false); expect(confirmed.isConfirmed()).toEqual(true); expect(confirmed.isCxPending()).toEqual(false); expect(confirmed.isCxRejected()).toEqual(false); expect(confirmed.isCxConfirmed()).toEqual(true); confirmed.setCxStatus(confirmed.cxStatus); confirmed.setTxStatus(confirmed.txStatus); expect(confirmed.getTxStatus()).toEqual(TxStatus.CONFIRMED); expect(confirmed.getCxStatus()).toEqual(TxStatus.CONFIRMED); }); });