Merge pull request #321 from ratik/feat/contracts-support

feat: contracts info
This commit is contained in:
ping 2023-02-13 13:25:17 +08:00 committed by GitHub
commit af2a4dfda1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 221 additions and 1 deletions

View File

@ -84,7 +84,7 @@ export default {
doQuery() {
const height = /^\d+$/
const txhash = /^[A-Z\d]{64}$/
const addr = /^[a-z]+1[a-z\d]{38}$/
const addr = /^[a-z]+1[a-z\d]{38,58}$/
const key = this.searchQuery
const c = store.state.chains.selected

View File

@ -130,6 +130,16 @@
"acct_num": "Account Number",
"seq": "Sequence",
"pub_key": "Public Key",
"contract_info": "Contract Info",
"query": "Query",
"code_id": "Code ID",
"creator": "Creator",
"admin": "Admin",
"label": "Label",
"created": "Created",
"height": "Height",
"tx_index": "Tx index",
"ibc_port_id": "IBC port ID",
"orig_vest": "Original Vesting",
"delegated_free": "Delegated Free",
"delegated_vest": "Delegated Vesting",
@ -147,5 +157,10 @@
"two_ways": "There are two ways to monitor your validators:",
"pin": "Pin a validator on Uptime pages.",
"link": "Specify parameters like following:"
},
"queryContractModal": {
"title": "Query Contract",
"submit": "Query",
"reset": "Reset"
}
}

View File

@ -633,6 +633,22 @@ export default class ChainFetch {
return index < conf.api.length ? index : 0
}
async getContractInfo(address, config = null) {
return this.get(`/cosmwasm/wasm/v1/contract/${address}`, config, true).then(
data => commonProcess(data.contract_info),
)
}
async queryContract(address, msg, config = null) {
return this.get(
`/cosmwasm/wasm/v1/contract/${address}/smart/${encodeURIComponent(
btoa(msg),
)}`,
config,
true,
).then(data => commonProcess(data))
}
async resolveStarName(address) {
const endpoint = 'https://rest.stargaze-apis.com'
const query = toBase64(Buffer.from(JSON.stringify({ name: { address } })))

View File

@ -283,6 +283,61 @@
@change="pageload"
/>
</b-card>
<b-card
v-if="isContract && !!contractInfo"
>
<query-modal
modal-id="queryModal"
:address="address"
/>
<b-card-header class="pt-0 pl-0 pr-0">
<b-card-title>{{ $t('walletAccountDetail.contract_info') }}</b-card-title>
<div>
<b-button
v-b-modal.queryModal
variant="primary"
size="sm"
class="mr-25"
>{{ $t('walletAccountDetail.query') }}</b-button>
</div>
</b-card-header>
<b-card-body class="pl-0 pr-0">
<b-table-simple stacked="sm">
<b-tbody>
<b-tr>
<b-td>
{{ $t('walletAccountDetail.code_id') }}
</b-td><b-td> {{ contractInfo.code_id }} </b-td>
</b-tr>
<b-tr>
<b-td>
{{ $t('walletAccountDetail.creator') }}
</b-td><b-td> {{ contractInfo.creator }} </b-td>
</b-tr>
<b-tr>
<b-td>
{{ $t('walletAccountDetail.admin') }}
</b-td><b-td> {{ contractInfo.admin }} </b-td>
</b-tr>
<b-tr>
<b-td>
{{ $t('walletAccountDetail.label') }}
</b-td><b-td> {{ contractInfo.label }} </b-td>
</b-tr>
<b-tr v-if="contractInfo.created">
<b-td>
{{ $t('walletAccountDetail.created') }} ({{ $t('walletAccountDetail.height') }} / {{ $t('walletAccountDetail.tx_index') }})
</b-td><b-td> {{ contractInfo.created.block_height }} / {{ contractInfo.created.tx_index }} </b-td>
</b-tr>
<b-tr>
<b-td>
{{ $t('walletAccountDetail.ibc_port_id') }}
</b-td><b-td> {{ contractInfo.ibc_port_id }} </b-td>
</b-tr>
</b-tbody>
</b-table-simple>
</b-card-body>
</b-card>
<b-card
v-if="account"
@ -447,6 +502,7 @@ import {
toDuration, abbrMessage, abbrAddress, getUserCurrency, getUserCurrencySign, numberWithCommas, toETHAddress,
} from '@/libs/utils'
import OperationModal from '@/views/components/OperationModal/index.vue'
import QueryModal from '@/views/components/QueryModal/index.vue'
import {
convertAddress,
resolveDomainDetails,
@ -483,6 +539,7 @@ export default {
ObjectFieldComponent,
ChartComponentDoughnut,
OperationModal,
QueryModal,
},
directives: {
'b-modal': VBModal,
@ -513,7 +570,9 @@ export default {
selectedValidator: '',
totalCurrency: 0,
address,
isContract: !!address.match(/^[a-z]+1[a-z\d]{58}$/),
account: null,
contractInfo: null,
assets: [],
reward: [],
delegations: [],
@ -721,6 +780,11 @@ export default {
this.$http.getBankAccountBalance(this.address).then(bal => {
this.assets = bal
})
if (this.isContract) {
this.$http.getContractInfo(this.address).then(res => {
this.contractInfo = res
})
}
this.$http.getStakingReward(this.address).then(res => {
this.reward = res
})

View File

@ -0,0 +1,125 @@
<template>
<b-modal
:id="modalId"
ref="queryModal"
:title="title"
>
<div>
<b-alert
v-if="isError"
variant="danger"
show
>
{{ response }}
</b-alert>
<b-form-textarea
v-if="!response && !isError"
id="textarea"
v-model="query"
placeholder="Enter something..."
rows="3"
max-rows="6"
/>
<pre v-if="response && !isError">{{ response }}</pre>
</div>
<template v-slot:modal-footer>
<b-button
v-if="!response"
variant="primary"
@click="submitData"
>
{{ $t('queryContractModal.submit') }}
</b-button>
<b-button
v-if="response"
variant="primary"
@click="resetForm"
>
{{ $t('queryContractModal.reset') }}
</b-button>
</template>
</b-modal>
</template>
<script>
import {
BFormTextarea,
BButton,
BAlert,
} from 'bootstrap-vue'
export default {
components: {
BFormTextarea,
BButton,
BAlert,
},
props: {
modalId: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
selectedChainName: {
type: String,
default: null,
},
isError: {
type: Boolean,
default: false,
},
},
data() {
return {
response: '',
title: this.$t('queryContractModal.title'),
query: '',
}
},
computed: {
selectedChain() {
let config = null
const allChains = localStorage.getItem('chains')
const selectedChain = localStorage.getItem('selected_chain')
if (allChains && selectedChain) {
config = JSON.parse(allChains)[selectedChain]
}
return config
},
},
methods: {
resetForm() {
this.showInput = true
this.showResponse = false
this.inputValue = ''
this.response = ''
this.isError = false
},
async submitData() {
this.showInput = false
this.showResponse = true
try {
const x = JSON.parse(this.query)
if (typeof x !== 'object') {
throw new Error('Query must be valid JSON!')
}
} catch (e) {
this.isError = true
this.response = `Query must be valid JSON! Error: ${e.message}`
return
}
try {
const res = await this.$http.queryContract(this.address, this.query, this.selectedChain)
this.response = JSON.stringify(res.data, null, 2)
this.isError = false
} catch (error) {
this.isError = true
this.response = `Error: ${error.message}`
}
},
},
}
</script>