finish block and transaction

This commit is contained in:
liangping 2021-08-05 12:38:58 +08:00
parent f1e3e04e1f
commit 9e9f26af40
16 changed files with 628 additions and 33 deletions

View File

@ -15,6 +15,7 @@
"@cosmjs/amino": "^0.25.6",
"@cosmjs/crypto": "^0.25.6",
"@cosmjs/encoding": "^0.25.6",
"@cosmjs/proto-signing": "^0.25.6",
"@fullcalendar/common": "5.x",
"@fullcalendar/core": "5.x",
"@fullcalendar/daygrid": "5.x",

View File

@ -12,6 +12,20 @@ export function percent(num) {
return parseFloat((num * 100).toFixed(2))
}
export function abbr(string, length = 6) {
if (string && string.length > length) {
return `${string.substring(0, length)}...`
}
return string
}
export function abbrMessage(msg) {
if (Array.isArray(msg)) {
return msg.map(x => abbrMessage(x)).join()
}
return msg.typeUrl.substring(msg.typeUrl.lastIndexOf('.') + 1)
}
export function isToken(value) {
let is = false
if (Array.isArray(value)) {
@ -21,15 +35,18 @@ export function isToken(value) {
}
export function formatToken(token) {
let denom = token.denom.toUpperCase()
if (denom.charAt(0) === 'U') {
denom = denom.substring(1)
if (token) {
let denom = token.denom.toUpperCase()
if (denom.charAt(0) === 'U') {
denom = denom.substring(1)
}
const amount = token.amount / 1000000
if (amount > 10) {
return `${amount.toFixed()} ${denom}`
}
return `${amount} ${denom}`
}
const amount = token.amount / 1000000
if (amount > 10) {
return `${amount.toFixed()} ${denom}`
}
return `${amount} ${denom}`
return ''
}
const COUNT_ABBRS = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']

View File

@ -9,6 +9,7 @@ export { default as StakingParameters } from './staking-parameters'
export { default as Block } from './block'
export { default as ValidatorDistribution } from './validator-distribution'
export { default as StakingDelegation } from './staking-delegation'
export { default as WrapStdTx } from './wrapstdtx'
export * from './data'
export default class Test {}

36
src/libs/data/stdtx.js Normal file
View File

@ -0,0 +1,36 @@
import compareVersions from 'compare-versions'
import Token from './token'
export default class StdTx {
constructor() {
this.type = ''
this.fee = [new Token()]
this.gas = 0
this.memo = ''
this.messages = []
this.signatures = []
this.timeout_height = 0
}
static create(element, version = '0.40') {
const self = new StdTx()
if (compareVersions(version, '0.40') < 1) {
self.type = element.type
self.fee = element.value.fee.amount
self.gas = element.value.fee.gas
self.memo = element.value.memo
self.messages = element.value.msg
self.signatures = element.value.signatures
self.timeout_height = 0
} else {
self.type = element['@type']
self.fee = element.auth_info.fee.amount
self.gas = element.auth_info.fee.gas_limit
self.memo = element.body.memo
self.messages = element.body.messages
self.signatures = element.signatures
self.timeout_height = element.body.timeout_height
}
return self
}
}

13
src/libs/data/token.js Normal file
View File

@ -0,0 +1,13 @@
export default class Token {
constructor() {
this.amount = 0
this.denom = ''
}
static create(element) {
const self = new Token()
self.amount = Number(element.amount)
self.denom = element.denom
return self
}
}

27
src/libs/data/tx.js Normal file
View File

@ -0,0 +1,27 @@
import { sha256 } from '@cosmjs/crypto'
import { fromBase64, toHex } from '@cosmjs/encoding'
import Token from './token'
export default class Tx {
constructor() {
this.hash = ''
this.fee = [new Token()]
this.memo = ''
this.messages = []
this.signatures = []
}
static create(element) {
const self = new Tx()
self.hash = ''
self.fee = element.authInfo.fee.amount
self.memo = element.body.memo
self.messages = element.body.messages
self.signatures = element.signatures
return self
}
setHash(raw) {
this.hash = toHex(sha256(fromBase64(raw))).toUpperCase()
}
}

View File

@ -0,0 +1,45 @@
import compareVersions from 'compare-versions'
import StdTx from './stdtx'
export default class WrapStdTx {
constructor() {
this.code = 0
this.txhash = ''
this.data = ''
this.gas_used = ''
this.gas_wanted = ''
this.height = 0
this.logs = []
this.timestamp = ''
this.tx = new StdTx()
this.info = ''
this.raw_log = ''
}
static create(element, version = '0.40') {
const self = new WrapStdTx()
if (compareVersions(version, '0.40') < 1) {
self.txhash = element.txhash
self.data = element.data
self.gas_used = element.gas_used
self.gas_wanted = element.gas_wanted
self.height = Number(element.height)
self.logs = element.logs
self.timestamp = element.timestamp
self.tx = StdTx.create(element.tx)
} else {
self.code = element.tx_response.code
self.txhash = element.tx_response.txhash
self.data = element.tx_response.data
self.gas_used = element.tx_response.gas_used
self.gas_wanted = element.tx_response.gas_wanted
self.height = Number(element.tx_response.height)
self.info = element.tx_response.info
self.logs = element.tx_response.logs
self.timestamp = element.tx_response.timestamp
self.tx = StdTx.create(element.tx, version)
self.raw_log = element.tx_response.raw_log
}
return self
}
}

View File

@ -3,7 +3,7 @@ import store from '@/store'
import compareVersions from 'compare-versions'
import {
Proposal, ProposalTally, Proposer, StakingPool, Votes, Deposit,
Validator, StakingParameters, Block, ValidatorDistribution, StakingDelegation,
Validator, StakingParameters, Block, ValidatorDistribution, StakingDelegation, WrapStdTx,
} from './data'
function commonProcess(res) {
@ -11,14 +11,34 @@ function commonProcess(res) {
}
// 头像
export async function keybase(identity) {
export function keybase(identity) {
return fetch(`https://keybase.io/_/api/1.0/user/lookup.json?key_suffix=${identity}&fields=pictures`)
.then(res => res.json())
}
async function refetchVersion(chain) {
await fetch(`${chain.api}/node_info`)
.then(res => res.json())
.then(json => {
const sdk = json.application_version.build_deps.find(e => e.startsWith('github.com/cosmos/cosmos-sdk'))
const re = /(\d+(\.\d+)*)/i
const version = sdk.match(re)
return version[0]
})
}
const chainAPI = class ChainFetch {
getSelectedConfig() {
this.config = store.state.chains.selected
let chain = store.state.chains.selected
const lschains = localStorage.getItem('chains')
if (lschains) {
chain = JSON.parse(lschains)[chain.chain_name]
}
if (!chain.sdk_version) {
chain.sdk_version = refetchVersion(chain)
}
this.config = chain
console.log(this.config)
return this.config
}
@ -30,6 +50,17 @@ const chainAPI = class ChainFetch {
return this.get(`/blocks/${height}`).then(data => Block.create(data))
}
async getTxs(hash) {
const FIELD = 'sdk_version'
const ver = this.getSelectedConfig() ? this.config.sdk_version : '0.41'
console.log(ver, this.config[FIELD])
// /cosmos/tx/v1beta1/txs/{hash}
if (ver && compareVersions(ver, '0.40') < 1) {
return this.get(`/txs/${hash}`).then(data => WrapStdTx.create(data, ver))
}
return this.get(`/cosmos/tx/v1beta1/txs/${hash}`).then(data => WrapStdTx.create(data, ver))
}
async getValidatorDistribution(address) {
return this.get(`/distribution/validators/${address}`).then(data => {
const ret = ValidatorDistribution.create(commonProcess(data))

View File

@ -110,6 +110,34 @@ const router = new VueRouter({
],
},
},
{
path: '/:chain/block/:height',
name: 'block',
component: () => import('@/views/Block.vue'),
meta: {
pageTitle: 'Block',
breadcrumb: [
{
text: 'Block',
active: true,
},
],
},
},
{
path: '/:chain/tx/:hash',
name: 'transaction',
component: () => import('@/views/Transaction.vue'),
meta: {
pageTitle: 'Transaction',
breadcrumb: [
{
text: 'Transaction',
active: true,
},
],
},
},
{
path: '/login',
name: 'login',
@ -139,7 +167,7 @@ router.beforeEach((to, from, next) => {
if (has > -1) {
const chain = store.state.chains.config[c]
store.commit('select', { chain_name: c })
if (chain.sdk_version === undefined) {
if (chain.sdk_version) {
fetch(`${chain.api}/node_info`)
.then(res => res.json())
.then(json => {

View File

@ -1,9 +1,32 @@
const chains = {}
const configs = require.context('.', false, /\.json$/)
let chains = {}
configs.keys().forEach(k => {
const c = configs(k)
chains[c.chain_name] = c
const localChains = localStorage.getItem('chains')
if (localChains) {
chains = JSON.parse(localChains)
} else {
const configs = require.context('.', false, /\.json$/)
configs.keys().forEach(k => {
const c = configs(k)
chains[c.chain_name] = c
})
localStorage.setItem('chains', JSON.stringify(chains))
}
Object.keys(chains).forEach(key => {
const chain = chains[key]
fetch(`${chain.api}/node_info`)
.then(res => res.json())
.then(json => {
const sdk = json.application_version.build_deps.find(e => e.startsWith('github.com/cosmos/cosmos-sdk'))
const re = /(\d+(\.\d+)*)/i
const version = sdk.match(re)
// eslint-disable-next-line prefer-destructuring
chain.sdk_version = version[0]
localStorage.setItem('chains', JSON.stringify(chains))
console.log(`${chain.api}/node_info`, localStorage.getItem('chains'))
})
.catch(e => console.log(`Failed get api vesion of ${key}`, e))
})
export default {

View File

@ -1,5 +1,6 @@
<template>
<b-table
v-if="Array.isArray(tablefield)"
:items="tablefield"
:sticky-header="true"
:no-border-collapse="true"
@ -11,7 +12,10 @@
v-else-if="isArrayText(data.value)"
:tablefield="eval_value(data.value)"
/>
<span v-else>{{ data.value }}</span>
<span
v-else
:title="data.value"
>{{ formatText(data.value) }}</span>
</template>
</b-table>
</template>
@ -20,7 +24,9 @@
import { BTable } from 'bootstrap-vue'
// import fetch from 'node-fetch'
import { isToken, tokenFormatter } from '@/libs/data/data'
import {
abbr, isToken, toDay, tokenFormatter,
} from '@/libs/data/data'
// import { Proposal, Proposer } from '@/libs/data'
// import { formatToken } from '@/libs/data/data'
@ -31,7 +37,7 @@ export default {
},
props: {
tablefield: {
type: Array,
type: [Array, Object],
default: () => [],
},
},
@ -46,9 +52,16 @@ export default {
return isToken(value)
},
isArrayText(value) {
const has = String(value).startsWith('[')
const has = String(value).startsWith('[') && String(value).endsWith(']')
return has
},
formatText(value) {
const reg = /^\d{4}.\d{1,2}.\d{1,2}T\d{2}:\d{2}:.+Z$/
if (reg.test(value)) {
return toDay(value)
}
return abbr(value, 40)
},
formatTokens(value) {
return tokenFormatter(value)
},

95
src/views/Block.vue Normal file
View File

@ -0,0 +1,95 @@
<template>
<div>
<b-card title="Block Id">
<object-field-component :tablefield="block.block_id" />
</b-card>
<b-card title="Block Header">
<object-field-component :tablefield="block.block.header" />
</b-card>
<b-card
v-if="block.block.data.txs"
title="Transaction"
>
<b-table
:items="txs"
:fields="fields"
responsive="sm"
>
<template #cell(hash)="data">
<router-link :to="`../tx/${data.value}`">
{{ data.value }}
</router-link>
</template>
</b-table>
</b-card>
<b-card
v-if="block.block.evidence.evidence"
title="Evidence"
>
<array-field-component :tablefield="block.block.evidence.evidence" />
</b-card>
<b-card title="Last Commit">
<object-field-component :tablefield="block.block.last_commit" />
</b-card>
</div>
</template>
<script>
import { BCard, BTable } from 'bootstrap-vue'
import { fromBase64 } from '@cosmjs/encoding'
import { decodeTxRaw } from '@cosmjs/proto-signing'
import Tx from '@/libs/data/tx'
import { abbrMessage, tokenFormatter } from '@/libs/data'
import ObjectFieldComponent from './ObjectFieldComponent.vue'
import ArrayFieldComponent from './ArrayFieldComponent.vue'
export default {
components: {
BCard,
BTable,
ObjectFieldComponent,
ArrayFieldComponent,
},
data() {
return {
block: { block: { header: {}, data: {}, evidence: {} } },
txs: null,
fields: [
{ key: 'hash' },
{ key: 'fee', formatter: v => tokenFormatter(v) },
{ key: 'messages', formatter: v => abbrMessage(v) },
{ key: 'memo' },
],
}
},
created() {
const { height } = this.$route.params
this.$http.getBlockByHeight(height).then(res => {
this.block = res
const { txs } = res.block.data
const array = []
for (let i = 0; i <= txs.length; i += 1) {
try {
const origin = decodeTxRaw(fromBase64(txs[i]))
const tx = Tx.create(origin)
tx.setHash(txs[i])
array.push(tx)
console.log('tx', origin, tx)
} catch (e) {
console.log(e)
}
}
if (array.length > 0) this.txs = array
console.log(this.txs)
})
},
}
</script>
<style>
</style>

View File

@ -1,5 +1,11 @@
<template>
<b-table-simple>
<b-table-simple
v-if="typeof tablefield === 'object'"
hover
small
striped
responsive
>
<b-tr
v-for="(value, name) in tablefield"
:key="name"
@ -7,7 +13,7 @@
<b-td
style="text-transform: capitalize; vertical-align: top; width:200px"
>
{{ name.replaceAll('_',' ') }}
{{ name }}
</b-td>
<b-td v-if="isTokenField(value)">
{{ formatTokens( value ) }}
@ -15,8 +21,31 @@
<b-td v-else-if="Array.isArray(value)">
<array-field-component :tablefield="value" />
</b-td>
<b-td
v-else-if="typeof (value) ==='object'"
hover
>
<b-tabs>
<b-tab
v-for="key in Object.keys(value)"
:key="key"
:title="key"
variant="danger"
>
<array-field-component
v-if="Array.isArray(value[key])"
:tablefield="value[key]"
/>
<object-field-component
v-else-if="typeof value[key] === 'object'"
:tablefield="value[key]"
/>
<span v-else>{{ formatText(value[key]) }} </span>
</b-tab>
</b-tabs>
</b-td>
<b-td v-else>
{{ value }}
{{ formatText(value) }}
</b-td>
</b-tr>
</b-table-simple>
@ -24,15 +53,10 @@
<script>
import {
BTableSimple, BTr, BTd,
BTableSimple, BTr, BTd, BTabs, BTab,
} from 'bootstrap-vue'
import { isToken, tokenFormatter } from '@/libs/data'
import { abbr, isToken, tokenFormatter } from '@/libs/data'
import ArrayFieldComponent from './ArrayFieldComponent.vue'
// import fetch from 'node-fetch'
// import { tokenFormatter } from '@/libs/data/data'
// import { Proposal, Proposer } from '@/libs/data'
// import { formatToken } from '@/libs/data/data'
export default {
name: 'ObjectFieldComponent',
@ -40,15 +64,26 @@ export default {
BTableSimple,
BTr,
BTd,
BTabs,
BTab,
ArrayFieldComponent,
},
props: {
tablefield: {
type: Object,
type: [Array, Object],
default: () => {},
},
},
methods: {
formatObject(value) {
// console.log(value, typeof (value) === 'object', Object.keys(value))
// if (typeof (value) === 'object' && Object.keys(value).length === 1) {
// console.log(value)
// return value[Object.keys(value)[0]]
// }
return value
},
formatText: v => abbr(v, 60),
eval_value(value) {
return Array.from(value)
},
@ -61,3 +96,7 @@ export default {
},
}
</script>
<style scoped>
</style>

View File

@ -293,7 +293,7 @@ export default {
inProgress: 64,
},
selfDelegation: {
balance: {},
balance: { amount: 0 },
},
latestHeight: 0,
accountAddress: '-',

130
src/views/Transaction.vue Normal file
View File

@ -0,0 +1,130 @@
<template>
<div>
<b-card title="Baisc">
<b-table-simple>
<b-tr>
<b-td style="width:200px">
{{ 'txhash' }}
</b-td><b-td>{{ tx.txhash }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'status' }}
</b-td><b-td> <b-badge
v-if="tx.code===0"
variant="light-success"
>
Success
</b-badge><b-badge
v-else
variant="light-danger"
>
Failed
</b-badge><b v-if="tx.code > 0"> {{ tx.raw_log }}</b> </b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'height' }}
</b-td><b-td>{{ tx.height }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'timestamp' }}
</b-td><b-td>{{ formatTime(tx.timestamp) }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'gas_used' }}
</b-td><b-td>{{ tx.gas_used }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'gas_wanted' }}
</b-td><b-td>{{ tx.gas_wanted }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'gas' }}
</b-td><b-td>{{ tx.tx.gas }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'fee' }}
</b-td><b-td>{{ formattoken(tx.tx.fee) }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'memo' }}
</b-td><b-td>{{ tx.tx.memo }}</b-td>
</b-tr>
<b-tr>
<b-td>
{{ 'timeout_height' }}
</b-td><b-td>{{ tx.tx.timeout_height }}</b-td>
</b-tr>
</b-table-simple>
</b-card>
<b-card
v-if="tx.tx.messages"
:title="`Messages (total: ${tx.tx.messages.length})`"
>
<b-card-body
v-for="(item, i) in tx.tx.messages "
id="message"
:key="i"
class="message"
>
<object-field-component :tablefield="item" />
</b-card-body>
</b-card>
</div>
</template>
<script>
import {
BCard, BTableSimple, BTr, BTd, BBadge, BCardBody,
} from 'bootstrap-vue'
import { toDay, tokenFormatter } from '@/libs/data'
import ObjectFieldComponent from './ObjectFieldComponent.vue'
export default {
components: {
BCard,
BCardBody,
BTableSimple,
BTr,
BTd,
BBadge,
ObjectFieldComponent,
},
data() {
return {
tx: { tx: {} },
}
},
created() {
const { hash } = this.$route.params
this.$http.getTxs(hash).then(res => {
console.log(res)
this.tx = res
})
},
methods: {
formattoken: v => tokenFormatter(v),
formatTime: v => toDay(v),
},
}
</script>
<style>
#message {
border-top-width: 2px;
border-top-style: double;
}
#message table.table-hover tr td:hover {
border-width: 1px;
border: double;
border-radius: 0.5px;
}
</style>

View File

@ -957,6 +957,15 @@
dependencies:
bn.js "^4.11.8"
"@cosmjs/proto-signing@^0.25.6":
version "0.25.6"
resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8"
integrity sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA==
dependencies:
"@cosmjs/amino" "^0.25.6"
long "^4.0.0"
protobufjs "~6.10.2"
"@cosmjs/utils@^0.25.6":
version "0.25.6"
resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca"
@ -1187,6 +1196,59 @@
consola "^2.15.0"
node-fetch "^2.6.1"
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
"@protobufjs/base64@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
"@protobufjs/codegen@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.nlark.com/@sindresorhus/is/download/@sindresorhus/is-0.14.0.tgz"
@ -1349,6 +1411,11 @@
dependencies:
"@types/node" "*"
"@types/long@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
"@types/mime@^1":
version "1.3.2"
resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz"
@ -1374,6 +1441,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a"
integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==
"@types/node@^13.7.0":
version "13.13.52"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7"
integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==
"@types/normalize-package-data@^2.4.0":
version "2.4.1"
resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz"
@ -7130,6 +7202,11 @@ loglevel@^1.6.8:
resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz"
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
longest@^1.0.0:
version "1.0.1"
resolved "https://registry.npm.taobao.org/longest/download/longest-1.0.1.tgz"
@ -8901,6 +8978,25 @@ proto-list@~1.2.1:
resolved "https://registry.npm.taobao.org/proto-list/download/proto-list-1.2.4.tgz"
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
protobufjs@~6.10.2:
version "6.10.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b"
integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
"@protobufjs/codegen" "^2.0.4"
"@protobufjs/eventemitter" "^1.1.0"
"@protobufjs/fetch" "^1.1.0"
"@protobufjs/float" "^1.0.2"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/path" "^1.1.2"
"@protobufjs/pool" "^1.1.0"
"@protobufjs/utf8" "^1.1.0"
"@types/long" "^4.0.1"
"@types/node" "^13.7.0"
long "^4.0.0"
proxy-addr@~2.0.5:
version "2.0.7"
resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz"