diff --git a/.github/workflows/042_devnet_on_merge_trigger_deploy.yml b/.github/workflows/042_devnet_on_merge_trigger_deploy.yml new file mode 100644 index 000000000..87834f12b --- /dev/null +++ b/.github/workflows/042_devnet_on_merge_trigger_deploy.yml @@ -0,0 +1,43 @@ +#name: 042 Trigger DevNet Block Explorer Build And Deploy Pipeline +#on: +# push: +# branches: +# - 'feature/0.42' +# #test trigger +# +#jobs: +# DevNet: +# name: Trigger Block Explorer Pipeline +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v2 +# +# - name: Set version +# run: | +# VER=$(cat versions/version) +# echo $VER +# echo "VERSION=$VER" >> $GITHUB_ENV +# +# - name: 042 DevNet Trigger Block Explorer Pipeline +# if: ${{ github.ref == 'refs/heads/feature/0.42' }} +# uses: mvasigh/dispatch-action@main +# with: +# token: ${{ secrets.CHAINOPS_ACCESS_TOKEN }} +# repo: chainOps +# owner: Sifchain +# event_type: build_bigdipper_042 +# message: | +# { +# "aws_region": "us-east-1", +# "target_big_dipper_branch": "feature/0.42", +# "app_region": "us", +# "aws_cluster_name": "sifchain-aws-devnet-042-data", +# "aws_role": "arn:aws:iam::346064283538:role/OrganizationAccountAccessRole", +# "app_namespace": "block-explorer", +# "image": "sifchain/block-explorer", +# "image_tag": "devnet-${{ env.VERSION }}", +# "version": "${{ env.VERSION }}", +# "env": "data", +# "app_name": "block-explorer", +# "app_env": "data" +# } diff --git a/.github/workflows/devnet_on_merge_trigger_deploy.yml b/.github/workflows/devnet_on_merge_trigger_deploy.yml new file mode 100644 index 000000000..f79dce58a --- /dev/null +++ b/.github/workflows/devnet_on_merge_trigger_deploy.yml @@ -0,0 +1,70 @@ +name: Trigger DevNet Block Explorer Build And Deploy Pipeline +on: + push: + branches: + - 'develop' + - 'testnet' + - 'master' + +jobs: + DevNet: + name: Trigger Block Explorer Pipeline + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set version + run: | + VER=$(cat versions/version) + echo $VER + echo "VERSION=$VER" >> $GITHUB_ENV + + - name: DevNet Trigger Block Explorer Pipeline + if: ${{ github.ref == 'refs/heads/develop' }} + uses: mvasigh/dispatch-action@main + with: + # You should create a personal access token and store it in your repository + token: ${{ secrets.CHAINOPS_ACCESS_TOKEN }} + repo: chainOps + owner: Sifchain + event_type: build_bigdipper + message: | + { + "aws_region": "us-east-2", + "target_big_dipper_branch": "develop", + "app_region": "us", + "aws_cluster_name": "sifchain-aws-devnet-data", + "aws_role": "arn:aws:iam::346064283538:role/OrganizationAccountAccessRole", + "app_namespace": "block-explorer", + "image": "sifchain/block-explorer", + "image_tag": "devnet-${{ env.VERSION }}", + "version": "${{ env.VERSION }}", + "env": "data", + "app_name": "block-explorer", + "app_env": "data" + } + + - name: TestNet Trigger Block Explorer Pipeline + if: ${{ github.ref == 'refs/heads/testnet' }} + uses: mvasigh/dispatch-action@main + with: + # You should create a personal access token and store it in your repository + token: ${{ secrets.CHAINOPS_ACCESS_TOKEN }} + repo: chainOps + owner: Sifchain + event_type: build_bigdipper + message: | + { + "aws_region": "us-east-2", + "target_big_dipper_branch": "testnet", + "app_region": "us", + "aws_cluster_name": "sifchain-aws-testnet-data", + "aws_role": "arn:aws:iam::346064283538:role/OrganizationAccountAccessRole", + "app_namespace": "block-explorer", + "image": "sifchain/block-explorer", + "image_tag": "testnet-${{ env.VERSION }}", + "version": "${{ env.VERSION }}", + "env": "data", + "app_name": "block-explorer", + "app_env": "data" + } \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..c617a9b40 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release + +on: + release: + types: [published] + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Login to Docker Hub + run: docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Inject slug/short variables + uses: rlespinasse/github-slug-action@v2.x + + - name: Build docker image + run: | + docker build -t sifchain/block-explorer:${{ env.GITHUB_REF_SLUG }} . + + - name: Push docker images + run: | + docker push sifchain/block-explorer:${{ env.GITHUB_REF_SLUG }} diff --git a/Dockerfile b/Dockerfile index 839adc2a0..ca05942cc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,9 @@ ENV SCRIPTS_FOLDER /docker RUN apk --no-cache add \ bash \ - ca-certificates + ca-certificates \ + curl \ + jq COPY --from=1 $SCRIPTS_FOLDER $SCRIPTS_FOLDER/ diff --git a/README.md b/README.md index 79ff874ec..b3b576fb5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Block Explorer for Cosmos + ## Projects running on mainnets [Explore Akash with Big Dipper](https://akash.bigdipper.live/) diff --git a/SIFCHAIN_CHANGELOG.md b/SIFCHAIN_CHANGELOG.md new file mode 100644 index 000000000..dd4ef9606 --- /dev/null +++ b/SIFCHAIN_CHANGELOG.md @@ -0,0 +1,11 @@ + +---- + +# v0.2.0 +> April 27, 2021 + +## 🐛 Bug Fixes + +- [UI] Transaction fee is confusing on the transaction page (rowan vs ROWAN). +- [UI] Decimal formatting updates for cUSDT. +- [UI] Color rixes for the "Back to list" option on the validator page. diff --git a/both/document.html b/both/document.html index 36e534fd7..837670415 100644 --- a/both/document.html +++ b/both/document.html @@ -1,11 +1,11 @@ - Big Dipper | Block Explorer by Forbole + Sifchain - Block Explorer - - + + diff --git a/both/i18n/en-us.i18n.yml b/both/i18n/en-us.i18n.yml index ec99fb327..99296e932 100644 --- a/both/i18n/en-us.i18n.yml +++ b/both/i18n/en-us.i18n.yml @@ -19,7 +19,7 @@ common: hash: 'Hash' more: 'More' fullStop: '.' - searchPlaceholder: 'Search with tx hash / block height / address' + searchPlaceholder: 'Search with Tx Hash / Block Height / Address' cancel: 'Cancel' retry: 'Retry' rewards: 'Rewards' @@ -178,6 +178,8 @@ transactions: distribution: 'Distribution' governance: 'Governance' slashing: 'Slashing' + clp: "CLP" + peg: "Peg" proposals: notFound: 'No proposal found.' listOfProposals: 'Here is a list of governance proposals.' diff --git a/both/utils/coins.js b/both/utils/coins.js index 2c9fb51cf..3d90a20f1 100644 --- a/both/utils/coins.js +++ b/both/utils/coins.js @@ -41,6 +41,17 @@ constructor(amount, denom=Meteor.settings.public.bondDenom) { } } +toString (precision) { + // default to display in mint denom if it has more than 4 decimal places + let minStake = Coin.StakingCoin.fraction/(precision?Math.pow(10, precision):10000) + // console.log(this._coin.denom, this._coin) + if ((this.amount < minStake) && this._coin.demon === "rowan") { + return `${numbro(this.amount).format('0,0.0000' )} ${this._coin.denom}`; + } else { + return `${precision?numbro(this.stakingAmount).format('0,0.' + '0'.repeat(precision)):autoformat(this.stakingAmount)} ${this._coin.displayName}` + } +} + get amount () { return this._amount; } diff --git a/client/styles.scss b/client/styles.scss index 457fffd15..cc173e160 100644 --- a/client/styles.scss +++ b/client/styles.scss @@ -1,12 +1,57 @@ -$forbole-red: #bd081c; +$forbole-red: #CAA93A; $primary: $forbole-red !default; @import "materia/variables"; @import "bootstrap"; @import "materia/bootswatch"; +@import url('https://fonts.googleapis.com/css2?family=PT+Serif:ital,wght@0,400;0,700;1,400&display=swap'); + +.nav-item { cursor: pointer } +.quick-note { font-weight: 900; + width: 100%; + border-top: 1px solid; + display: block;} + +.card { + box-shadow: none; + border: 1px solid rgba(0,0,0,.5); +} + +.navbar { + box-shadow: none; +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 1); + font-weight: 900; +} + +#account > div:nth-child(2) > div > h3 > span > span > a { + color: white +} +#queryString {box-shadow: inset 0 -2px 0 #fff} +h1 { color: white } +#footer { display: none !important} + +.bgw { background: white} +.cw {color: white} + +#validator-list > .card { border: none} +#validator-list > div.validator-list.row > div > div:nth-child(1) {} +#validator-list > div.bgw.mt15 > div > div > div{border: none} +.mt15 { margin-top: 15px} +.p15 { padding: 15px} +.pl0 {padding-left: 0} +#main > div:nth-child(3) > div:nth-child(2) > div > div > div.col-md-8 > ul.nav-pills { background: white; padding: 15px} +#account > div:nth-child(2) > div > h3 > span > i { color: #343434 !important } +#account > div:nth-child(2) > div > h3 > span > span {overflow: hidden !important} + +::placeholder { color: white !important; opacity: 1} body { font-size: inherit !important; + font-family: "PT Serif"; + background: #caa93a; } .no-select { @@ -1075,4 +1120,23 @@ body { font-size: 18px; cursor: help; opacity: 0.7; - } \ No newline at end of file + } + +table, #block-table, .transactions-list { + background-color: white; +} +.status-switch { + background-color: white; + margin-top: 8px; +} +.validator-list { + padding-left: 0 !important; + padding-right: 0 !important; + .row { + margin: 0; + } + .card-body { + border: none; + border-radius: 0; + } +} diff --git a/imports/api/blocks/server/methods.js b/imports/api/blocks/server/methods.js index 716350c0b..016068d18 100644 --- a/imports/api/blocks/server/methods.js +++ b/imports/api/blocks/server/methods.js @@ -431,7 +431,7 @@ Meteor.methods({ let endBlockInsertTime = new Date(); console.log("Block insert time: "+((endBlockInsertTime-startBlockInsertTime)/1000)+"seconds."); - let chainStatus = Chain.findOne({chainId:block.block.header.chain_id}); + let chainStatus = Chain.findOne({chainId:Meteor.settings.public.chainId}); let lastSyncedTime = chainStatus?chainStatus.lastSyncedTime:0; let timeDiff; let blockTime = Meteor.settings.params.defaultBlockTime; @@ -447,7 +447,7 @@ Meteor.methods({ let endGetValidatorsTime = new Date(); console.log("Get height validators time: "+((endGetValidatorsTime-startGetValidatorsTime)/1000)+"seconds."); - Chain.update({chainId:block.block.header.chainId}, {$set:{lastSyncedTime:blockData.time, blockTime:blockTime}}); + Chain.update({chainId:Meteor.settings.public.chainId}, {$set:{lastSyncedTime:blockData.time, blockTime:blockTime}}); analyticsData.averageBlockTime = blockTime; analyticsData.timeDiff = timeDiff; diff --git a/imports/api/chain/server/methods.js b/imports/api/chain/server/methods.js index 0910d72f0..cd16fbe15 100644 --- a/imports/api/chain/server/methods.js +++ b/imports/api/chain/server/methods.js @@ -48,7 +48,7 @@ Meteor.methods({ let latestBlock = JSON.parse(response.content); let chain = {}; - chain.chainId = latestBlock.block.header.chain_id; + chain.chainId = Meteor.settings.public.chainId chain.latestBlockHeight = parseInt(latestBlock.block.header.height); chain.latestBlockTime = latestBlock.block.header.time; let latestState = ChainStates.findOne({}, {sort: {height: -1}}) diff --git a/imports/api/transactions/server/methods.js b/imports/api/transactions/server/methods.js index 8bfb59a57..be442da22 100644 --- a/imports/api/transactions/server/methods.js +++ b/imports/api/transactions/server/methods.js @@ -1,112 +1,123 @@ -import { Meteor } from 'meteor/meteor'; -import { HTTP } from 'meteor/http'; -import { Transactions } from '../../transactions/transactions.js'; -import { Validators } from '../../validators/validators.js'; +import { Meteor } from 'meteor/meteor' +import { HTTP } from 'meteor/http' +import { Transactions } from '../../transactions/transactions.js' +import { Validators } from '../../validators/validators.js' -const AddressLength = 40; +const AddressLength = 40 Meteor.methods({ - 'Transactions.updateTransactions': async function(){ - this.unblock(); - if (TXSYNCING) - return "Syncing transactions..."; + 'Transactions.updateTransactions': async function () { + this.unblock() + if (TXSYNCING) return 'Syncing transactions...' - const transactions = Transactions.find({processed:false},{limit: 500}).fetch(); - try{ - TXSYNCING = true; - const bulkTransactions = Transactions.rawCollection().initializeUnorderedBulkOp(); - for (let i in transactions){ - let url = ""; + const transactions = Transactions.find({ processed: false }, { limit: 500 }).fetch() + try { + TXSYNCING = true + const bulkTransactions = Transactions.rawCollection().initializeUnorderedBulkOp() + for (let i in transactions) { + let url = '' try { - url = API+ '/cosmos/tx/v1beta1/txs/'+transactions[i].txhash; - let response = HTTP.get(url); - let tx = JSON.parse(response.content); + url = API + '/cosmos/tx/v1beta1/txs/' + transactions[i].txhash + let response = HTTP.get(url) + let tx = JSON.parse(response.content) - tx.height = parseInt(tx.tx_response.height); - tx.processed = true; + tx.height = parseInt(tx.tx_response.height) + tx.processed = true - bulkTransactions.find({txhash:transactions[i].txhash}).updateOne({$set:tx}); - - } - catch(e) { + bulkTransactions.find({ txhash: transactions[i].txhash }).updateOne({ $set: tx }) + } catch (e) { // console.log(url); // console.log("tx not found: %o") - console.log("Getting transaction %o: %o", transactions[i].txhash, e); - bulkTransactions.find({txhash:transactions[i].txhash}).updateOne({$set:{processed:true, missing:true}}); + console.log('Getting transaction %o: %o', transactions[i].txhash, e) + bulkTransactions + .find({ txhash: transactions[i].txhash }) + .updateOne({ $set: { processed: true, missing: true } }) } } - if (bulkTransactions.length > 0){ - console.log("aaa: %o",bulkTransactions.length) + if (bulkTransactions.length > 0) { + console.log('aaa: %o', bulkTransactions.length) bulkTransactions.execute((err, result) => { - if (err){ - console.log(err); + if (err) { + console.log(err) } - if (result){ - console.log(result); + if (result) { + console.log(result) } - }); + }) } - } - catch (e) { - TXSYNCING = false; + } catch (e) { + TXSYNCING = false return e } - TXSYNCING = false; + TXSYNCING = false return transactions.length }, - 'Transactions.findDelegation': function(address, height){ - this.unblock(); + 'Transactions.findDelegation': function (address, height) { + this.unblock() // following cosmos-sdk/x/slashing/spec/06_events.md and cosmos-sdk/x/staking/spec/06_events.md - return Transactions.find({ - $or: [{$and: [ - {"tx_response.logs.events.type": "delegate"}, - {"tx_response.logs.events.attributes.key": "validator"}, - {"tx_response.logs.events.attributes.value": address} - ]}, {$and:[ - {"tx_response.logs.events.attributes.key": "action"}, - {"tx_response.logs.events.attributes.value": "unjail"}, - {"tx_response.logs.events.attributes.key": "sender"}, - {"tx_response.logs.events.attributes.value": address} - ]}, {$and:[ - {"tx_response.logs.events.type": "create_validator"}, - {"tx_response.logs.events.attributes.key": "validator"}, - {"tx_response.logs.events.attributes.value": address} - ]}, {$and:[ - {"tx_response.logs.events.type": "unbond"}, - {"tx_response.logs.events.attributes.key": "validator"}, - {"tx_response.logs.events.attributes.value": address} - ]}, {$and:[ - {"tx_response.logs.events.type": "redelegate"}, - {"tx_response.logs.events.attributes.key": "destination_validator"}, - {"tx_response.logs.events.attributes.value": address} - ]}], - "tx_response.code": 0, - height:{$lt:height}}, - {sort:{height:-1}, - limit: 1} - ).fetch(); + return Transactions.find( + { + $or: [ + { + $and: [ + { 'tx_response.logs.events.type': 'delegate' }, + { 'tx_response.logs.events.attributes.key': 'validator' }, + { 'tx_response.logs.events.attributes.value': address }, + ], + }, + { + $and: [ + { 'tx_response.logs.events.attributes.key': 'action' }, + { 'tx_response.logs.events.attributes.value': 'unjail' }, + { 'tx_response.logs.events.attributes.key': 'sender' }, + { 'tx_response.logs.events.attributes.value': address }, + ], + }, + { + $and: [ + { 'tx_response.logs.events.type': 'create_validator' }, + { 'tx_response.logs.events.attributes.key': 'validator' }, + { 'tx_response.logs.events.attributes.value': address }, + ], + }, + { + $and: [ + { 'tx_response.logs.events.type': 'unbond' }, + { 'tx_response.logs.events.attributes.key': 'validator' }, + { 'tx_response.logs.events.attributes.value': address }, + ], + }, + { + $and: [ + { 'tx_response.logs.events.type': 'redelegate' }, + { 'tx_response.logs.events.attributes.key': 'destination_validator' }, + { 'tx_response.logs.events.attributes.value': address }, + ], + }, + ], + 'tx_response.code': 0, + height: { $lt: height }, + }, + { sort: { height: -1 }, limit: 1 } + ).fetch() }, - 'Transactions.findUser': function(address, fields=null){ - this.unblock(); + 'Transactions.findUser': function (address, fields = null) { + this.unblock() // address is either delegator address or validator operator address - let validator; - if (!fields) - fields = {address:1, description:1, operator_address:1, delegator_address:1}; - if (address.includes(Meteor.settings.public.bech32PrefixValAddr)){ + let validator + if (!fields) fields = { address: 1, description: 1, operator_address: 1, delegator_address: 1 } + if (address.includes(Meteor.settings.public.bech32PrefixValAddr)) { // validator operator address - validator = Validators.findOne({operator_address:address}, {fields}); - } - else if (address.includes(Meteor.settings.public.bech32PrefixAccAddr)){ + validator = Validators.findOne({ operator_address: address }, { fields }) + } else if (address.includes(Meteor.settings.public.bech32PrefixAccAddr)) { // delegator address - validator = Validators.findOne({delegator_address:address}, {fields}); + validator = Validators.findOne({ delegator_address: address }, { fields }) + } else if (address.length === AddressLength) { + validator = Validators.findOne({ address: address }, { fields }) } - else if (address.length === AddressLength) { - validator = Validators.findOne({address:address}, {fields}); + if (validator) { + return validator } - if (validator){ - return validator; - } - return false; - - } -}); + return false + }, +}) diff --git a/imports/api/transactions/server/publications.js b/imports/api/transactions/server/publications.js index 88c2efb32..f000be793 100644 --- a/imports/api/transactions/server/publications.js +++ b/imports/api/transactions/server/publications.js @@ -29,7 +29,16 @@ publishComposite('transactions.validator', function(validatorAddress, delegatorA } if (!validatorAddress && delegatorAddress){ - query = {"tx_response.logs.events.attributes.value":delegatorAddress} + query = {$or:[ + {"logs.events.attributes.value":delegatorAddress}, + {"tx.value.msg.value.cosmos_receiver": delegatorAddress }, + {"tx.value.msg.value.cosmos_sender": delegatorAddress }, + {"tx.value.msg.value.delegator_address": delegatorAddress }, + {"tx.value.msg.value.from_address": delegatorAddress }, + {"tx.value.msg.value.Signer": delegatorAddress }, + {"tx.value.msg.value.delegator_address": delegatorAddress }, + {"tx_response.logs.events.attributes.value":delegatorAddress}, + ]} } return { diff --git a/imports/api/validators/server/methods.js b/imports/api/validators/server/methods.js index 27fe036e6..5eeb99402 100644 --- a/imports/api/validators/server/methods.js +++ b/imports/api/validators/server/methods.js @@ -53,26 +53,28 @@ Meteor.methods({ let url = RPC + '/status'; let chainId; + try { let response = HTTP.get(url); let status = JSON.parse(response?.content); - chainId = (status?.result?.node_info?.network); + chainId = Meteor.settings.public.chainId } catch (e) { console.log("Error getting chainId for keybase fetching") } - let chainStatus = Chain.findOne({ chainId}); - const bulkValidators = Validators.rawCollection().initializeUnorderedBulkOp(); + let chainStatus = Chain.findOne({chainId}); + const bulkValidators = Validators.rawCollection().initializeUnorderedBulkOp(); let lastKeybaseFetchTime = Date.parse(chainStatus?.lastKeybaseFetchTime) ?? 0 - console.log("Last fetch time: %o", lastKeybaseFetchTime) + console.log("Last fetch time: %o", lastKeybaseFetchTime) console.log('Fetching keybase...') - // eslint-disable-next-line no-loop-func + Validators.find({}).forEach(async (validator) => { try { if (validator?.description && validator?.description?.identity) { - let profileUrl = getValidatorProfileUrl(validator?.description?.identity) + let profileUrl = "https://sifchain.finance/wp-content/themes/icos-child/images/achieved.svg" + if (profileUrl) { bulkValidators.find({ address: validator?.address }).upsert().updateOne({ $set: { 'profile_url': profileUrl } }); if (bulkValidators.length > 0) { @@ -92,6 +94,7 @@ Meteor.methods({ } }) try{ + console.log("Update chain") Chain.update({ chainId }, { $set: { lastKeybaseFetchTime: new Date().toUTCString() } }); } catch(e){ diff --git a/imports/ui/blocks/BlockContainer.js b/imports/ui/blocks/BlockContainer.js index df8b979f2..bc6e06368 100644 --- a/imports/ui/blocks/BlockContainer.js +++ b/imports/ui/blocks/BlockContainer.js @@ -37,6 +37,21 @@ export default BlockContainer = withTracker((props) => { blockExist, transactionsExist, block: blockExist ? block : {}, + clpTxs: transactionsExist ? Transactions.find({ + $or: [ + {"tx.value.msg.type":"clp/Swap"}, + {"tx.value.msg.type":"clp/AddLiquidity"}, + {"tx.value.msg.type":"clp/CreatePool"}, + {"tx.value.msg.type":"clp/RemoveLiquidity"} + ] + }).fetch() : {}, + pegTxs: transactionsExist ? Transactions.find({ + $or: [ + {"tx.value.msg.type":"ethbridge/MsgLock"}, + {"tx.value.msg.type":"ethbridge/MsgBurn"}, + {"tx.value.msg.type":"ethbridge/MsgCreateEthBridgeClaim"}, + ] + }).fetch() : {}, transferTxs: transactionsExist ? Transactions.find({ $or: [ {"tx.body.messages.@type":"/cosmos.bank.v1beta1.MsgSend"}, diff --git a/imports/ui/blocks/BlocksTable.jsx b/imports/ui/blocks/BlocksTable.jsx index 1f6c9a04f..0a07dcb44 100644 --- a/imports/ui/blocks/BlocksTable.jsx +++ b/imports/ui/blocks/BlocksTable.jsx @@ -26,7 +26,7 @@ export default class BlocksTable extends Component { } isBottom(el) { - return el.getBoundingClientRect().bottom <= window.innerHeight; + return el?.getBoundingClientRect().bottom <= window.innerHeight; } componentDidMount() { diff --git a/imports/ui/components/Activities.jsx b/imports/ui/components/Activities.jsx index 9aee989c3..8f5f90024 100644 --- a/imports/ui/components/Activities.jsx +++ b/imports/ui/components/Activities.jsx @@ -91,7 +91,7 @@ export default class Activites extends Component { case "/cosmos.gov.v1beta1.MsgSubmitProposal": const proposalId = _.get(this.props, 'events[2].attributes[0].value', null) const proposalLink = proposalId ? `/proposals/${proposalId}` : "#"; - return

