import { Transaction , Wallet } from '@zilliqa-js/account' ; import { HTTPProvider } from '@zilliqa-js/core' ; import { BN , Long } from '@zilliqa-js/util' ; import { Blockchain } from '../src/chain' ; import fetch , { MockParams } from 'jest-fetch-mock' ; const provider = new HTTPProvider ( 'https://mock.com' ) ; const wallet = new Wallet ( provider ) ; for ( let i = 0 ; i < 10 ; i ++ ) { wallet . create ( ) ; } const blockchain = new Blockchain ( provider , wallet ) ; const getExpectedReq = ( method , params ) => { return { url : 'https://mock.com' , payload : { id : 1 , jsonrpc : '2.0' , method , params , } , } ; } ; describe ( 'Module: Blockchain' , ( ) => { afterEach ( ( ) => { fetch . resetMocks ( ) ; } ) ; it ( 'should sign and send transactions' , async ( ) => { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : 'some_hash' , Info : 'Non-contract txn, sent to shard' , } , } , { id : 1 , jsonrpc : '2.0' , result : { ID : 'some_hash' , receipt : { success : true } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const { txParams } = await blockchain . createTransaction ( tx ) ; expect ( txParams ) . toHaveProperty ( 'signature' ) ; expect ( txParams ) . toHaveProperty ( 'pubKey' ) ; expect ( tx . isConfirmed ( ) ) . toEqual ( true ) ; } ) ; it ( 'should send raw transactions' , async ( ) => { const payload = '{"version":65537,"nonce":2,"toAddr":"39550aB45D74cCe5feF70e857c1326b2d9bEE096","pubKey":"03bb0637134af801bcc912f7cf61448aed05fea21f4a6460a7f15a48c8704f2aea","amount":"0","gasPrice":"1000000000","gasLimit":"40000","code":"","data":"{\\"_tag\\":\\"ProxyTransfer\\",\\"params\\":[{\\"vname\\":\\"to\\",\\"type\\":\\"ByStr20\\",\\"value\\":\\"0x0200a288be83e2a2061d7519d3397b3c6da05f29\\"},{\\"vname\\":\\"value\\",\\"type\\":\\"Uint128\\",\\"value\\":\\"10000000\\"}]}","signature":"8ae91f246b428248c73d6646e3c6d57ceb7877ad9d074e867b4860fbe7d248fbedfbd2a37822ab8610305756f643b76c62f2c7573c6ef0240e6af32d7ff106e6","priority":false}' ; const responses = [ { id : 1 , jsonrpc : '2.0' , result : { TranID : 'some_hash' , receipt : { success : true } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const id = await blockchain . createTransactionRaw ( payload ) ; expect ( id ) . toEqual ( 'some_hash' ) ; } ) ; it ( 'should handle error properly while sending raw transactions' , async ( ) => { const payload = '{"version":65537,"nonce":2,"toAddr":"39550aB45D74cCe5feF70e857c1326b2d9bEE096","pubKey":"03bb0637134af801bcc912f7cf61448aed05fea21f4a6460a7f15a48c8704f2aea","amount":"0","gasPrice":"1000000000","gasLimit":"40000","code":"","data":"{\\"_tag\\":\\"ProxyTransfer\\",\\"params\\":[{\\"vname\\":\\"to\\",\\"type\\":\\"ByStr20\\",\\"value\\":\\"0x0200a288be83e2a2061d7519d3397b3c6da05f29\\"},{\\"vname\\":\\"value\\",\\"type\\":\\"Uint128\\",\\"value\\":\\"10000000\\"}]}","signature":"8ae91f246b428248c73d6646e3c6d57ceb7877ad9d074e867b4860fbe7d248fbedfbd2a37822ab8610305756f643b76c62f2c7573c6ef0240e6af32d7ff106e6","priority":false}' ; const responses = [ { id : 1 , jsonrpc : '2.0' , error : { code : - 8 , message : 'Nonce (1012) lower than current (1012)' , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; try { await blockchain . createTransactionRaw ( payload ) ; } catch ( error ) { expect ( error ) . toEqual ( { code : - 8 , message : 'Nonce (1012) lower than current (1012)' , } ) ; } } ) ; it ( 'should respect the maxAttempts parameter' , async ( ) => { const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : 'some_hash' , Info : 'Non-contract txn, sent to shard' , } , } , ... ( ( ) => { const mocks = [ ] ; for ( let i = 0 ; i < 40 ; i ++ ) { mocks . push ( { id : 1 , jsonrpc : '2.0' , error : { code : - 888 , message : 'Not found' , } , } ) ; } return mocks ; } ) ( ) , { id : 1 , jsonrpc : '2.0' , result : { ID : 'some_hash' , receipt : { cumulative_gas : '1000' , success : true } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const tx = new Transaction ( { version : 0 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; await expect ( blockchain . createTransaction ( tx , 40 , 0 ) ) . rejects . toThrow ( 'The transaction is still not confirmed after 40 attempts.' ) ; } ) ; it ( 'should receive transition array' , async ( ) => { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : 'some_hash' , Info : 'Non-contract txn, sent to shard' , } , } , { id : 1 , jsonrpc : '2.0' , result : { ID : 'some_hash' , receipt : { success : true , transitions : [ { addr : '0xde641801b4c3a87298808ffe260ecf9b32bd958f' , msg : { _amount : '0' , _recipient : '0x0dcca194fa156e388f01b3c4b9993d031d596699' , _tag : 'callback' , params : [ { type : 'String' , value : '5' , vname : 'result' } ] , } , } , ] , } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const { txParams } = await blockchain . createTransaction ( tx ) ; expect ( txParams . receipt ) . not . toBeNull ( ) ; expect ( txParams . receipt ! . transitions ) . toEqual ( [ { addr : '0xde641801b4c3a87298808ffe260ecf9b32bd958f' , msg : { _amount : '0' , _recipient : '0x0dcca194fa156e388f01b3c4b9993d031d596699' , _tag : 'callback' , params : [ { type : 'String' , value : '5' , vname : 'result' } ] , } , } , ] ) ; } ) ; it ( 'validates params for GetTransactionsForTxBlockEx' , async ( ) => { const sampleResponse = { id : '1' , jsonrpc : '2.0' , result : { CurrPage : 2 , NumPages : 5 , Transactions : [ [ '0a9b4733bff6be2d48020f42e561a89d735eeb809eda257b6a56712223e842eb' , '01924067b8d120de35c72bf7213faa12d8b6d20dfc867a027a39799090fd2bad' , '321fe2ed656c622c14d4c7919080086bc95fa57f52a235966cf2c3661dc2fbc5' , '3e0eee38171169b7f179035fd02e40f74d698d05733597115ef67ae2034a7b48' , ] , [ '000d1ab6963ff7c3db82fcce858e93fa264f7d39010099482ab965a518566195' , '6374f8d23d2aa96e3b205a677ad0569bf087d8a099ce90c2869bfca8588f11eb' , '6ad9c1aca7106ace4b836c677ac4a850f611349725358c541741842fb12b4d8d' , 'd116b78ddd5a30bc1a27495f9227af1cd62a90766eaaba7610a395aeab78ee10' , ] , [ ] , [ ] , ] , } , } ; fetch . mockResponse ( JSON . stringify ( sampleResponse ) ) ; const testCases = [ { params : [ - 1 ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 0.1234 ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ Infinity ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 'one' ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 0 ] , expectedReqParams : [ '0' ] , result : sampleResponse , error : undefined , } , { params : [ 10 ] , expectedReqParams : [ '10' ] , result : sampleResponse , error : undefined , } , ] ; for ( const t of testCases ) { if ( t . error ) { try { await blockchain . getTransactionsForTxBlockEx ( t . params [ 0 ] as number ) ; expect ( true ) . toBe ( false ) ; } catch ( error ) { if ( error instanceof Error ) { expect ( error . message ) . toBe ( t . error ) ; } } } else { const res = await blockchain . getTransactionsForTxBlockEx ( t . params [ 0 ] as number ) ; const req = getExpectedReq ( 'GetTransactionsForTxBlockEx' , t . expectedReqParams ) ; const expectedRes = { req , ... t . result } ; expect ( res ) . toEqual ( expectedRes ) ; } } } ) ; it ( 'should receive transaction bodies' , async ( ) => { const responses = [ { id : 1 , jsonrpc : '2.0' , result : [ { ID : 'some_hash' , } , ] , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const result = await blockchain . getTxnBodiesForTxBlock ( 1339810 ) ; expect ( result . result ) . toBeDefined ( ) ; expect ( result . result . length ) . toEqual ( 1 ) ; expect ( result . result [ 0 ] . ID ) . toEqual ( 'some_hash' ) ; } ) ; it ( 'validates params for GetTxnBodiesForTxBlockEx' , async ( ) => { const sampleResponse = { id : '1' , jsonrpc : '2.0' , result : { CurrPage : 2 , NumPages : 5 , Transactions : [ { ID : '0a9b4733bff6be2d48020f42e561a89d735eeb809eda257b6a56712223e842eb' , amount : '0' , gasLimit : '1' , gasPrice : '2000000000' , nonce : '96538' , receipt : { cumulative_gas : '1' , epoch_num : '1002353' , success : true , } , senderPubKey : '0x0235372F21184432428ABCDF99385FFF3A4EC346942B51FACBE9589DDF482C5D45' , signature : '0x1A7CD80504D1BD75C50F751C08FC36ACC0F1A94852048179BCC927A3D5BC297AF01FB0A9CADBEC9AB870D330C8E2931E7025AE1293CE66B7429ABC44E785F16B' , toAddr : '43b358e23092e2d367cedcd08c513fdca2162c01' , version : '65537' , } , { ID : 'd116b78ddd5a30bc1a27495f9227af1cd62a90766eaaba7610a395aeab78ee10' , amount : '0' , gasLimit : '1' , gasPrice : '2000000000' , nonce : '98068' , receipt : { cumulative_gas : '1' , epoch_num : '1002353' , success : true , } , senderPubKey : '0x02FBB56136F2BBC10C963CCB8FA19287926A655023AB137BB018D2C65238D0F481' , signature : '0xC6C4B4060026631F6F79BB5D6B163A51729E11A92D0E217F3ABCD38D2A8E733C62A9EBADA184DEAD5859BBE68ABD888E3A0B194B260FF7A9ACD58523A37EF896' , toAddr : '43b358e23092e2d367cedcd08c513fdca2162c01' , version : '65537' , } , ] , } , } ; fetch . mockResponse ( JSON . stringify ( sampleResponse ) ) ; const testCases = [ { params : [ - 1 ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 0.1234 ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ Infinity ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 'one' ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 0 ] , expectedReqParams : [ '0' ] , result : sampleResponse , error : undefined , } , { params : [ 10 ] , expectedReqParams : [ '10' ] , result : sampleResponse , error : undefined , } , ] ; for ( const t of testCases ) { if ( t . error ) { try { await blockchain . getTxnBodiesForTxBlockEx ( t . params [ 0 ] as number ) ; expect ( true ) . toBe ( false ) ; } catch ( error ) { if ( error instanceof Error ) { expect ( error . message ) . toBe ( t . error ) ; } } } else { const res = await blockchain . getTxnBodiesForTxBlockEx ( t . params [ 0 ] as number ) ; const req = getExpectedReq ( 'GetTxnBodiesForTxBlockEx' , t . expectedReqParams ) ; const expectedRes = { req , ... t . result } ; expect ( res ) . toEqual ( expectedRes ) ; } } } ) ; it ( 'should receive transaction status with confirmed' , async ( ) => { const responses = [ { id : 1 , jsonrpc : '2.0' , result : { ID : '96ba63371a57c9d4d7cbf448dbdd78d209c888a76a30413abd72691c16efffbb' , gasLimit : '1' , gasPrice : '2000000000' , modificationState : 2 , status : 3 , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const result = await blockchain . getTransactionStatus ( '96ba63371a57c9d4d7cbf448dbdd78d209c888a76a30413abd72691c16efffbb' ) ; expect ( result . statusMessage ) . toEqual ( 'Confirmed' ) ; } ) ; it ( 'should receive miner info' , async ( ) => { const responses = [ { id : 1 , jsonrpc : '2.0' , result : { dscommittee : [ '0x03F25E4B68050496086758C33D16C47792F18D1102BB5DFC0CE5E3A57927008A0B' , '0x03CF937B2EBE194C72350A6A7E6612C2D8636A33753929F1553E6273442B2F8E5B' , '0x0372E43C4E7960F02E10F5AFE800E903579E2BE853B160681CBDF7C048FFB78A0F' , ... '0x0397FD33ED459AD72939CA531385271311DA74094D89109F3876E81BEE84B4E414' , ] , shards : [ { nodes : [ '0x0245C0DDAA493700F86A3943260EB04D05DEBD62897E3EC51AE65A704E5C65C0A6' , '0x0250CF4B40C0C984F2BB005599D2A7503F9C68F701A24CBC10B1EB2533575ADBA7' , '0x023F2F657F170563E9B28BF837AB295FD13A7E2A4117DB44B2ADFE536F28D28102' , ... '0x02358F60B4BD90805E6940A901E3C3A5867FFF5BDBD5AD9BFD66FE47C9FA6F1035' , ] , size : 535 , } , { nodes : [ '0x02646640964F472CBE1E9BAF2DC5F1A0915AE529DDFF08F28DDE3E460C755DC8C4' , '0x025EC6741880EC217F921A8FFB4AACDB95FF6477E1BB66CB39950FB2723D3740C8' , '0x03DE42F6719E8A0147A93604C5F6A4304D14AD5F6A70C011EE37DBFC65D1E7F842' , ... '0x02B1DB735BF54FC5765D89248DA1C07934282182F3C65CD9152D8F48C539BB5C53' , ] , size : 535 , } , { nodes : [ '0x0218C2BA9876BCF3EE9EFF220C9F4CF433F5BE09D9D592F3C657AE7353CFFC3245' , '0x02BCD61D2F47165E0CD6B3CF9429140C3F017C440DA63E9F44A84503A7D1E41590' , '0x03E7699C19CFF554D265DC9C797713A7403D99A607EA7C8794259150436EB9FFBB' , ... '0x031169CB469B6083954F578C19FC7833A90D835AA75942820119272FC6EE4361A5' , ] , size : 534 , } , ] , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const result = await blockchain . getMinerInfo ( '5500' ) ; expect ( result . result ) . toBeDefined ( ) ; expect ( result . result . dscommittee ) . toEqual ( [ '0x03F25E4B68050496086758C33D16C47792F18D1102BB5DFC0CE5E3A57927008A0B' , '0x03CF937B2EBE194C72350A6A7E6612C2D8636A33753929F1553E6273442B2F8E5B' , '0x0372E43C4E7960F02E10F5AFE800E903579E2BE853B160681CBDF7C048FFB78A0F' , ... '0x0397FD33ED459AD72939CA531385271311DA74094D89109F3876E81BEE84B4E414' , ] ) ; expect ( result . result . shards ) . toEqual ( [ { nodes : [ '0x0245C0DDAA493700F86A3943260EB04D05DEBD62897E3EC51AE65A704E5C65C0A6' , '0x0250CF4B40C0C984F2BB005599D2A7503F9C68F701A24CBC10B1EB2533575ADBA7' , '0x023F2F657F170563E9B28BF837AB295FD13A7E2A4117DB44B2ADFE536F28D28102' , ... '0x02358F60B4BD90805E6940A901E3C3A5867FFF5BDBD5AD9BFD66FE47C9FA6F1035' , ] , size : 535 , } , { nodes : [ '0x02646640964F472CBE1E9BAF2DC5F1A0915AE529DDFF08F28DDE3E460C755DC8C4' , '0x025EC6741880EC217F921A8FFB4AACDB95FF6477E1BB66CB39950FB2723D3740C8' , '0x03DE42F6719E8A0147A93604C5F6A4304D14AD5F6A70C011EE37DBFC65D1E7F842' , ... '0x02B1DB735BF54FC5765D89248DA1C07934282182F3C65CD9152D8F48C539BB5C53' , ] , size : 535 , } , { nodes : [ '0x0218C2BA9876BCF3EE9EFF220C9F4CF433F5BE09D9D592F3C657AE7353CFFC3245' , '0x02BCD61D2F47165E0CD6B3CF9429140C3F017C440DA63E9F44A84503A7D1E41590' , '0x03E7699C19CFF554D265DC9C797713A7403D99A607EA7C8794259150436EB9FFBB' , ... '0x031169CB469B6083954F578C19FC7833A90D835AA75942820119272FC6EE4361A5' , ] , size : 534 , } , ] ) ; } ) ; it ( 'should test the maxAttempts parameter using blockConfirm' , async ( ) => { const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : 'some_hash' , Info : 'Non-contract txn, sent to shard' , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10001' , } , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10001' , } , } , } , { id : 1 , jsonrpc : '2.0' , error : { code : - 888 , message : 'Not found' , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10002' , } , } , } , { id : 1 , jsonrpc : '2.0' , error : { code : - 888 , message : 'Not found' , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10003' , } , } , } , { id : 1 , jsonrpc : '2.0' , error : { code : - 888 , message : 'Not found' , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10004' , } , } , } , { id : 1 , jsonrpc : '2.0' , error : { code : - 888 , message : 'Not found' , } , } , { id : 1 , jsonrpc : '2.0' , result : { header : { BlockNum : '10004' , } , } , } , { id : 1 , jsonrpc : '2.0' , result : { ID : 'some_hash' , receipt : { cumulative_gas : '1000' , success : true } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const tx = new Transaction ( { version : 0 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; await expect ( blockchain . createTransaction ( tx , 4 , 0 , true ) ) . rejects . toThrow ( 'The transaction is still not confirmed after 4 blocks.' ) ; } ) ; it ( 'should sign and send batch transactions with confirm' , async ( ) => { const txList = [ ] ; const mockTxIdList = [ 'ffb54c1f25e4bf95747712aebd62a9451a77557f86fb6c4895ee54d07615c4c2' , 'ca7f6a3001241eeb2fffbcb96bb4a60df23b2a94aafb921b26523813999f55b3' , ] ; for ( let i = 0 ; i < 2 ; i ++ ) { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; txList . push ( tx ) ; } const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , [ { id : 1 , jsonrpc : '2.0' , result : { TranID : mockTxIdList [ 0 ] , receipt : { cumulative_gas : '1000' , success : true , } , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : mockTxIdList [ 1 ] , receipt : { cumulative_gas : '1000' , success : true , } , } , } , ] , { id : 1 , jsonrpc : '2.0' , result : { ID : mockTxIdList [ 0 ] , TranID : mockTxIdList [ 0 ] , Info : 'Non-contract txn, sent to shard' , receipt : { cumulative_gas : '1000' , success : true , } , } , } , { id : 1 , jsonrpc : '2.0' , result : { ID : mockTxIdList [ 1 ] , TranID : mockTxIdList [ 1 ] , Info : 'Non-contract txn, sent to shard' , receipt : { cumulative_gas : '1000' , success : true , } , } , } , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const signedTxList = await wallet . signBatch ( txList ) ; const batchResults = await blockchain . createBatchTransaction ( signedTxList ) ; for ( const index in batchResults ) { expect ( batchResults [ index ] ) . toHaveProperty ( 'signature' ) ; expect ( batchResults [ index ] ) . toHaveProperty ( 'pubKey' ) ; expect ( batchResults [ index ] . isConfirmed ( ) ) . toEqual ( true ) ; expect ( batchResults [ index ] . id ) . toEqual ( mockTxIdList [ index ] ) ; } } ) ; it ( 'should send batch transactions without confirm' , async ( ) => { const txList = [ ] ; const mockTxIdList = [ 'ffb54c1f25e4bf95747712aebd62a9451a77557f86fb6c4895ee54d07615c4c2' , 'ca7f6a3001241eeb2fffbcb96bb4a60df23b2a94aafb921b26523813999f55b3' , ] ; for ( let i = 0 ; i < 2 ; i ++ ) { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; txList . push ( tx ) ; } const responses = [ { id : 1 , jsonrpc : '2.0' , result : { balance : '39999999000000000' , nonce : 1 , } , } , [ { id : 1 , jsonrpc : '2.0' , result : { TranID : mockTxIdList [ 0 ] , receipt : { cumulative_gas : '1000' , success : true , } , } , } , { id : 1 , jsonrpc : '2.0' , result : { TranID : mockTxIdList [ 1 ] , receipt : { cumulative_gas : '1000' , success : true , } , } , } , ] , ] . map ( ( res ) => [ JSON . stringify ( res ) , { status : 200 } ] as [ string , MockParams ] ) ; fetch . mockResponses ( ... responses ) ; const signedTxList = await wallet . signBatch ( txList ) ; const batchResults = await blockchain . createBatchTransactionWithoutConfirm ( signedTxList ) ; for ( const index in batchResults ) { expect ( batchResults [ index ] ) . toHaveProperty ( 'signature' ) ; expect ( batchResults [ index ] ) . toHaveProperty ( 'pubKey' ) ; expect ( batchResults [ index ] . id ) . toEqual ( mockTxIdList [ index ] ) ; } } ) ; it ( 'should throw error if batch transactions with confirm is unsigned' , async ( ) => { const txList = [ ] ; for ( let i = 0 ; i < 2 ; i ++ ) { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; txList . push ( tx ) ; } await expect ( blockchain . createBatchTransaction ( txList ) ) . rejects . toThrow ( 'The transaction is not signed.' ) ; } ) ; it ( 'should throw error if batch transactions without confirm is unsigned' , async ( ) => { const txList = [ ] ; for ( let i = 0 ; i < 2 ; i ++ ) { const tx = new Transaction ( { version : 1 , toAddr : '0x1234567890123456789012345678901234567890' , amount : new BN ( 0 ) , gasPrice : new BN ( 1000 ) , gasLimit : Long . fromNumber ( 1000 ) , } , provider ) ; txList . push ( tx ) ; } await expect ( blockchain . createBatchTransactionWithoutConfirm ( txList ) ) . rejects . toThrow ( 'The transaction is not signed.' ) ; } ) ; it ( 'validates params for GetStateProof' , async ( ) => { const sampleResponse = { id : 1 , jsonrpc : '2.0' , result : { accountProof : [ 'F851808080A0C7083D05AC726A32DC3313B5CA7526449EFCADAB51179A47B60901C63B108E908080A0BC76B4E969C8214F2DF641D3F387AA35CDBF17EEB54D23F5F01B4E688AB2A21980808080808080808080' , 'F871808080A0D5FE2E3CEA6C64AD708DFAD93B79FC9894C5A5AE59372D3C3872C1C8143CD749A087B1E084016657B3F8D32B429AE8055A63F12811DDFDC3AA8E863F25A03781F4A0AEDA08F7295A9E63544F9EAE728EBF98D571A07757E4BD95C91749CE9CC40B858080808080808080808080' , 'F887A820376538396338303535623466306165633037376235396535646461326662346331346638313466B85C080112120A10000000000000000000000000000000001800222045EEB1C2D2462F819E2CA893329EEB25FA29199160C28C8DDF30A10E04CCF05D2A20DDD90D4C45815116C8F23802FC3E5ED0B6D8B6A2A25EAF63680A406A33094A85' , ] , stateProof : [ 'E213A01CE797360949BDEBE357D68D54CD592D300084732CEE4F93A4ED41BDDBACD016' , 'E216A042A6C50E3845BDB58866500B65D1721DD45AC4E8BE0A4FEE6AEB4E0140D9E4E3' , 'F841B83E203533393936303466316439303130376230396232393832326630643534636638633038656532623931663165353062316435363336643331393062376532' , 'F851808080A04569AAF476CCD06BA5F31049E02C00C6FD1B6AF44C90F9EF139F6DA919B0D1FA8080A0F27A4D7A3733D624A18316E4F9D1785349462FE39EA3842A62CDF2B4D7A29B8880808080808080808080' , 'F8518080A0CA36C33D7030330EA93A73F03A8E8B05F3661C268D79184168BA5D93B0F91009808080A053C216D9015F58FF44AC4984F2482A4B06E27B7284680D9DF0BDF5494F0048EF80808080808080808080' , 'F85180A0F61D98347C0929D0A2F9354110BB4FD2F0DE083AE1B1D8AEDAA961FA5D7803108080A0F637E8D9A259DF234DB75FF9983B10D57C8B0B8015D07003F0EB6C86732465DF808080808080808080808080' , 'F90111A098D43DC741B140DDAC365E4AF6C49E4C4E9C30D2B589C85490527ADB5407682880A0B8E67BDA2445251B34AE4E78D06E60CE7C5394127B0D847E79A618F53B4064DCA0278A99201A4DB0533B1DD2AF5674B4F7A4242B95675E3014AEAB6792B102B96FA0BEE54BAD23D8DCC3C04FEF75278186234CD3AEB04A0ED5873B36E18B30DFD882A01B2ACF79D7F6064E6A1EBE1084EC8A934EAE06DCEDA8FE58AC709A0821B1251D80A0D2745A95263E0BAEDEDBDD60E3ADBEB9010DA902701263792193B27B1C06EDE9A08578DA8C3BD2970F97D569AD389222809409B7960783033BF2D5614162EA3D66A07D115995BCF7A4E9920F0A34A5BE6F0A43A21A734A5E7C421F76B5F5BFF6128380808080808080' , ] , } , } ; fetch . mockResponse ( JSON . stringify ( sampleResponse ) ) ; const testCases = [ { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , - 1 , ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 0.1234 , ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , Infinity , ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 'last' , ] , expectedReqParams : undefined , result : undefined , error : 'invalid txBlock' , } , { params : [ 'zil1z98c4cgz8c6k3sxpakv7vfsa6k04hpvn7lf8sr' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 10 , ] , expectedReqParams : [ '114f8ae1023e3568c0c1ed99e6261dd59f5b8593' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , '10' , ] , result : sampleResponse , error : undefined , } , { params : [ '0x6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 10 , ] , expectedReqParams : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , '10' , ] , result : sampleResponse , error : undefined , } , { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 10 , ] , expectedReqParams : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , '10' , ] , result : sampleResponse , error : undefined , } , { params : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 'latest' , ] , expectedReqParams : [ '6d84363526a2d764835f8cf52dfeefe80a360fac' , 'A0BD91DE66D97E6930118179BA4F1836C366C4CB3309A6B354D26F52ABB2AAC6' , 'latest' , ] , result : sampleResponse , error : undefined , } , ] ; for ( const t of testCases ) { if ( t . error ) { try { await blockchain . getStateProof ( t . params [ 0 ] as string , t . params [ 1 ] as string , t . params [ 2 ] ) ; expect ( true ) . toBe ( false ) ; } catch ( error ) { if ( error instanceof Error ) { expect ( error . message ) . toBe ( t . error ) ; } } } else { const res = await blockchain . getStateProof ( t . params [ 0 ] as string , t . params [ 1 ] as string , t . params [ 2 ] ) ; const req = getExpectedReq ( 'GetStateProof' , t . expectedReqParams ) ; const expectedRes = { req , ... t . result } ; expect ( res ) . toEqual ( expectedRes ) ; } } } ) ; } ) ;