UNPKG

@bandprotocol/bandchain.js

Version:

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

956 lines (840 loc) 23.7 kB
import { Coin } from '../codegen/cosmos/base/v1beta1/coin_pb' import { Any } from 'google-protobuf/google/protobuf/any_pb' import { MsgRequestData, MsgSend, MsgDelegate, MsgUndelegate, MsgBeginRedelegate, MsgWithdrawDelegatorReward, MsgVote, MsgTransfer, MsgCreateDataSource, MsgEditDataSource, MsgCreateOracleScript, MsgEditOracleScript, MsgDeposit, } from '../src/message' import { VoteOption } from '../codegen/cosmos/gov/v1beta1/gov_pb' import fs from 'fs' import path from 'path' let coin = new Coin() coin.setDenom('uband') coin.setAmount('10') describe('MsgRequest', () => { const senderAddr = 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c' const calldata = Buffer.from('000000034254430000000000000001', 'hex') const clientId = 'test' it('create successfully', () => { const msgRequest = new MsgRequestData( 1, calldata, 2, 2, clientId, senderAddr, [coin], 20000, 20000, ) const anyMsg = new Any() const name = 'oracle.v1.MsgRequestData' anyMsg.pack(msgRequest.serializeBinary(), name, '/') expect(msgRequest.toAny()).toEqual(anyMsg) expect(() => msgRequest.validate()).not.toThrow() }) it('create with error from validate()', () => { let msgs: MsgRequestData[] = [] let errorText: string[] = [] let coin1 = new Coin() coin1.setDenom('uband') coin1.setAmount('-10') let coin2 = new Coin() coin2.setDenom('uband') coin2.setAmount('string') msgs.push( // Negative oracle script ID new MsgRequestData( -1, calldata, 2, 2, clientId, senderAddr, [coin], 20000, 20000, ), ) // oracleScriptId is not an integer msgs.push( new MsgRequestData( 1.1, calldata, 2, 2, clientId, senderAddr, [coin], 20000, 20000, ), ) // askCount is not an integer msgs.push( new MsgRequestData( 1, calldata, 2.1, 2, clientId, senderAddr, [coin], 20000, 20000, ), ) // minCount is not an integer msgs.push( new MsgRequestData( 1, calldata, 2, 2.1, clientId, senderAddr, [coin], 20000, 20000, ), ) // Invalid minCount, got: minCount: 0 msgs.push( new MsgRequestData( 1, calldata, 2, 0, clientId, senderAddr, [coin], 20000, 20000, ), ) // Fee limit cannot be less than zero msgs.push( new MsgRequestData( 1, calldata, 3, 2, clientId, senderAddr, [coin1], 20000, 20000, ), ) // Invalid fee limit, fee limit should be a number msgs.push( new MsgRequestData( 1, calldata, 3, 2, clientId, senderAddr, [coin2], 20000, 20000, ), ) errorText.push('oracleScriptId cannot be less than zero') errorText.push('oracleScriptId is not an integer') errorText.push('askCount is not an integer') errorText.push('minCount is not an integer') errorText.push('Invalid minCount, got: minCount: 0') errorText.push('Fee limit cannot be less than zero') errorText.push('Invalid fee limit, fee limit should be a number') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgSend', () => { it('create successfully', () => { const msgSend = new MsgSend( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', [coin], ) const anyMsg = new Any() const name = 'cosmos.bank.v1beta1.MsgSend' anyMsg.pack(msgSend.serializeBinary(), name, '/') expect(msgSend.toAny()).toEqual(anyMsg) expect(() => msgSend.validate()).not.toThrow() }) it('error MsgSend', () => { let msgs: MsgSend[] = [] let errorText: string[] = [] msgs.push( new MsgSend( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', [], ), ) msgs.push( new MsgSend('', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', [coin]), ) msgs.push( new MsgSend('band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', [coin]), ) errorText.push('Expect at least 1 coin') errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgDelegate', () => { it('create successfully', () => { const msgDelegate = new MsgDelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', coin, ) const anyMsg = new Any() const name = 'cosmos.staking.v1beta1.MsgDelegate' anyMsg.pack(msgDelegate.serializeBinary(), name, '/') expect(msgDelegate.toAny()).toEqual(anyMsg) expect(() => msgDelegate.validate()).not.toThrow() }) it('error MsgDelegate', () => { let msgs: MsgDelegate[] = [] let errorText: string[] = [] msgs.push( new MsgDelegate( '', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', coin, ), ) msgs.push( new MsgDelegate('band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', coin), ) errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgUndelegate', () => { it('create successfully', () => { const msgUndelegate = new MsgUndelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', coin, ) const anyMsg = new Any() const name = 'cosmos.staking.v1beta1.MsgUndelegate' anyMsg.pack(msgUndelegate.serializeBinary(), name, '/') expect(msgUndelegate.toAny()).toEqual(anyMsg) expect(() => msgUndelegate.validate()).not.toThrow() }) it('error MsgUndelegate', () => { let msgs: MsgUndelegate[] = [] let errorText: string[] = [] msgs.push( new MsgUndelegate( '', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', coin, ), ) msgs.push( new MsgUndelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', coin, ), ) errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgBeginRedelegate', () => { it('create successfully', () => { const msgBeginRedelegate = new MsgBeginRedelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', 'bandvaloper1kfj48adjsnrgu83lau6wc646q2uf65rf84tzus', coin, ) const anyMsg = new Any() const name = 'cosmos.staking.v1beta1.MsgBeginRedelegate' anyMsg.pack(msgBeginRedelegate.serializeBinary(), name, '/') expect(msgBeginRedelegate.toAny()).toEqual(anyMsg) expect(() => msgBeginRedelegate.validate()).not.toThrow() }) it('error MsgBeginRedelegate', () => { let msgs: MsgBeginRedelegate[] = [] let errorText: string[] = [] msgs.push( new MsgBeginRedelegate( '', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', 'bandvaloper1kfj48adjsnrgu83lau6wc646q2uf65rf84tzus', coin, ), ) msgs.push( new MsgBeginRedelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', 'bandvaloper1kfj48adjsnrgu83lau6wc646q2uf65rf84tzus', coin, ), ) msgs.push( new MsgBeginRedelegate( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'bandvaloper1kfj48adjsnrgu83lau6wc646q2uf65rf84tzus', '', coin, ), ) errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgWithdrawDelegatorReward', () => { it('create successfully', () => { const msgWithdrawDelegatorReward = new MsgWithdrawDelegatorReward( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', ) const anyMsg = new Any() const name = 'cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward' anyMsg.pack(msgWithdrawDelegatorReward.serializeBinary(), name, '/') expect(msgWithdrawDelegatorReward.toAny()).toEqual(anyMsg) expect(() => msgWithdrawDelegatorReward.validate()).not.toThrow() }) it('error MsgWithdrawDelegatorReward', () => { let msgs: MsgWithdrawDelegatorReward[] = [] let errorText: string[] = [] msgs.push( new MsgWithdrawDelegatorReward( '', 'bandvaloper1j9vk75jjty02elhwqqjehaspfslaem8pr20qst', ), ) msgs.push( new MsgWithdrawDelegatorReward( 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', ), ) errorText.push('Address should not be an empty string') errorText.push('Address should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgVote', () => { it('create successfully', () => { const msgVote = new MsgVote( 1, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', VoteOption.VOTE_OPTION_YES, ) const anyMsg = new Any() const name = 'cosmos.gov.v1beta1.MsgVote' anyMsg.pack(msgVote.serializeBinary(), name, '/') expect(msgVote.toAny()).toEqual(anyMsg) expect(() => msgVote.validate()).not.toThrow() }) it('error MsgVote', () => { let msgs: MsgVote[] = [] let errorText: string[] = [] msgs.push( new MsgVote( 0, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', VoteOption.VOTE_OPTION_YES, ), ) msgs.push(new MsgVote(1, '', VoteOption.VOTE_OPTION_YES)) msgs.push( new MsgVote( 1, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', VoteOption.VOTE_OPTION_UNSPECIFIED, ), ) errorText.push('proposalId cannot be less than zero') errorText.push('Address should not be an empty string') errorText.push('VoteOption should not be VOTE_OPTION_UNSPECIFIED') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgTransfer', () => { it('create successfully', () => { const msgTransfer = new MsgTransfer( 'transfer', 'channel-25', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'cosmos15d4apf20449ajvwycq8ruaypt7v6d34522frnd', coin, (Date.now() + 86400000) * 1e6, ) const anyMsg = new Any() const name = 'ibc.applications.transfer.v1.MsgTransfer' anyMsg.pack(msgTransfer.serializeBinary(), name, '/') expect(msgTransfer.toAny()).toEqual(anyMsg) expect(() => msgTransfer.validate()).not.toThrow() }) it('error MsgTransfer', () => { let msgs: MsgTransfer[] = [] let errorText: string[] = [] msgs.push( new MsgTransfer( '', 'channel-25', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'cosmos15d4apf20449ajvwycq8ruaypt7v6d34522frnd', coin, (Date.now() + 86400000) * 1e6, ), new MsgTransfer( 'transfer', '', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', 'cosmos15d4apf20449ajvwycq8ruaypt7v6d34522frnd', coin, (Date.now() + 86400000) * 1e6, ), new MsgTransfer( 'transfer', 'channel-25', '', 'cosmos15d4apf20449ajvwycq8ruaypt7v6d34522frnd', coin, (Date.now() + 86400000) * 1e6, ), new MsgTransfer( 'transfer', 'channel-25', 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', '', coin, (Date.now() + 86400000) * 1e6, ), ) errorText.push('sourcePort should not be an empty string') errorText.push('sourceChannel should not be an empty string') errorText.push('sender should not be an empty string') errorText.push('receiver should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgCreateDataSource', () => { const dsName = 'CoinGecko' const description = '' const ownerAddr = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' const senderAddr = 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c' const executable = Buffer.from( '000000034254430000000000000001', 'hex', ).toString('base64') const treasury = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' it('create successfully', () => { const msgCreateDs = new MsgCreateDataSource( dsName, executable, treasury, ownerAddr, senderAddr, [coin], description, ) const anyMsg = new Any() const name = 'oracle.v1.MsgCreateDataSource' anyMsg.pack(msgCreateDs.serializeBinary(), name, '/') expect(msgCreateDs.toAny()).toEqual(anyMsg) expect(() => msgCreateDs.validate()).not.toThrow() }) it('create with error from validate()', () => { let msgs: MsgCreateDataSource[] = [] let errorText: string[] = [] let coin1 = new Coin() coin1.setDenom('uband') coin1.setAmount('-10') let coin2 = new Coin() coin2.setDenom('uband') coin2.setAmount('string') // Fee cannot be less than zero msgs.push( new MsgCreateDataSource( dsName, executable, treasury, ownerAddr, senderAddr, [coin1], description, ), ) // Invalid fee, fee list should be a number msgs.push( new MsgCreateDataSource( dsName, executable, treasury, ownerAddr, senderAddr, [coin2], description, ), ) // Owner should not be an empty string msgs.push( new MsgCreateDataSource( dsName, executable, treasury, '', senderAddr, [coin], description, ), ) // Sender should not be an empty string msgs.push( new MsgCreateDataSource( dsName, executable, treasury, ownerAddr, '', [coin], description, ), ) // Treasury should not be an empty string msgs.push( new MsgCreateDataSource( dsName, executable, '', ownerAddr, senderAddr, [coin], description, ), ) errorText.push('Fee cannot be less than zero') errorText.push('Invalid fee, fee list should be a number') errorText.push('owner should not be an empty string') errorText.push('sender should not be an empty string') errorText.push('treasury should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgEditDataSource', () => { const dataSourceId = 1 const description = '' const ownerAddr = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' const senderAddr = 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c' const treasury = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' const execPath = path.resolve( __dirname, '../mock_files/example_data_source.py', ) const file = fs.readFileSync(execPath, 'utf8') const executable = Buffer.from(file).toString('base64') it('create successfully', () => { const msgCreateDs = new MsgEditDataSource( dataSourceId, treasury, ownerAddr, senderAddr, [coin], description, executable, ) const anyMsg = new Any() const name = 'oracle.v1.MsgEditDataSource' anyMsg.pack(msgCreateDs.serializeBinary(), name, '/') expect(msgCreateDs.toAny()).toEqual(anyMsg) expect(() => msgCreateDs.validate()).not.toThrow() }) it('create with error from validate()', () => { let msgs: MsgEditDataSource[] = [] let errorText: string[] = [] let coin1 = new Coin() coin1.setDenom('uband') coin1.setAmount('-10') let coin2 = new Coin() coin2.setDenom('uband') coin2.setAmount('string') // Fee list cannot be less than zero msgs.push( new MsgEditDataSource( dataSourceId, treasury, ownerAddr, senderAddr, [coin1], description, executable, ), ) // Invalid fee limit, fee limit should be a number msgs.push( new MsgEditDataSource( dataSourceId, treasury, ownerAddr, senderAddr, [coin2], description, executable, ), ) errorText.push('Fee cannot be less than zero') errorText.push('Invalid fee, fee list should be a number') errorText.push('owner should not be an empty string') errorText.push('sender should not be an empty string') errorText.push('treasury should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgCreateOracleScript', () => { const sender = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' const execPath = path.resolve( __dirname, '../mock_files/example_oracle_script.wasm', ) const code = fs.readFileSync(execPath) it('create successfully', () => { const msgCreateOs = new MsgCreateOracleScript( 'Oracle Script Name', code, sender, sender, 'Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ) const anyMsg = new Any() const name = 'oracle.v1.MsgCreateOracleScript' anyMsg.pack(msgCreateOs.serializeBinary(), name, '/') expect(msgCreateOs.toAny()).toEqual(anyMsg) expect(() => msgCreateOs.validate()).not.toThrow() }) it('create with error from validate()', () => { let msgs: MsgCreateOracleScript[] = [] let errorText: string[] = [] const execPathEmpty = path.resolve( __dirname, '../mock_files/empty_oracle_script.wasm', ) const codeEmpty = fs.readFileSync(execPathEmpty) // name should not be an empty string msgs.push( new MsgCreateOracleScript( '', code, sender, sender, 'Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) // code should not be an empty string msgs.push( new MsgCreateOracleScript( 'Oracle Script Name', codeEmpty, sender, sender, 'Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) // owner should not be an empty string msgs.push( new MsgCreateOracleScript( 'Oracle Script Name', codeEmpty, '', sender, 'Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) // sender should not be an empty string msgs.push( new MsgCreateOracleScript( 'Oracle Script Name', codeEmpty, sender, '', 'Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) errorText.push('name should not be an empty string') errorText.push('code should not be an empty string') errorText.push('owner should not be an empty string') errorText.push('sender should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgEditOracleScript', () => { const sender = 'band1nm9ux8rmdpm20v90znav3hjrvxrvfachu7ym3d' const execPath = path.resolve( __dirname, '../mock_files/example_oracle_script.wasm', ) const code = fs.readFileSync(execPath) it('create successfully', () => { const msgEditOs = new MsgEditOracleScript( 1, sender, sender, 'Oracle Script Name', 'Edit Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', code, ) const anyMsg = new Any() const name = 'oracle.v1.MsgEditOracleScript' anyMsg.pack(msgEditOs.serializeBinary(), name, '/') expect(msgEditOs.toAny()).toEqual(anyMsg) expect(() => msgEditOs.validate()).not.toThrow() }) it('create with error from validate()', () => { let msgs: MsgEditOracleScript[] = [] let errorText: string[] = [] // owner should not be an empty string msgs.push( new MsgEditOracleScript( 1, '', sender, 'Oracle Script Name', 'Edit Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) // sender should not be an empty string msgs.push( new MsgEditOracleScript( 1, sender, '', 'Oracle Script Name', 'Edit Oracle Script Description', '{symbols:[string],multiplier:u64}/{rates:[u64]}', 'https://mockurl.com', ), ) errorText.push('owner should not be an empty string') errorText.push('sender should not be an empty string') msgs.forEach((msg, index) => { expect(() => { msg.validate() }).toThrowError(errorText[index]) }) }) }) describe('MsgDeposit', () => { it('deposit successfully', () => { const msgDeposit = new MsgDeposit( 1, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', [coin], ) const anyMsg = new Any() const name = 'cosmos.gov.v1beta1.MsgDeposit' anyMsg.pack(msgDeposit.serializeBinary(), name, '/') expect(msgDeposit.toAny()).toEqual(anyMsg) expect(() => msgDeposit.validate()).not.toThrow() }) it('error MsgDeposit', () => { let msgs = [] let errorText: string[] = [] msgs.push( // @ts-ignore new MsgDeposit(0, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', [coin]), ) msgs.push( // @ts-ignore new MsgDeposit(1, '', [coin]), ) msgs.push( // @ts-ignore new MsgDeposit(1, 'band13eznuehmqzd3r84fkxu8wklxl22r2qfmtlth8c', []), ) errorText.push('proposalId cannot be less than zero') errorText.push('depositor should not be an empty string') errorText.push('Expect at least 1 coin') msgs.forEach((msg, index) => { expect(() => { // @ts-ignore msg.validate() }).toThrowError(errorText[index]) }) }) })