activities.withTitle {msg.content.value.title}common.fullStop

+ return

activities.withTitle {msg.content.title}common.fullStop

case "/cosmos.gov.v1beta1.MsgDeposit": return

{(this.props.invalid)?activities.failedTo:''} {msg.amount.map((amount,i) =>new Coin(amount.amount, amount.denom).toString(6)).join(', ')} activities.to proposals.proposal {msg.proposal_id}common.fullStop

case "/cosmos.gov.v1beta1.MsgVote": diff --git a/imports/ui/components/ChainStates.jsx b/imports/ui/components/ChainStates.jsx index fd7975645..b1274b5e6 100644 --- a/imports/ui/components/ChainStates.jsx +++ b/imports/ui/components/ChainStates.jsx @@ -85,8 +85,8 @@ export default class ChainStates extends Component{ chainStates.price: ${this.state.price} - chainStates.marketCap: {this.state.marketCap} - chainStates.inflation: {this.state.inflation} + {/*chainStates.marketCap: {this.state.marketCap}*/} + {/*chainStates.inflation: {this.state.inflation}*/} chainStates.communityPool: {(this.renderValues(this.state.communityPool))} diff --git a/imports/ui/components/Header.jsx b/imports/ui/components/Header.jsx index dd726a3a8..ba72f0788 100644 --- a/imports/ui/components/Header.jsx +++ b/imports/ui/components/Header.jsx @@ -25,7 +25,7 @@ import { import { Link } from 'react-router-dom'; import SearchBar from './SearchBar.jsx'; import i18n from 'meteor/universe:i18n'; -import LedgerModal from '../ledger/LedgerModal.jsx'; +// import LedgerModal from '../ledger/LedgerModal.jsx'; import Account from './Account.jsx'; const T = i18n.createComponent(); @@ -172,11 +172,15 @@ export default class Header extends Component { let signedInAddress = getUser(); return ( - navbar.siteName {this.state.version} - + + + {/* navbar.siteName  + {this.state.version} */} + + {/* {Meteor.settings.public.chainId} {this.state.networks} - + */} @@ -194,9 +198,12 @@ export default class Header extends Component { navbar.proposals - navbar.votingPower + navbar.votingPower - + + Trade + + {/* {!signedInAddress?: @@ -218,7 +225,7 @@ export default class Header extends Component { } - + */} diff --git a/imports/ui/components/MsgType.jsx b/imports/ui/components/MsgType.jsx index 905e0c378..0f99cd2fd 100644 --- a/imports/ui/components/MsgType.jsx +++ b/imports/ui/components/MsgType.jsx @@ -48,64 +48,11 @@ export const MsgType = (props) => { case "/cosmos.IBCTransferMsg": return messageTypes.IBCTransfer; case "/cosmos.IBCReceiveMsg": - return messageTypes.IBCReceive; - - case "/ibc.core.client.v1.MsgCreateClient": - return messageTypes.IBCCreateClient; - case "/ibc.core.client.v1.MsgUpdateClient": - return messageTypes.IBCUpdateClient; - case "/ibc.core.client.v1.MsgUpgradeClient": - return messageTypes.IBCUpgradeClient; - case "/ibc.core.client.v1.MsgSubmitMisbehaviour": - return messageTypes.IBCSubmitMisbehaviour; - case "/ibc.core.client.v1.Height": - return messageTypes.IBCHeight; - - case "/ibc.core.channel.v1.MsgRecvPacket": - return messageTypes.IBCReceivePacket; - case "/ibc.core.channel.v1.Channel": - return messageTypes.IBCChannel; - case "/ibc.core.channel.v1.Counterparty": - return messageTypes.IBCCounterparty; - case "/ibc.core.channel.v1.Packet": - return messageTypes.IBCPacket; - case "/ibc.core.channel.v1.MsgAcknowledgement": - return messageTypes.IBCAcknowledgement; - case "/ibc.core.channel.v1.MsgChannelCloseConfirm": - return messageTypes.IBCChannelCloseConfirm; - case "/ibc.core.channel.v1.MsgChannelCloseInit": - return messageTypes.IBCChannelCloseInit; - case "/ibc.core.channel.v1.MsgChannelOpenAck": - return messageTypes.IBCChannelOpenAck; - case "/ibc.core.channel.v1.MsgChannelOpenConfirm": - return messageTypes.IBCChannelOpenConfirm; - case "/ibc.core.channel.v1.MsgChannelOpenInit": - return messageTypes.IBCChannelOpenInit; - case "/ibc.core.channel.v1.MsgChannelOpenTry": - return messageTypes.IBCChannelOpenTry; - case "/ibc.core.channel.v1.MsgTimeout": - return messageTypes.IBCTimeout; - case "/ibc.core.channel.v1.MsgTimeoutOnClose": - return messageTypes.IBCTimeoutOnClose; - - case "/ibc.core.connection.v1.MsgConnectionOpenAck": - return messageTypes.IBCConnectionOpenAck; - case "/ibc.core.connection.v1.MsgConnectionOpenConfirm": - return messageTypes.IBCConnectionOpenConfirm; - case "/ibc.core.connection.v1.MsgConnectionOpenInit": - return messageTypes.IBCConnectionOpenInit; - case "/ibc.core.connection.v1.MsgConnectionOpenTry": - return messageTypes.IBCConnectionOpenTry; - case "/ibc.core.connection.v1.ConnectionEnd": - return messageTypes.IBCConnectionEnd; - case "/ibc.core.connection.v1.Counterparty": - return messageTypes.IBCCounterparty; - case "/ibc.core.connection.v1.Version": - return messageTypes.IBCVersion; - - case "/ibc.applications.transfer.v1.MsgTransfer": - return messageTypes.IBCMsgTransfer; + return messageTypes.IBCReceive; + // clp + case "clp/Swap": + return Swap; default: return {props.type}; } diff --git a/imports/ui/components/Transactions.jsx b/imports/ui/components/Transactions.jsx index 2e8ced6c8..2b4ead365 100644 --- a/imports/ui/components/Transactions.jsx +++ b/imports/ui/components/Transactions.jsx @@ -14,6 +14,8 @@ export default class ValidatorTransactions extends Component{ distributionTxs: {}, governanceTxs: {}, slashingTxs: {}, + clpTxs: {}, + pegTxs: {} }; } @@ -26,7 +28,9 @@ export default class ValidatorTransactions extends Component{ stakingTxs: this.props.stakingTxs, distributionTxs: this.props.distributionTxs, governanceTxs: this.props.governanceTxs, - slashingTxs: this.props.slashingTxs + slashingTxs: this.props.slashingTxs, + clpTxs: this.props.clpTxs, + pegTxs: this.props.pegTxs }) } } @@ -43,6 +47,8 @@ export default class ValidatorTransactions extends Component{ distributionTxs={this.state.distributionTxs} governanceTxs={this.state.governanceTxs} slashingTxs={this.state.slashingTxs} + clpTxs={this.state.clpTxs} + pegTxs={this.state.pegTxs} /> } else { diff --git a/imports/ui/components/TransactionsContainer.js b/imports/ui/components/TransactionsContainer.js index 6f5bbe975..cbf86a2d6 100644 --- a/imports/ui/components/TransactionsContainer.js +++ b/imports/ui/components/TransactionsContainer.js @@ -27,6 +27,21 @@ export default TransactionsContainer = withTracker((props) => { return { loading, transactionsExist, + clpTxs: transactionsExist ? Transactions.find({ + $or: [ + {"tx.value.msg.type":"clp/Swap"}, + {"tx.value.msg.type":"clp/AddLiquidity"}, + {"tx.value.msg.type":"clp/CreatePool"}, + {"tx.value.msg.type":"clp/RemoveLiquidity"} + ] + }).fetch() : {}, + pegTxs: transactionsExist ? Transactions.find({ + $or: [ + {"tx.value.msg.type":"ethbridge/MsgLock"}, + {"tx.value.msg.type":"ethbridge/MsgBurn"}, + {"tx.value.msg.type":"ethbridge/MsgCreateEthBridgeClaim"}, + ] + }).fetch() : {}, transferTxs: transactionsExist ? Transactions.find({ $or: [ {"tx.body.messages.@type":"/cosmos.bank.v1beta1.MsgSend"}, diff --git a/imports/ui/transactions/TransactionTabs.jsx b/imports/ui/transactions/TransactionTabs.jsx index 712b667cc..2ef5d2230 100644 --- a/imports/ui/transactions/TransactionTabs.jsx +++ b/imports/ui/transactions/TransactionTabs.jsx @@ -16,7 +16,9 @@ export default class TransactionTabs extends Component{ stakingTxs: {}, distributionTxs: {}, governanceTxs: {}, - slashingTxs: {} + slashingTxs: {}, + clpTxs: {}, + pegTxs: {} } } @@ -35,7 +37,9 @@ export default class TransactionTabs extends Component{ stakingTxs: this.props.stakingTxs, distributionTxs: this.props.distributionTxs, governanceTxs: this.props.governanceTxs, - slashingTxs: this.props.slashingTxs + slashingTxs: this.props.slashingTxs, + clpTxs: this.props.clpTxs, + pegTxs: this.props.pegTxs }) } } @@ -85,6 +89,22 @@ export default class TransactionTabs extends Component{ transactions.slashing ({numbro(this.state.slashingTxs.length).format("0,0")}) + + { this.toggle('tx-clp'); }} + > + transactions.clp ({numbro(this.state.clpTxs.length).format("0,0")}) + + + + { this.toggle('tx-peg'); }} + > + transactions.peg ({numbro(this.state.pegTxs.length).format("0,0")}) + + @@ -157,6 +177,34 @@ export default class TransactionTabs extends Component{ + + + + {(this.state.clpTxs.length > 0)?this.state.clpTxs.map((tx, i) => { + return + }):''} + + + + + + + {(this.state.pegTxs.length > 0)?this.state.pegTxs.map((tx, i) => { + return + }):''} + + + diff --git a/imports/ui/transactions/TransactionsList.jsx b/imports/ui/transactions/TransactionsList.jsx index 4a9544796..16292a156 100644 --- a/imports/ui/transactions/TransactionsList.jsx +++ b/imports/ui/transactions/TransactionsList.jsx @@ -31,7 +31,7 @@ export default class Transactions extends Component{ } isBottom(el) { - return el.getBoundingClientRect().bottom <= window.innerHeight; + return el?.getBoundingClientRect().bottom <= window.innerHeight; } componentDidMount() { diff --git a/imports/ui/validators/Validator.jsx b/imports/ui/validators/Validator.jsx index 628f21062..14297bf3c 100644 --- a/imports/ui/validators/Validator.jsx +++ b/imports/ui/validators/Validator.jsx @@ -11,7 +11,7 @@ import { Badge, Row, Col, Card, import KeybaseCheck from '../components/KeybaseCheck.jsx'; import ValidatorDelegations from './Delegations.jsx'; import ValidatorTransactions from '../components/TransactionsContainer.js'; -import { DelegationButtons } from '../ledger/LedgerActions.jsx'; +// import { DelegationButtons } from '../ledger/LedgerActions.jsx'; import { Helmet } from 'react-helmet'; import LinkIcon from '../components/LinkIcon.jsx'; import i18n from 'meteor/universe:i18n'; @@ -241,9 +241,9 @@ export default class Validator extends Component{
common.votingPower
- {this.state.user?:''} + history={this.props.history} stakingParams={this.props.chainStatus.staking?this.props.chainStatus.staking.params:null}/>:''} */} {this.props.validator.tokens?

{numbro(Math.floor(this.props.validator.tokens/Meteor.settings.public.powerReduction)).format('0,0')}

(~{numbro(this.props.validator.tokens/Meteor.settings.public.powerReduction/this.props.chainStatus.activeVotingPower).format('0.00%')}):''} validators.selfDelegationRatio diff --git a/imports/ui/validators/ValidatorsList.jsx b/imports/ui/validators/ValidatorsList.jsx index c79b39a21..f00d1c9b6 100644 --- a/imports/ui/validators/ValidatorsList.jsx +++ b/imports/ui/validators/ValidatorsList.jsx @@ -84,7 +84,7 @@ export default class Validators extends Component{

{title}

-