UNPKG

@bandprotocol/bandchain.js

Version:

Library for interacting with BandChain in browser and Node.js environments

513 lines (492 loc) 22.3 kB
import { Client } from '../../src' import { grpc } from '@improbable-eng/grpc-web' import { ServiceClient as TxServiceClient } from '../../codegen/cosmos/tx/v1beta1/service_pb_service' import { ServiceError, UnaryResponse, } from '../../codegen/oracle/v1/query_pb_service' import { BroadcastTxRequest, BroadcastTxResponse, } from '../../codegen/cosmos/tx/v1beta1/service_pb' import { TxResponse } from '../../codegen/cosmos/base/abci/v1beta1/abci_pb' import { ABCIMessageLog, StringEvent, Attribute, } from '../../codegen/cosmos/base/abci/v1beta1/abci_pb' jest.mock('../../codegen/cosmos/tx/v1beta1/service_pb_service') const MockedTxService = jest.mocked(TxServiceClient) const TEST_GRPC = 'http://localhost:8080' const expectedSignatureFailed = { height: 0, txhash: 'C6FCF7AB773EFE9D616DBD0C2B09CAF552C8998CABBF17A394B5243CAA9381E0', codespace: 'sdk', code: 4, data: '', eventsList: [], rawLog: 'signature verification failed; please verify account number (104) and chain-id (band-laozi-testnet6): unauthorized', logsList: [], info: '', gasWanted: 2000000, gasUsed: 39362, tx: undefined, timestamp: '', } beforeEach(() => { MockedTxService.mockClear() }) describe('send transaction sync mode', () => { it('sync mode success', async () => { expect(MockedTxService).not.toHaveBeenCalled() const client = new Client(TEST_GRPC) expect(MockedTxService).toHaveBeenCalledTimes(1) const mockedTxServices = jest.mocked(MockedTxService.mock.instances[0]) type ExpectedDataSourceSignature = ( requestMessage: BroadcastTxRequest, metadata: grpc.Metadata, callback: ( error: ServiceError | null, responseMessage: BroadcastTxResponse | null, ) => void, ) => UnaryResponse const mockedBroadcasting = jest.mocked( mockedTxServices.broadcastTx as ExpectedDataSourceSignature, { shallow: true, }, ) mockedBroadcasting.mockImplementationOnce( (_req, _metadata, callback): UnaryResponse => { const response = new BroadcastTxResponse() const txResponse = new TxResponse() txResponse.setCode(0) txResponse.setTxhash( 'B7ACAEE66D48CF24B0F752A1D0B25E055CE2B49F1BC7F7D77EEE80269C5176DF', ) response.setTxResponse(txResponse) callback(null, response) return { cancel: function () {} } }, ) const expected = { height: 0, txhash: 'B7ACAEE66D48CF24B0F752A1D0B25E055CE2B49F1BC7F7D77EEE80269C5176DF', codespace: '', code: 0, data: '', eventsList: [], rawLog: '', logsList: [], info: '', gasWanted: 0, gasUsed: 0, tx: undefined, timestamp: '', } const response = await client.sendTxSyncMode('txBytes') expect(mockedBroadcasting).toHaveBeenCalledTimes(1) expect(response).toEqual(expected) }) it('sync mode signature fail', async () => { expect(MockedTxService).not.toHaveBeenCalled() const client = new Client(TEST_GRPC) expect(MockedTxService).toHaveBeenCalledTimes(1) const mockedTxServices = jest.mocked(MockedTxService.mock.instances[0]) type ExpectedDataSourceSignature = ( requestMessage: BroadcastTxRequest, metadata: grpc.Metadata, callback: ( error: ServiceError | null, responseMessage: BroadcastTxResponse | null, ) => void, ) => UnaryResponse const mockedBroadcasting = jest.mocked( mockedTxServices.broadcastTx as ExpectedDataSourceSignature, { shallow: true, }, ) mockedBroadcasting.mockImplementationOnce( (_req, _metadata, callback): UnaryResponse => { const response = new BroadcastTxResponse() const txResponse = new TxResponse() txResponse.setHeight(0) txResponse.setCodespace('sdk') txResponse.setCode(4) txResponse.setTxhash( 'C6FCF7AB773EFE9D616DBD0C2B09CAF552C8998CABBF17A394B5243CAA9381E0', ) txResponse.setRawLog( 'signature verification failed; please verify account number (104) and chain-id (band-laozi-testnet6): unauthorized', ), txResponse.setGasWanted(2000000) txResponse.setGasUsed(39362) response.setTxResponse(txResponse) callback(null, response) return { cancel: function () {} } }, ) expectedSignatureFailed const response = await client.sendTxAsyncMode('txBytesFail') expect(mockedBroadcasting).toHaveBeenCalledTimes(1) expect(response).toEqual(expectedSignatureFailed) }) }) describe('send transaction async mode', () => { it('asyn mode success', async () => { expect(MockedTxService).not.toHaveBeenCalled() const client = new Client(TEST_GRPC) expect(MockedTxService).toHaveBeenCalledTimes(1) const mockedTxServices = jest.mocked(MockedTxService.mock.instances[0]) type ExpectedDataSourceSignature = ( requestMessage: BroadcastTxRequest, metadata: grpc.Metadata, callback: ( error: ServiceError | null, responseMessage: BroadcastTxResponse | null, ) => void, ) => UnaryResponse const mockedBroadcasting = jest.mocked( mockedTxServices.broadcastTx as ExpectedDataSourceSignature, { shallow: true, }, ) mockedBroadcasting.mockImplementationOnce( (_req, _metadata, callback): UnaryResponse => { const response = new BroadcastTxResponse() const txResponse = new TxResponse() txResponse.setCode(0) txResponse.setTxhash( 'B7ACAEE66D48CF24B0F752A1D0B25E055CE2B49F1BC7F7D77EEE80269C5176DF', ) response.setTxResponse(txResponse) callback(null, response) return { cancel: function () {} } }, ) const expected = { height: 0, txhash: 'B7ACAEE66D48CF24B0F752A1D0B25E055CE2B49F1BC7F7D77EEE80269C5176DF', codespace: '', code: 0, data: '', eventsList: [], rawLog: '', logsList: [], info: '', gasWanted: 0, gasUsed: 0, tx: undefined, timestamp: '', } const response = await client.sendTxAsyncMode('txBytes') expect(mockedBroadcasting).toHaveBeenCalledTimes(1) expect(response).toEqual(expected) }) }) describe('send transaction block mode', () => { it('block mode success', async () => { expect(MockedTxService).not.toHaveBeenCalled() const client = new Client(TEST_GRPC) expect(MockedTxService).toHaveBeenCalledTimes(1) const mockedTxServices = jest.mocked(MockedTxService.mock.instances[0]) type ExpectedDataSourceSignature = ( requestMessage: BroadcastTxRequest, metadata: grpc.Metadata, callback: ( error: ServiceError | null, responseMessage: BroadcastTxResponse | null, ) => void, ) => UnaryResponse const mockedBroadcasting = jest.mocked( mockedTxServices.broadcastTx as ExpectedDataSourceSignature, { shallow: true, }, ) mockedBroadcasting.mockImplementationOnce( (_req, _metadata, callback): UnaryResponse => { const response = new BroadcastTxResponse() const txResponse = new TxResponse() txResponse.setHeight(272796) txResponse.setTxhash( 'E894BB773470ADB28D8FA61BF5300A23D6BA04D2F28A6AF2E7DA5AB4122FA3E0', ) txResponse.setCodespace('') txResponse.setCode(0) txResponse.setData('0A090A0772657175657374') txResponse.setRawLog( '[{"events":[{"type":"message","attributes":[{"key":"action","value":"request"}]},{"type":"raw_request","attributes":[{"key":"data_source_id","value":"61"},{"key":"data_source_hash","value":"07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef"},{"key":"external_id","value":"6"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"57"},{"key":"data_source_hash","value":"61b369daa5c0918020a52165f6c7662d5b9c1eee915025cb3d2b9947a26e48c7"},{"key":"external_id","value":"0"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"62"},{"key":"data_source_hash","value":"107048da9dbf7960c79fb20e0585e080bb9be07d42a1ce09c5479bbada8d0289"},{"key":"external_id","value":"3"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"5"},{"key":"calldata","value":"huobipro ETH"},{"key":"fee"},{"key":"data_source_id","value":"59"},{"key":"data_source_hash","value":"5c011454981c473af3bf6ef93c76b36bfb6cc0ce5310a70a1ba569de3fc0c15d"},{"key":"external_id","value":"2"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"4"},{"key":"calldata","value":"binance ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"9"},{"key":"calldata","value":"bittrex ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"7"},{"key":"calldata","value":"kraken ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"8"},{"key":"calldata","value":"bitfinex ETH"},{"key":"fee"},{"key":"data_source_id","value":"58"},{"key":"data_source_hash","value":"7e6759fade717a06fb643392bfde837bfc3437da2ded54feed706e6cd35de461"},{"key":"external_id","value":"1"},{"key":"calldata","value":"ETH"},{"key":"fee"}]},{"type":"request","attributes":[{"key":"id","value":"37643"},{"key":"client_id","value":"Blue"},{"key":"oracle_script_id","value":"37"},{"key":"calldata","value":"00000001000000034554480000000000000064"},{"key":"ask_count","value":"4"},{"key":"min_count","value":"3"},{"key":"gas_used","value":"71512"},{"key":"total_fees"},{"key":"validator","value":"bandvaloper19eu9g3gka6rxlevkjlvjq7s6c498tejnwxjwxx"},{"key":"validator","value":"bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz"},{"key":"validator","value":"bandvaloper1a570h9e3rtvfhm030ta5hvel7e7e4lh4pgv8wj"},{"key":"validator","value":"bandvaloper1274qgg28xkz6f3upx05ftr9zepgmtfgts392dy"}]}]}]', ) const ABCIMsgLog = new ABCIMessageLog() ABCIMsgLog.setMsgIndex(0) ABCIMsgLog.setLog('') const eventList1 = new StringEvent() eventList1.setType('message') const attribute1 = new Attribute() attribute1.setKey('action') attribute1.setValue('request') eventList1.setAttributesList([attribute1]) const eventList2 = new StringEvent() eventList2.setType('raw_request') const attribute2 = new Attribute() attribute2.setKey('data_source_id') attribute2.setValue('61') const attribute3 = new Attribute() attribute3.setKey('data_source_hash') attribute3.setValue( '07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef', ) const attribute4 = new Attribute() attribute4.setKey('external_id') attribute4.setValue('6') const attribute5 = new Attribute() attribute5.setKey('calldata') attribute5.setValue('ETH') const attribute6 = new Attribute() attribute6.setKey('fee') attribute6.setValue('') eventList2.setAttributesList([ attribute2, attribute3, attribute4, attribute5, attribute6, ]) const eventList3 = new StringEvent() eventList3.setType('request') const attribute7 = new Attribute() attribute7.setKey('id') attribute7.setValue('37643') const attribute8 = new Attribute() attribute8.setKey('client_id') attribute8.setValue('Blue') const attribute9 = new Attribute() attribute9.setKey('oracle_script_id') attribute9.setValue('37') const attribute10 = new Attribute() attribute10.setKey('calldata') attribute10.setValue('00000001000000034554480000000000000064') const attribute11 = new Attribute() attribute11.setKey('ask_count') attribute11.setValue('4') const attribute12 = new Attribute() attribute12.setKey('min_count') attribute12.setValue('3') const attribute13 = new Attribute() attribute13.setKey('gas_used') attribute13.setValue('71512') const attribute14 = new Attribute() attribute14.setKey('total_fees') attribute14.setValue('') const attribute15 = new Attribute() attribute15.setKey('validator') attribute15.setValue( 'bandvaloper19eu9g3gka6rxlevkjlvjq7s6c498tejnwxjwxx', ) const attribute16 = new Attribute() attribute16.setKey('validator') attribute16.setValue( 'bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz', ) const attribute17 = new Attribute() attribute17.setKey('validator') attribute17.setValue( 'bandvaloper1a570h9e3rtvfhm030ta5hvel7e7e4lh4pgv8wj', ) const attribute18 = new Attribute() attribute18.setKey('validator') attribute18.setValue( 'bandvaloper1274qgg28xkz6f3upx05ftr9zepgmtfgts392dy', ) eventList3.setAttributesList([ attribute7, attribute8, attribute9, attribute10, attribute11, attribute12, attribute13, attribute14, attribute15, attribute16, attribute17, attribute18, ]) ABCIMsgLog.setEventsList([eventList1, eventList2, eventList3]) txResponse.setInfo('') txResponse.setGasWanted(2000000) txResponse.setGasUsed(406535) txResponse.setTimestamp('') txResponse.setLogsList([ABCIMsgLog]) response.setTxResponse(txResponse) callback(null, response) return { cancel: function () {} } }, ) const expected = { height: 272796, txhash: 'E894BB773470ADB28D8FA61BF5300A23D6BA04D2F28A6AF2E7DA5AB4122FA3E0', codespace: '', code: 0, data: '0A090A0772657175657374', eventsList: [], rawLog: '[{"events":[{"type":"message","attributes":[{"key":"action","value":"request"}]},{"type":"raw_request","attributes":[{"key":"data_source_id","value":"61"},{"key":"data_source_hash","value":"07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef"},{"key":"external_id","value":"6"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"57"},{"key":"data_source_hash","value":"61b369daa5c0918020a52165f6c7662d5b9c1eee915025cb3d2b9947a26e48c7"},{"key":"external_id","value":"0"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"62"},{"key":"data_source_hash","value":"107048da9dbf7960c79fb20e0585e080bb9be07d42a1ce09c5479bbada8d0289"},{"key":"external_id","value":"3"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"5"},{"key":"calldata","value":"huobipro ETH"},{"key":"fee"},{"key":"data_source_id","value":"59"},{"key":"data_source_hash","value":"5c011454981c473af3bf6ef93c76b36bfb6cc0ce5310a70a1ba569de3fc0c15d"},{"key":"external_id","value":"2"},{"key":"calldata","value":"ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"4"},{"key":"calldata","value":"binance ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"9"},{"key":"calldata","value":"bittrex ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"7"},{"key":"calldata","value":"kraken ETH"},{"key":"fee"},{"key":"data_source_id","value":"60"},{"key":"data_source_hash","value":"2e588de76a58338125022bc42b460072300aebbcc4acaf55f91755c1c1799bac"},{"key":"external_id","value":"8"},{"key":"calldata","value":"bitfinex ETH"},{"key":"fee"},{"key":"data_source_id","value":"58"},{"key":"data_source_hash","value":"7e6759fade717a06fb643392bfde837bfc3437da2ded54feed706e6cd35de461"},{"key":"external_id","value":"1"},{"key":"calldata","value":"ETH"},{"key":"fee"}]},{"type":"request","attributes":[{"key":"id","value":"37643"},{"key":"client_id","value":"Blue"},{"key":"oracle_script_id","value":"37"},{"key":"calldata","value":"00000001000000034554480000000000000064"},{"key":"ask_count","value":"4"},{"key":"min_count","value":"3"},{"key":"gas_used","value":"71512"},{"key":"total_fees"},{"key":"validator","value":"bandvaloper19eu9g3gka6rxlevkjlvjq7s6c498tejnwxjwxx"},{"key":"validator","value":"bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz"},{"key":"validator","value":"bandvaloper1a570h9e3rtvfhm030ta5hvel7e7e4lh4pgv8wj"},{"key":"validator","value":"bandvaloper1274qgg28xkz6f3upx05ftr9zepgmtfgts392dy"}]}]}]', logsList: [ { msgIndex: 0, log: '', eventsList: [ { type: 'message', attributesList: [ { key: 'action', value: 'request', }, ], }, { type: 'raw_request', attributesList: [ { key: 'data_source_id', value: '61', }, { key: 'data_source_hash', value: '07be7bd61667327aae10b7a13a542c7dfba31b8f4c52b0b60bf9c7b11b1a72ef', }, { key: 'external_id', value: '6', }, { key: 'calldata', value: 'ETH', }, { key: 'fee', value: '', }, ], }, { type: 'request', attributesList: [ { key: 'id', value: '37643', }, { key: 'client_id', value: 'Blue', }, { key: 'oracle_script_id', value: '37', }, { key: 'calldata', value: '00000001000000034554480000000000000064', }, { key: 'ask_count', value: '4', }, { key: 'min_count', value: '3', }, { key: 'gas_used', value: '71512', }, { key: 'total_fees', value: '', }, { key: 'validator', value: 'bandvaloper19eu9g3gka6rxlevkjlvjq7s6c498tejnwxjwxx', }, { key: 'validator', value: 'bandvaloper1p46uhvdk8vr829v747v85hst3mur2dzlhfemmz', }, { key: 'validator', value: 'bandvaloper1a570h9e3rtvfhm030ta5hvel7e7e4lh4pgv8wj', }, { key: 'validator', value: 'bandvaloper1274qgg28xkz6f3upx05ftr9zepgmtfgts392dy', }, ], }, ], }, ], info: '', gasWanted: 2000000, gasUsed: 406535, tx: undefined, timestamp: '', } const response = await client.sendTxBlockMode('txBytes') expect(mockedBroadcasting).toHaveBeenCalledTimes(1) expect(response).toEqual(expected) }) it('block mode signature fail', async () => { expect(MockedTxService).not.toHaveBeenCalled() const client = new Client(TEST_GRPC) expect(MockedTxService).toHaveBeenCalledTimes(1) const mockedTxServices = jest.mocked(MockedTxService.mock.instances[0]) type ExpectedDataSourceSignature = ( requestMessage: BroadcastTxRequest, metadata: grpc.Metadata, callback: ( error: ServiceError | null, responseMessage: BroadcastTxResponse | null, ) => void, ) => UnaryResponse const mockedBroadcasting = jest.mocked( mockedTxServices.broadcastTx as ExpectedDataSourceSignature, { shallow: true, }, ) mockedBroadcasting.mockImplementationOnce( (_req, _metadata, callback): UnaryResponse => { const response = new BroadcastTxResponse() const txResponse = new TxResponse() txResponse.setHeight(0) txResponse.setCodespace('sdk') txResponse.setCode(4) txResponse.setTxhash( 'C6FCF7AB773EFE9D616DBD0C2B09CAF552C8998CABBF17A394B5243CAA9381E0', ) txResponse.setRawLog( 'signature verification failed; please verify account number (104) and chain-id (band-laozi-testnet6): unauthorized', ), txResponse.setGasWanted(2000000) txResponse.setGasUsed(39362) response.setTxResponse(txResponse) callback(null, response) return { cancel: function () {} } }, ) expectedSignatureFailed const response = await client.sendTxBlockMode('txBytesFail') expect(mockedBroadcasting).toHaveBeenCalledTimes(1) expect(response).toEqual(expectedSignatureFailed) }) })