set pretttier to run on commit with husky

This commit is contained in:
2xburnt committed 2025-07-10 10:22:44 -05:00
1 parent abebe228bf
commit 63abc74816
131 files changed
+7727 -5437

No files matched your search

+7 -5
View File
@@ -13,8 +13,8 @@ function calculateValue(value: any) {
if (Array.isArray(value)) {
return (value[0] && value[0].amount) || '-';
}
if(String(value).search(/^\d+s$/g) > -1) {
return formatSeconds(value)
if (String(value).search(/^\d+s$/g) > -1) {
return formatSeconds(value);
}
const newValue = Number(value);
if (`${newValue}` === 'NaN' || typeof value === 'boolean') {
@@ -28,8 +28,8 @@ function calculateValue(value: any) {
}
function formatTitle(v: string) {
if(!v) return ""
return v.replace(/_/g, " ")
if (!v) return '';
return v.replace(/_/g, ' ');
}
</script>
<template>
@@ -46,7 +46,9 @@ function formatTitle(v: string) {
:key="index"
class="rounded-sm bg-active px-4 py-2"
>
<div class="text-xs mb-2 text-secondary capitalize">{{ formatTitle(item?.subtitle) }}</div>
<div class="text-xs mb-2 text-secondary capitalize">
{{ formatTitle(item?.subtitle) }}
</div>
<div class="text-base text-main">{{ calculateValue(item?.value) }}</div>
</div>
</div>
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue';
import { controlledComputed } from '@vueuse/core'
import { controlledComputed } from '@vueuse/core';
interface Props {
title: string;
@@ -47,7 +47,7 @@ const isPositive = controlledComputed(
<div class="">
<h6 class="text-lg text-center font-semibold mt-2 mb-1">
{{ props.stats || '-'}}
{{ props.stats || '-' }}
</h6>
<p class="text-sm text-center">
{{ props.title }}
+13 -14
View File
@@ -7,26 +7,26 @@ const props = defineProps({
css: { type: String },
});
const s = ref(0)
const s = ref(0);
</script>
<template>
<Countdown
v-if="time"
:time="time > 0 ? time : 0"
v-slot="{ days, hours, minutes, seconds }"
class="countdown-container justify-items-center "
class="countdown-container justify-items-center"
>
<span class="text-primary font-bold " :class="css">{{ days }}</span> days
<span class="text-primary font-bold" :class="css">{{ hours }}</span> hours
<span class="text-primary font-bold" :class="css">{{ minutes }}</span> minutes
<span class="text-primary font-bold w-40" :class="css">
<Transition name="slide-up">
<span v-if="seconds % 2 === 0" class="countdown">{{ seconds }}</span>
<span v-else="seconds % 2 === 1" class="countdown">{{ seconds }}</span>
</Transition>
</span>
<span class="ml-10">seconds</span>
<span class="text-primary font-bold" :class="css">{{ days }}</span> days
<span class="text-primary font-bold" :class="css">{{ hours }}</span> hours
<span class="text-primary font-bold" :class="css">{{ minutes }}</span>
minutes
<span class="text-primary font-bold w-40" :class="css">
<Transition name="slide-up">
<span v-if="seconds % 2 === 0" class="countdown">{{ seconds }}</span>
<span v-else="seconds % 2 === 1" class="countdown">{{ seconds }}</span>
</Transition>
</span>
<span class="ml-10">seconds</span>
</Countdown>
</template>
@@ -42,5 +42,4 @@ const s = ref(0)
text-align: right;
float: right;
}
</style>
+43 -35
View File
@@ -2,49 +2,57 @@
import { computed, ref } from 'vue';
const props = defineProps({
total: { type: String },
limit: { type: Number },
callback: { type: Function, required: true },
total: { type: String },
limit: { type: Number },
callback: { type: Function, required: true },
});
const current = ref(1)
const showSize = 3
const current = ref(1);
const showSize = 3;
const pages = computed(() => {
const pages: { color: string, page: number }[] = []
const total = Number(props.total || 0)
if (total > 0 && props.limit && total > props.limit) {
let page = 0
while (true) {
if (page * props.limit >= total) break
page += 1
if (total / props.limit > 10 && page > showSize && page < (total / props.limit - showSize + 1)) {
if (!(page >= current.value - 1 && page <= current.value + 1)) {
continue
}
}
pages.push({
color: page === current.value ? 'btn-primary' : '',
page: page,
})
const pages: { color: string; page: number }[] = [];
const total = Number(props.total || 0);
if (total > 0 && props.limit && total > props.limit) {
let page = 0;
while (true) {
if (page * props.limit >= total) break;
page += 1;
if (
total / props.limit > 10 &&
page > showSize &&
page < total / props.limit - showSize + 1
) {
if (!(page >= current.value - 1 && page <= current.value + 1)) {
continue;
}
}
pages.push({
color: page === current.value ? 'btn-primary' : '',
page: page,
});
}
return pages
})
}
return pages;
});
function gotoPage(pageNum: number) {
current.value = pageNum
props.callback(pageNum)
current.value = pageNum;
props.callback(pageNum);
}
</script>
<template>
<div class="my-5 text-center">
<div v-if="total && limit" class="btn-group">
<button v-for="{ page, color } in pages" :key="page"
class="btn bg-gray-100 text-gray-500 hover:text-white border-none dark:bg-gray-800 dark:text-white" :class="{
'!btn-primary': color === 'btn-primary',
}" @click="gotoPage(page)">
{{ page }}
</button>
</div>
<div class="my-5 text-center">
<div v-if="total && limit" class="btn-group">
<button
v-for="{ page, color } in pages"
:key="page"
class="btn bg-gray-100 text-gray-500 hover:text-white border-none dark:bg-gray-800 dark:text-white"
:class="{
'!btn-primary': color === 'btn-primary',
}"
@click="gotoPage(page)"
>
{{ page }}
</button>
</div>
</div>
</template>
+34 -10
View File
@@ -39,10 +39,12 @@ const voterStatusMap: Record<string, string> = {
const proposalInfo = ref();
function metaItem(metadata: string|undefined): { title: string; summary: string } {
return metadata ? JSON.parse(metadata) : {}
function metaItem(metadata: string | undefined): {
title: string;
summary: string;
} {
return metadata ? JSON.parse(metadata) : {};
}
</script>
<template>
<div class="bg-white dark:bg-[#28334e] rounded text-sm">
@@ -64,13 +66,17 @@ function metaItem(metadata: string|undefined): { title: string; summary: string
:to="`/${chain.chainName}/gov/${item?.proposal_id}`"
class="text-main text-base mb-1 block hover:text-indigo-400 truncate"
>
{{ item?.content?.title || item?.title || metaItem(item?.metadata)?.title }}
{{
item?.content?.title ||
item?.title ||
metaItem(item?.metadata)?.title
}}
</RouterLink>
<div
v-if="item.content"
class="bg-[#f6f2ff] text-[#9c6cff] dark:bg-gray-600 dark:text-gray-300 inline-block rounded-full px-2 py-[1px] text-xs mb-1"
>
{{ showType(item.content['@type']) }}
{{ showType(item.content['@type']) }}
</div>
</div>
</td>
@@ -149,7 +155,11 @@ function metaItem(metadata: string|undefined): { title: string; summary: string
<RouterLink
:to="`/${chain.chainName}/gov/${item?.proposal_id}`"
class="flex-1 w-0 truncate mr-4"
>{{ item?.content?.title || item?.title || metaItem(item?.metadata)?.title }}</RouterLink
>{{
item?.content?.title ||
item?.title ||
metaItem(item?.metadata)?.title
}}</RouterLink
>
<label
for="proposal-detail-modal"
@@ -225,7 +235,6 @@ function metaItem(metadata: string|undefined): { title: string; summary: string
<span v-else>Vote</span></label
>
</div>
</div>
</div>
@@ -242,9 +251,24 @@ function metaItem(metadata: string|undefined): { title: string; summary: string
<h3 class="font-bold text-lg">Description</h3>
<p class="py-4">
<Component
v-if="proposalInfo?.content?.description || proposalInfo?.summary || metaItem(proposalInfo?.metadata)?.summary"
:is="select(proposalInfo?.content?.description || proposalInfo?.summary || metaItem(proposalInfo?.metadata)?.summary, 'horizontal')"
:value="proposalInfo?.content?.description || proposalInfo?.summary || metaItem(proposalInfo?.metadata)?.summary"
v-if="
proposalInfo?.content?.description ||
proposalInfo?.summary ||
metaItem(proposalInfo?.metadata)?.summary
"
:is="
select(
proposalInfo?.content?.description ||
proposalInfo?.summary ||
metaItem(proposalInfo?.metadata)?.summary,
'horizontal'
)
"
:value="
proposalInfo?.content?.description ||
proposalInfo?.summary ||
metaItem(proposalInfo?.metadata)?.summary
"
>
</Component>
</p>
+2 -2
View File
@@ -1,14 +1,14 @@
<script lang="ts" setup>
import { useTxDialog, useBlockchain } from '@/stores';
const store = useTxDialog();
const chainStore = useBlockchain()
const chainStore = useBlockchain();
</script>
<template>
<ping-tx-dialog
:type="store.type"
:sender="store.sender"
:endpoint="store.endpoint"
:params='store.params'
:params="store.params"
:hd-path="store.hdPaths"
:registry-name="chainStore.current?.prettyName || chainStore.chainName"
@view="store.view"
+7 -9
View File
@@ -2,17 +2,17 @@
import type { PropType } from 'vue';
const props = defineProps({
blocks: { type: Array as PropType<{height:string, color: string}[]> },
blocks: { type: Array as PropType<{ height: string; color: string }[]> },
});
</script>
<template>
<div class="flex gap-0.5">
<div class="cursor-default" v-for="(item, index) in blocks" :key="index">
<div class="tooltip"
:data-tip="item.height"
:class="item.color"
style="width: 3px;"
<div
class="tooltip"
:data-tip="item.height"
:class="item.color"
style="width: 3px"
>
&nbsp;
</div>
@@ -20,6 +20,4 @@ const props = defineProps({
</div>
</template>
<style>
</style>
<style></style>
+106 -101
View File
@@ -5,34 +5,34 @@ import { useFormatter } from '@/stores';
import type { CommissionRate } from '@/types';
const props = defineProps({
commission: { type: Object as PropType<CommissionRate> },
commission: { type: Object as PropType<CommissionRate> },
});
let rate = computed(
() => Number(props.commission?.commission_rates.rate || 0) * 100
() => Number(props.commission?.commission_rates.rate || 0) * 100
);
let change = computed(
() => Number(props.commission?.commission_rates.max_change_rate || 0) * 100
() => Number(props.commission?.commission_rates.max_change_rate || 0) * 100
);
let max = computed(
() => Number(props.commission?.commission_rates.max_rate || 1) * 100
() => Number(props.commission?.commission_rates.max_rate || 1) * 100
);
const left = rate;
const right = computed(() => max.value - rate.value);
const s1 = computed(() =>
left.value > change.value ? left.value - change.value : 0
left.value > change.value ? left.value - change.value : 0
);
const s2 = computed(() =>
left.value > change.value ? change.value : left.value
left.value > change.value ? change.value : left.value
);
const s3 = 2;
const s4 = computed(() =>
right.value > change.value ? change.value : right.value
right.value > change.value ? change.value : right.value
);
const s5 = computed(() =>
right.value > change.value ? right.value - change.value : 0
right.value > change.value ? right.value - change.value : 0
);
const series = computed(() => [s1.value, s2.value, s3, s4.value, s5.value]);
@@ -40,107 +40,112 @@ const series = computed(() => [s1.value, s2.value, s3, s4.value, s5.value]);
const format = useFormatter();
const chartConfig = computed(() => {
const secondaryText = `hsl(var(--bc))`;
const primaryText = `hsl(var(--bc))`;
const secondaryText = `hsl(var(--bc))`;
const primaryText = `hsl(var(--bc))`;
return {
chart: {
width: '200px',
sparkline: { enabled: false },
},
colors: ['rgba(109,120,141,0.2)', 'rgba(114,225,40,0.2)', 'rgba(114,225,40,1)', 'rgba(114,225,40,0.2)', 'rgba(109,120,141,0.2)'],
legend: { show: false },
tooltip: { enabled: false },
dataLabels: { enabled: false },
stroke: {
width: 3,
lineCap: 'round',
colors: ['hsl(var(--b1))'],
},
labels: [
'Available',
'Daily Change',
'Commission Rate',
'Daily Change',
'Available',
],
states: {
hover: {
filter: { type: 'none' },
return {
chart: {
width: '200px',
sparkline: { enabled: false },
},
colors: [
'rgba(109,120,141,0.2)',
'rgba(114,225,40,0.2)',
'rgba(114,225,40,1)',
'rgba(114,225,40,0.2)',
'rgba(109,120,141,0.2)',
],
legend: { show: false },
tooltip: { enabled: false },
dataLabels: { enabled: false },
stroke: {
width: 3,
lineCap: 'round',
colors: ['hsl(var(--b1))'],
},
labels: [
'Available',
'Daily Change',
'Commission Rate',
'Daily Change',
'Available',
],
states: {
hover: {
filter: { type: 'none' },
},
active: {
filter: { type: 'none' },
},
},
plotOptions: {
pie: {
endAngle: 130,
startAngle: -130,
customScale: 0.9,
donut: {
size: '83%',
labels: {
show: true,
name: {
offsetY: 25,
fontSize: '1rem',
color: secondaryText,
},
active: {
filter: { type: 'none' },
value: {
offsetY: -15,
fontWeight: 500,
fontSize: '2.125rem',
formatter: (value: unknown) => `${rate.value.toFixed(1)}%`,
color: primaryText,
},
total: {
show: true,
label: 'Commission Rate',
fontSize: '1rem',
color: secondaryText,
formatter: () => `${rate.value.toFixed(1)}%`,
},
},
},
plotOptions: {
pie: {
endAngle: 130,
startAngle: -130,
customScale: 0.9,
donut: {
size: '83%',
labels: {
show: true,
name: {
offsetY: 25,
fontSize: '1rem',
color: secondaryText,
},
value: {
offsetY: -15,
fontWeight: 500,
fontSize: '2.125rem',
formatter: (value: unknown) => `${rate.value.toFixed(1)}%`,
color: primaryText,
},
total: {
show: true,
label: 'Commission Rate',
fontSize: '1rem',
color: secondaryText,
formatter: () => `${rate.value.toFixed(1)}%`,
},
},
},
},
},
},
responsive: [
{
breakpoint: 1709,
options: {
chart: { height: 237 },
},
responsive: [
{
breakpoint: 1709,
options: {
chart: { height: 237 },
},
},
],
};
},
],
};
});
</script>
<template>
<div class="bg-base-100 rounded shadow p-4">
<div class="text-lg text-main font-semibold mb-1">Commission Rate</div>
<div class="text-sm text-gray-500 dark:text-gray-400">
{{ `Updated at ${format.toDay(props.commission?.update_time, 'short')}` }}
</div>
<div class="w-80 m-auto">
<ApexCharts type="donut" :options="chartConfig" :series="series" />
</div>
<div>
<div class="flex items-center justify-center flex-wrap gap-x-3">
<div class="flex items-center gap-x-2">
<div class="bg-success w-[6px] h-[6px] rounded-full"></div>
<span class="text-caption">Rate:{{ rate.toFixed(0) }}%</span>
</div>
<div class="flex items-center gap-x-2">
<div class="bg-success w-[6px] h-[6px] rounded-full opacity-60"></div>
<span class="text-caption">24h: ±{{ change }}%</span>
</div>
<div class="flex items-center gap-x-2">
<div class="bg-secondary w-[6px] h-[6px] rounded-full"></div>
<span class="text-caption">Max:{{ max }}%</span>
</div>
</div>
</div>
<div class="bg-base-100 rounded shadow p-4">
<div class="text-lg text-main font-semibold mb-1">Commission Rate</div>
<div class="text-sm text-gray-500 dark:text-gray-400">
{{ `Updated at ${format.toDay(props.commission?.update_time, 'short')}` }}
</div>
<div class="w-80 m-auto">
<ApexCharts type="donut" :options="chartConfig" :series="series" />
</div>
<div>
<div class="flex items-center justify-center flex-wrap gap-x-3">
<div class="flex items-center gap-x-2">
<div class="bg-success w-[6px] h-[6px] rounded-full"></div>
<span class="text-caption">Rate:{{ rate.toFixed(0) }}%</span>
</div>
<div class="flex items-center gap-x-2">
<div class="bg-success w-[6px] h-[6px] rounded-full opacity-60"></div>
<span class="text-caption">24h: ±{{ change }}%</span>
</div>
<div class="flex items-center gap-x-2">
<div class="bg-secondary w-[6px] h-[6px] rounded-full"></div>
<span class="text-caption">Max:{{ max }}%</span>
</div>
</div>
</div>
</div>
</template>
+252 -157
View File
@@ -1,15 +1,15 @@
<script setup lang="ts">
import { get, post } from "@/libs/http"
import { useBaseStore, useTxDialog } from "@/stores";
import { computed, onMounted, ref } from "vue";
import TextElement from "@/components/dynamic/TextElement.vue";
import { get, post } from '@/libs/http';
import { useBaseStore, useTxDialog } from '@/stores';
import { computed, onMounted, ref } from 'vue';
import TextElement from '@/components/dynamic/TextElement.vue';
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
import { codeToHtml } from 'shiki'
import { useWasmStore } from "@/modules/[chain]/cosmwasm/WasmStore";
import { toBase64 } from "@cosmjs/encoding";
import { codeToHtml } from 'shiki';
import { useWasmStore } from '@/modules/[chain]/cosmwasm/WasmStore';
import { toBase64 } from '@cosmjs/encoding';
import { JsonViewer } from "vue3-json-viewer"
import { CosmjsOfflineSigner } from "@leapwallet/cosmos-snap-provider";
import { JsonViewer } from 'vue3-json-viewer';
import { CosmjsOfflineSigner } from '@leapwallet/cosmos-snap-provider';
interface Verification {
chainId?: string;
@@ -29,13 +29,13 @@ interface SourceCode<T> {
interface Argument {
format?: string;
type: string;
properties: Record<string, Argument>
properties: Record<string, Argument>;
}
interface Method {
type: string;
required: string[];
properties: Record<string, Argument>
properties: Record<string, Argument>;
additionalProperties: boolean;
}
@@ -49,7 +49,7 @@ const props = defineProps({
contract: { type: String },
});
const baseurl = "https://prod.compiler.welldonestudio.io"
const baseurl = 'https://prod.compiler.welldonestudio.io';
const verification = ref<Verification>({});
const sourceCode = ref<SourceCode<string>[]>([]);
@@ -59,206 +59,301 @@ const baseStore = useBaseStore();
const dialog = useTxDialog();
const result = ref<Record<string, any>>({});
function fetchVerification() {
const url = `${baseurl}/deploy-histories/${chain_id.value}?contract=${props.contract}`
get(url).then((x) => {
console.log("verification:", x)
verification.value = x
}).catch(e => {
console.error(e)
})
const url = `${baseurl}/deploy-histories/${chain_id.value}?contract=${props.contract}`;
get(url)
.then((x) => {
console.log('verification:', x);
verification.value = x;
})
.catch((e) => {
console.error(e);
});
}
function fetchSchema() {
const base = useBaseStore()
const chainId = base.latest?.block?.header?.chain_id || "neutron-1"
const url = `${baseurl}/schemas/${chainId}?contract=${props.contract}`
get(url).then(async (x) => {
console.log("schema:", x)
schemas.value = x.sourceCodes
}).catch(e => {
console.error(e)
})
}
function fetchSourceCode() {
const base = useBaseStore()
const chainId = base.latest?.block?.header?.chain_id || "neutron-1"
const url = `${baseurl}/source-codes/${chainId}?contract=${props.contract}`
const theme = baseStore.theme === 'dark' ? 'material-theme' : 'github-light'
get(url).then(async (x) => {
console.log("source codes:", x)
for (let i = 0; i < x.sourceCodes.length; i++) {
const sc = x.sourceCodes[i];
sc.sourceCode = await codeToHtml(sc.sourceCode, {lang: sc.path.endsWith('.toml')?'toml':'rust', theme})
}
sourceCode.value = x.sourceCodes
}).catch(e => {
console.error(e)
})
const base = useBaseStore();
const chainId = base.latest?.block?.header?.chain_id || 'neutron-1';
const url = `${baseurl}/schemas/${chainId}?contract=${props.contract}`;
get(url)
.then(async (x) => {
console.log('schema:', x);
schemas.value = x.sourceCodes;
})
.catch((e) => {
console.error(e);
});
}
const base = useBaseStore()
const chain_id = ref("")
function fetchSourceCode() {
const base = useBaseStore();
const chainId = base.latest?.block?.header?.chain_id || 'neutron-1';
const url = `${baseurl}/source-codes/${chainId}?contract=${props.contract}`;
const theme = baseStore.theme === 'dark' ? 'material-theme' : 'github-light';
get(url)
.then(async (x) => {
console.log('source codes:', x);
for (let i = 0; i < x.sourceCodes.length; i++) {
const sc = x.sourceCodes[i];
sc.sourceCode = await codeToHtml(sc.sourceCode, {
lang: sc.path.endsWith('.toml') ? 'toml' : 'rust',
theme,
});
}
sourceCode.value = x.sourceCodes;
})
.catch((e) => {
console.error(e);
});
}
const base = useBaseStore();
const chain_id = ref('');
base.$subscribe((m, s) => {
if (chain_id.value !== s.latest?.block?.header?.chain_id) {
chain_id.value = s.latest?.block?.header?.chain_id || "unknown"
chain_id.value = s.latest?.block?.header?.chain_id || 'unknown';
fetchVerification();
fetchSchema();
fetchSourceCode();
}
})
});
function verify() {
const base = useBaseStore();
const id = base.latest?.block?.header?.chain_id || 'unknown';
const data = { contractAddress: props.contract, chainId: id };
const base = useBaseStore()
const id = base.latest?.block?.header?.chain_id || "unknown"
const data = {"contractAddress": props.contract, "chainId": id}
post(`${baseurl}/verification/neutron`, data).then((x)=> {
if(x.result) {
verification.value = x.result
fetchSchema();
fetchSourceCode();
}
})
post(`${baseurl}/verification/neutron`, data).then((x) => {
if (x.result) {
verification.value = x.result;
fetchSchema();
fetchSourceCode();
}
});
}
const tab = ref('verification')
const tab = ref('verification');
function selectTab(tabName: string) {
tab.value = tabName
tab.value = tabName;
}
const executions = computed(() => {
return schemas.value
.filter(x => x.path.indexOf('execute_msg')>-1 || x.path.indexOf('query_msg')>-1)
.map(x => JSON.parse(x.sourceCode||"{}") as Schema)
.filter(
(x) =>
x.path.indexOf('execute_msg') > -1 || x.path.indexOf('query_msg') > -1
)
.map((x) => JSON.parse(x.sourceCode || '{}') as Schema);
// if(raw && raw.sourceCode) {
// return JSON.parse(raw.sourceCode) as Schema
// }
// }
// return {} as Schema
})
});
const queries = computed(() => {
let raw = schemas.value.find(x => x.path.indexOf('query_msg')>-1)
if(raw && raw.sourceCode) {
return JSON.parse(raw.sourceCode) as Schema
}
return {} as Schema
})
let raw = schemas.value.find((x) => x.path.indexOf('query_msg') > -1);
if (raw && raw.sourceCode) {
return JSON.parse(raw.sourceCode) as Schema;
}
return {} as Schema;
});
function callFunction(title: string, method: string, arg: Argument) {
if(!props.contract) return
if (!props.contract) return;
// console.log("callFunction", title, method, arg)
let args = {} as Record<string, any>
if(arg.properties) Object.keys(arg.properties).forEach(k => {
const input = document.querySelector(`input[name="${method}-${k}"]`) as HTMLInputElement
if (input) {
args[k] = input.value
}
})
let args = {} as Record<string, any>;
if (arg.properties)
Object.keys(arg.properties).forEach((k) => {
const input = document.querySelector(
`input[name="${method}-${k}"]`
) as HTMLInputElement;
if (input) {
args[k] = input.value;
}
});
//console.log("args", arg.properties, JSON.stringify(args))
if(title === 'ExecuteMsg') {
let execution = {} as Record<string, any>
execution[method] = args
console.log("execution", execution)
dialog.open('wasm_execute_contract', { contract: props.contract, execution})
if (title === 'ExecuteMsg') {
let execution = {} as Record<string, any>;
execution[method] = args;
console.log('execution', execution);
dialog.open('wasm_execute_contract', {
contract: props.contract,
execution,
});
} else {
// QueryMsg
wasmStore.wasmClient
.getWasmContractSmartQuery(props.contract, `{"${method}": ${JSON.stringify(args)}}`)
.getWasmContractSmartQuery(
props.contract,
`{"${method}": ${JSON.stringify(args)}}`
)
.then((x) => {
result.value[`${title}-${method}`] = x;
result.value[`${title}-${method}`] = x;
})
.catch((err) => {
result.value[`${title}-${method}`] = err;
});
}
}
</script>
<template>
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow">
<div role="tablist" class="tabs tabs-boxed">
<a role="tab" class="tab tooltip tooltip-right tooltip-success" data-tip="Powered By WELLDONE Studio">
<div class="w-8 rounded">
<img src="../assets/images/welldone-logo.svg" alt="Powered By WELLDONE Studio"/>
</div>
</a>
<a role="tab" class="tab" :class="{'tab-active': tab==='verification'}" @click="selectTab('verification')">Verification</a>
<a role="tab" class="tab" :class="{'tab-active': tab==='executions'}" @click="selectTab('executions')">Functions</a>
<a role="tab" class="tab" :class="{'tab-active': tab==='source_code'}" @click="selectTab('source_code')">Source Code</a>
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow">
<div role="tablist" class="tabs tabs-boxed">
<a
role="tab"
class="tab tooltip tooltip-right tooltip-success"
data-tip="Powered By WELLDONE Studio"
>
<div class="w-8 rounded">
<img
src="../assets/images/welldone-logo.svg"
alt="Powered By WELLDONE Studio"
/>
</div>
<div class="">
<div v-if="tab === 'verification'"><DynamicComponent :value="verification"/></div>
<div v-if="tab === 'executions'" class="">
<div v-for="{title, oneOf} in executions" class="join join-vertical w-full mt-2">
<div v-if="oneOf" v-for="m in oneOf">
<div v-for="(props, method) in m.properties" class="collapse collapse-arrow join-item border border-base-300">
<input type="radio" name="my-accordion-1" :checked="false"/>
<div class="collapse-title font-medium">
{{title}}::{{ method }}
</div>
<div class="collapse-content">
<div v-for="(p, name) in props.properties" class="form-control pb-2">
<label class="label">
<span class="label-text">{{ name }}</span>
<span></span>
</label>
<input :name="`${method}-${name}`" type="text" :placeholder="p.format" class="input input-sm border border-gray-300 dark:border-gray-600 w-full" />
</div>
<div>
<label v-if="title==='ExecuteMsg'" for="wasm_execute_contract" class="btn btn-sm" @click="callFunction(title, method, props)">{{ method }}</label>
<label v-else class="btn btn-sm" @click="callFunction(title, method, props)">{{ method }}</label>
</div>
<div v-if="result[`${title}-${method}`]" class="mt-2">
<JsonViewer :value="result[`${title}-${method}`]" :theme="baseStore.theme||'dark'" style="background: transparent;" copyable boxed sort :expand-depth="5"/>
</div>
</div>
</a>
<a
role="tab"
class="tab"
:class="{ 'tab-active': tab === 'verification' }"
@click="selectTab('verification')"
>Verification</a
>
<a
role="tab"
class="tab"
:class="{ 'tab-active': tab === 'executions' }"
@click="selectTab('executions')"
>Functions</a
>
<a
role="tab"
class="tab"
:class="{ 'tab-active': tab === 'source_code' }"
@click="selectTab('source_code')"
>Source Code</a
>
</div>
<div class="">
<div v-if="tab === 'verification'">
<DynamicComponent :value="verification" />
</div>
<div v-if="tab === 'executions'" class="">
<div
v-for="{ title, oneOf } in executions"
class="join join-vertical w-full mt-2"
>
<div v-if="oneOf" v-for="m in oneOf">
<div
v-for="(props, method) in m.properties"
class="collapse collapse-arrow join-item border border-base-300"
>
<input type="radio" name="my-accordion-1" :checked="false" />
<div class="collapse-title font-medium">
{{ title }}::{{ method }}
</div>
<div class="collapse-content">
<div
v-for="(p, name) in props.properties"
class="form-control pb-2"
>
<label class="label">
<span class="label-text">{{ name }}</span>
<span></span>
</label>
<input
:name="`${method}-${name}`"
type="text"
:placeholder="p.format"
class="input input-sm border border-gray-300 dark:border-gray-600 w-full"
/>
</div>
<div>
<label
v-if="title === 'ExecuteMsg'"
for="wasm_execute_contract"
class="btn btn-sm"
@click="callFunction(title, method, props)"
>{{ method }}</label
>
<label
v-else
class="btn btn-sm"
@click="callFunction(title, method, props)"
>{{ method }}</label
>
</div>
<div v-if="result[`${title}-${method}`]" class="mt-2">
<JsonViewer
:value="result[`${title}-${method}`]"
:theme="baseStore.theme || 'dark'"
style="background: transparent"
copyable
boxed
sort
:expand-depth="5"
/>
</div>
</div>
</div>
</div>
<div v-if="tab === 'source_code'" class="mt-2 join join-vertical w-full">
<div v-for="sc in sourceCode.filter(x => !x.isDirectory)" class="collapse collapse-arrow join-item border border-base-300">
<input type="radio" name="sourceCodeAccordion" :checked="false"/>
<div class="collapse-title font-medium">{{sc.path}}</div>
<div class="collapse-content overflow-auto" v-html="sc.sourceCode"></div>
</div>
</div>
</div>
<div v-show="tab === 'verification'" class="text-center">
<div v-if="Object.keys(verification).length == 0" >
Haven't found verification
</div>
<button class="btn btn-primary mt-5" @click="verify" v-show="tab === 'verification'" :disabled="verification.error !== undefined">verify</button>
</div>
<!-- alert-info -->
</div>
<div v-if="tab === 'source_code'" class="mt-2 join join-vertical w-full">
<div
class="text-[#00cfe8] bg-[rgba(0,207,232,0.12)] rounded shadow mt-4 alert-info"
v-for="sc in sourceCode.filter((x) => !x.isDirectory)"
class="collapse collapse-arrow join-item border border-base-300"
>
<input type="radio" name="sourceCodeAccordion" :checked="false" />
<div class="collapse-title font-medium">{{ sc.path }}</div>
<div
class="drop-shadow-md px-4 pt-2 pb-2"
style="box-shadow: rgba(0, 207, 232, 0.4) 0px 6px 15px -7px"
>
<h2 class="text-base font-semibold">{{ $t('consensus.tips') }}</h2>
</div>
<div class="px-4 py-4">
<ul style="list-style-type: disc" class="pl-8">
<li>
{{ $t('cosmwasm.tips_description_1') }}
</li>
<li>
<a href="https://docs.welldonestudio.io/code/verification-api/" target="_blank">Link to Verification API Manual</a>
</li>
</ul>
</div>
class="collapse-content overflow-auto"
v-html="sc.sourceCode"
></div>
</div>
</div>
</div>
</template>
<div v-show="tab === 'verification'" class="text-center">
<div v-if="Object.keys(verification).length == 0">
Haven't found verification
</div>
<button
class="btn btn-primary mt-5"
@click="verify"
v-show="tab === 'verification'"
:disabled="verification.error !== undefined"
>
verify
</button>
</div>
<!-- alert-info -->
<div
class="text-[#00cfe8] bg-[rgba(0,207,232,0.12)] rounded shadow mt-4 alert-info"
>
<div
class="drop-shadow-md px-4 pt-2 pb-2"
style="box-shadow: rgba(0, 207, 232, 0.4) 0px 6px 15px -7px"
>
<h2 class="text-base font-semibold">{{ $t('consensus.tips') }}</h2>
</div>
<div class="px-4 py-4">
<ul style="list-style-type: disc" class="pl-8">
<li>
{{ $t('cosmwasm.tips_description_1') }}
</li>
<li>
<a
href="https://docs.welldonestudio.io/code/verification-api/"
target="_blank"
>Link to Verification API Manual</a
>
</li>
</ul>
</div>
</div>
</div>
</template>
+7 -8
View File
@@ -1,18 +1,17 @@
<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router'
const route = useRoute()
import { useRoute } from 'vue-router';
const route = useRoute();
const aa = computed(() => {
const hostname = location.hostname
const hostname = location.hostname;
if (hostname === 'testnet.ping.pub') {
return '2396360'
return '2396360';
} else if (hostname === 'ping.pub') {
return '2395639'
return '2395639';
} else {
return '2396360'
return '2396360';
}
});
</script>
<template>
</template>
<template></template>
+35 -37
View File
@@ -8,51 +8,49 @@ import { useBaseStore } from '@/stores';
const store = useIndexModule();
const baseStore = useBaseStore();
const chartConfig = computed(() => {
const theme = baseStore.theme;
const labels = store.marketData.prices.map((item: any) => item[0]);
return getMarketPriceChartConfig(theme, labels);
const theme = baseStore.theme;
const labels = store.marketData.prices.map((item: any) => item[0]);
return getMarketPriceChartConfig(theme, labels);
});
const kind = ref('price');
const series = computed(() => {
return [
{
name: kind.value === 'price' ? 'Price' : 'Volume',
data:
kind.value === 'price'
? store.marketData.prices.map((item: any) => item[1])
: store.marketData.total_volumes.map(
(item: any) => item[1]
),
},
];
return [
{
name: kind.value === 'price' ? 'Price' : 'Volume',
data:
kind.value === 'price'
? store.marketData.prices.map((item: any) => item[1])
: store.marketData.total_volumes.map((item: any) => item[1]),
},
];
});
function changeChart(type: string) {
kind.value = type;
kind.value = type;
}
</script>
<template>
<div class="tabs tabs-boxed bg-transparent justify-end">
<a
class="tab text-xs mr-2 text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'price' }"
@click="changeChart('price')"
>
Price
</a>
<a
class="tab text-xs text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'volume' }"
@click="changeChart('volume')"
>
Volume
</a>
</div>
<ApexCharts
type="area"
height="230"
:options="chartConfig"
:series="series"
/>
<div class="tabs tabs-boxed bg-transparent justify-end">
<a
class="tab text-xs mr-2 text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'price' }"
@click="changeChart('price')"
>
Price
</a>
<a
class="tab text-xs text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'volume' }"
@click="changeChart('volume')"
>
Volume
</a>
</div>
<ApexCharts
type="area"
height="230"
:options="chartConfig"
:series="series"
/>
</template>
+33 -29
View File
@@ -6,39 +6,43 @@ import { useBaseStore } from '@/stores';
const baseStore = useBaseStore();
const options = computed(() => {
return {
chart: {
type: 'bar',
height: 150
},
plotOptions: {
bar: {
// borderRadius: 4,
horizontal: false,
}
},
dataLabels: {
enabled: false
},
colors: ['#5A67D8'],
xaxis: {
labels: {
show: false,
rotate: -45
},
show: false,
categories: baseStore.recents.map((x) => x.block.header.height).concat(Array(50-baseStore.recents.length).fill('')),
}
};
return {
chart: {
type: 'bar',
height: 150,
},
plotOptions: {
bar: {
// borderRadius: 4,
horizontal: false,
},
},
dataLabels: {
enabled: false,
},
colors: ['#5A67D8'],
xaxis: {
labels: {
show: false,
rotate: -45,
},
show: false,
categories: baseStore.recents
.map((x) => x.block.header.height)
.concat(Array(50 - baseStore.recents.length).fill('')),
},
};
});
const series = computed(() => {
return [{
name: 'Txs',
data: baseStore.recents?.map((x) => x.block.data.txs.length) || []
}]
return [
{
name: 'Txs',
data: baseStore.recents?.map((x) => x.block.data.txs.length) || [],
},
];
});
</script>
<template>
<ApexCharts type="bar" height="150" :options="options" :series="series" />
<ApexCharts type="bar" height="150" :options="options" :series="series" />
</template>
+49 -9
View File
@@ -1,7 +1,7 @@
import { useBlockchain } from '@/stores';
import numeral from 'numeral';
const chainStore = useBlockchain()
const chainStore = useBlockchain();
const themeColors = (theme: string) => {
if (theme === 'light') {
@@ -260,14 +260,55 @@ export const getMarketPriceChartConfig = (
};
// const donutColors = Array.from({length: 19}, () => (`#${Math.floor(Math.random()*16777215+100000).toString(16)}`))
const donutColors = ["#bbe81a", "#ff5f0b", "#43ebef", "#1999e5", "#230b2c", "#628be8", "#aa5343", "#c9fa89", "#e88ea8", "#72e4a2", "#38cd87", "#515e13", "#7bf8f5", "#83dd6e", "#e8b203", "#7d11d5", "#3e4927", "#f303e2", "#249493", "#50e5e6", "#11deb2", "#a2f9c7", "#2a7bdc", "#47383a", "#226da4", "#966319", "#1bdf99", "#f3ab0c", "#961f50", "#832efd", "#875287", "#4bebe7", "#1d3d2e", "#9caea4", "#2772f5", "#938bf1", "#6228a5", "#24fea5", "#c9bbc8", "#e27225", "#54bd9f", "#babb2d", "#bcf591", "#803b36", "#124f03"]
export const getDonutChartConfig = (
theme: string,
labels: string[]
) => {
const donutColors = [
'#bbe81a',
'#ff5f0b',
'#43ebef',
'#1999e5',
'#230b2c',
'#628be8',
'#aa5343',
'#c9fa89',
'#e88ea8',
'#72e4a2',
'#38cd87',
'#515e13',
'#7bf8f5',
'#83dd6e',
'#e8b203',
'#7d11d5',
'#3e4927',
'#f303e2',
'#249493',
'#50e5e6',
'#11deb2',
'#a2f9c7',
'#2a7bdc',
'#47383a',
'#226da4',
'#966319',
'#1bdf99',
'#f3ab0c',
'#961f50',
'#832efd',
'#875287',
'#4bebe7',
'#1d3d2e',
'#9caea4',
'#2772f5',
'#938bf1',
'#6228a5',
'#24fea5',
'#c9bbc8',
'#e27225',
'#54bd9f',
'#babb2d',
'#bcf591',
'#803b36',
'#124f03',
];
export const getDonutChartConfig = (theme: string, labels: string[]) => {
const { themeSecondaryTextColor, themePrimaryTextColor } =
colorVariables(theme);
@@ -359,4 +400,3 @@ export const getDonutChartConfig = (
],
};
};
+1 -1
View File
@@ -7,7 +7,7 @@ const props = defineProps({
</script>
<template>
<div>
<div v-for="(item,index) of props.value" :key="index">
<div v-for="(item, index) of props.value" :key="index">
{{ toBase64(item) }}
</div>
</div>
+1 -1
View File
@@ -3,7 +3,7 @@ import ArrayBytesElement from './ArrayBytesElement.vue';
import ArrayObjectElement from './ArrayObjectElement.vue';
import TextElement from './TextElement.vue';
import ArrayCoinElement from './ArrayCoinElement.vue';
import ArrayStringElement from './ArrayStringElement.vue'
import ArrayStringElement from './ArrayStringElement.vue';
const props = defineProps({
value: { type: Array<Object> },
@@ -18,7 +18,7 @@ const header = computed(() => {
});
</script>
<template>
<div class="overflow-auto max-h-96 ">
<div class="overflow-auto max-h-96">
<table class="table table-xs table-compact table-pin-rows w-full">
<thead v-if="thead">
<tr>
+2 -4
View File
@@ -8,13 +8,11 @@ const props = defineProps(['value']);
<table class="table table-compact w-full text-sm">
<tbody>
<tr v-for="(v, k) of value">
<td
class="capitalize whitespace-break-spaces min-w-max"
>
<td class="capitalize whitespace-break-spaces min-w-max">
{{ String(k).replaceAll('_', ' ') }}
</td>
<td class="w-4/5">
<div class="overflow-hidden w-auto whitespace-normal" >
<div class="overflow-hidden w-auto whitespace-normal">
<Component
v-if="v"
:is="select(v, 'horizontal')"
+97 -41
View File
@@ -6,15 +6,16 @@ import { computed, onMounted, ref } from 'vue';
import { fromBase64, toHex } from '@cosmjs/encoding';
import { registry as nameMatcha } from "@leapwallet/name-matcha"
import { registry as nameMatcha } from '@leapwallet/name-matcha';
const chainStore = useBlockchain()
const chainStore = useBlockchain();
const props = defineProps(['value']);
const format = useFormatter();
function isMD() {
if (
props.value &&
(String(props.value).indexOf('\n') > -1 || String(props.value).indexOf('\\n') > -1)
(String(props.value).indexOf('\n') > -1 ||
String(props.value).indexOf('\\n') > -1)
) {
return true;
}
@@ -22,39 +23,44 @@ function isMD() {
}
function isAddress() {
return isBech32Address(props.value) && String(props.value).indexOf('valoper1') === -1
return (
isBech32Address(props.value) &&
String(props.value).indexOf('valoper1') === -1
);
}
const text = computed(() => {
if(!props.value) return ""
const v = String(props.value)
switch(true) {
case v.length === 28 && v.endsWith("="): {
return format.validator(v) || v
if (!props.value) return '';
const v = String(props.value);
switch (true) {
case v.length === 28 && v.endsWith('='): {
return format.validator(v) || v;
}
// 2023-06-12T03:09:38.253756368Z
case v.search(/^[1-9]\d{3}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}:\d{2}[.\d]*Z$/g) > -1: {
return new Date(v).toLocaleString(navigator.language)
case v.search(/^[1-9]\d{3}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}:\d{2}[.\d]*Z$/g) >
-1: {
return new Date(v).toLocaleString(navigator.language);
}
case toHexOutput.value:
return toHex(fromBase64(v)).toUpperCase()
return toHex(fromBase64(v)).toUpperCase();
}
return v
})
return v;
});
const names = ref([] as {name?: any, provider?: string}[])
const names = ref([] as { name?: any; provider?: string }[]);
onMounted(() => {
if(isAddress()) nameMatcha.lookupAll(props.value).then(re => {
names.value = Object.keys(re).map(key => ({name: re[key], provider: key})).filter( x => x.name)
})
})
const toHexOutput = ref(false)
if (isAddress())
nameMatcha.lookupAll(props.value).then((re) => {
names.value = Object.keys(re)
.map((key) => ({ name: re[key], provider: key }))
.filter((x) => x.name);
});
});
const toHexOutput = ref(false);
const isConvertable = computed(() => {
return String(props.value).endsWith('=') && props.value.length !== 28
})
return String(props.value).endsWith('=') && props.value.length !== 28;
});
</script>
<template>
<MdEditor
@@ -64,32 +70,67 @@ const isConvertable = computed(() => {
class="md-editor-recover"
></MdEditor>
<span v-else-if="isAddress()" class="flex">
<RouterLink :to="`/${chainStore.chainName}/account/${text}`">{{ text }}</RouterLink>
<div v-for="{name, provider} in names">
<span class="text-xs truncate relative py-1 px-2 p2-4 w-fit ml-2 rounded text-success tooltip" :data-tip="provider" :title="provider">
<RouterLink :to="`/${chainStore.chainName}/account/${text}`">{{
text
}}</RouterLink>
<div v-for="{ name, provider } in names">
<span
class="text-xs truncate relative py-1 px-2 p2-4 w-fit ml-2 rounded text-success tooltip"
:data-tip="provider"
:title="provider"
>
<span class="inset-x-0 inset-y-0 opacity-10 absolute bg-success"></span>
<button>{{ name }}</button>
</span>
</div>
</span>
<span v-else class="flex"><span class="break-words max-w-5xl">{{ text }}</span>
<span v-if="isConvertable" @click="toHexOutput = !toHexOutput" class="ml-2 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
</span>
<span v-else class="flex"
><span class="break-words max-w-5xl">{{ text }}</span>
<span
v-if="isConvertable"
@click="toHexOutput = !toHexOutput"
class="ml-2 cursor-pointer"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
</span>
</span>
</span>
</template>
<style lang="scss">
.md-editor-recover {
.h1,h1 {
.h1,
h1 {
font-size: 2rem;
}
.h2,h2 {
.h2,
h2 {
font-size: 1.5rem;
}
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
@@ -104,10 +145,15 @@ const isConvertable = computed(() => {
margin-inline-end: 0px;
padding-inline-start: 40px;
}
dl, ol, ul {
dl,
ol,
ul {
margin-top: 0;
}
address, dl, ol, ul {
address,
dl,
ol,
ul {
margin-bottom: 1rem;
}
p {
@@ -115,11 +161,21 @@ const isConvertable = computed(() => {
margin-bottom: 1rem;
}
a {
color: #666cff !important;
color: #666cff !important;
}
.h1 > a, .h2> a, .h3> a, .h4> a, .h5> a, .h6> a, h1> a, h2> a, h3> a, h4> a, h5> a, h6> a {
.h1 > a,
.h2 > a,
.h3 > a,
.h4 > a,
.h5 > a,
.h6 > a,
h1 > a,
h2 > a,
h3 > a,
h4 > a,
h5 > a,
h6 > a {
color: inherit !important;
}
}
</style>
+1 -5
View File
@@ -1,10 +1,6 @@
<script lang="ts" setup>
const props = defineProps(['value']);
</script>
<template>
<div class="overflow-auto">
{{ value["amount"] }} {{ value["denom"] }}
</div>
<div class="overflow-auto">{{ value['amount'] }} {{ value['denom'] }}</div>
</template>
+28 -21
View File
@@ -9,21 +9,23 @@ const props = defineProps({
});
const txs = computed(() => {
return props.value?.map((x) => {
const tx_bytes = fromBase64(x);
let tx = null
let injected = 'Standard'
try {
tx = decodeTxRaw(fromBase64(x))
} catch(e) {
injected = 'Injected'
}
return {
hash: hashTx(tx_bytes),
tx,
injected
}
}) || []
return (
props.value?.map((x) => {
const tx_bytes = fromBase64(x);
let tx = null;
let injected = 'Standard';
try {
tx = decodeTxRaw(fromBase64(x));
} catch (e) {
injected = 'Injected';
}
return {
hash: hashTx(tx_bytes),
tx,
injected,
};
}) || []
);
});
const format = useFormatter();
@@ -35,7 +37,7 @@ const chain = useBlockchain();
<thead>
<tr>
<th>Type</th>
<th style="position: relative; z-index: 2;">Hash</th>
<th style="position: relative; z-index: 2">Hash</th>
<th>Msgs</th>
<th>Memo</th>
</tr>
@@ -44,10 +46,13 @@ const chain = useBlockchain();
<tr v-for="item in txs">
<td>{{ item.injected }}</td>
<td>
<span v-if="item.injected ==='Injected'">{{ item.hash }}</span>
<RouterLink v-else :to="`/${chain.chainName}/tx/${item.hash}`" class="text-primary dark:invert">{{
item.hash
}}</RouterLink>
<span v-if="item.injected === 'Injected'">{{ item.hash }}</span>
<RouterLink
v-else
:to="`/${chain.chainName}/tx/${item.hash}`"
class="text-primary dark:invert"
>{{ item.hash }}</RouterLink
>
</td>
<td>
<span v-if="item.tx">
@@ -58,7 +63,9 @@ const chain = useBlockchain();
}}
</span>
</td>
<td><span v-if="item.tx">{{ item.tx.body.memo }}</span></td>
<td>
<span v-if="item.tx">{{ item.tx.body.memo }}</span>
</td>
</tr>
</tbody>
</table>
+3 -1
View File
@@ -31,7 +31,9 @@ function selectObject(v: Object, direct?: string) {
return UInt8Array;
case Array.isArray(v):
return ArrayElement;
case v && Object.keys(v).includes('amount') && Object.keys(v).includes('denom'): {
case v &&
Object.keys(v).includes('amount') &&
Object.keys(v).includes('denom'): {
return TokenElement;
}
case direct === 'horizontal':
+11 -1
View File
@@ -1 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" tag="i" class="v-icon notranslate v-theme--light v-icon--size-default iconify iconify--mdi" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M16.36 14c.08-.66.14-1.32.14-2c0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2m-5.15 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95a8.03 8.03 0 0 1-4.33 3.56M14.34 14H9.66c-.1-.66-.16-1.32-.16-2c0-.68.06-1.35.16-2h4.68c.09.65.16 1.32.16 2c0 .68-.07 1.34-.16 2M12 19.96c-.83-1.2-1.5-2.53-1.91-3.96h3.82c-.41 1.43-1.08 2.76-1.91 3.96M8 8H5.08A7.923 7.923 0 0 1 9.4 4.44C8.8 5.55 8.35 6.75 8 8m-2.92 8H8c.35 1.25.8 2.45 1.4 3.56A8.008 8.008 0 0 1 5.08 16m-.82-2C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2c0 .68.06 1.34.14 2M12 4.03c.83 1.2 1.5 2.54 1.91 3.97h-3.82c.41-1.43 1.08-2.77 1.91-3.97M18.92 8h-2.95a15.65 15.65 0 0 0-1.38-3.56c1.84.63 3.37 1.9 4.33 3.56M12 2C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2Z"></path></svg>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
tag="i"
class="v-icon notranslate v-theme--light v-icon--size-default iconify iconify--mdi"
width="1em"
height="1em"
viewBox="0 0 24 24"
><path fill="currentColor" d="M16.36 14c.08-.66.14-1.32.14-2c0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2m-5.15 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95a8.03 8.03 0 0 1-4.33 3.56M14.34 14H9.66c-.1-.66-.16-1.32-.16-2c0-.68.06-1.35.16-2h4.68c.09.65.16 1.32.16 2c0 .68-.07 1.34-.16 2M12 19.96c-.83-1.2-1.5-2.53-1.91-3.96h3.82c-.41 1.43-1.08 2.76-1.91 3.96M8 8H5.08A7.923 7.923 0 0 1 9.4 4.44C8.8 5.55 8.35 6.75 8 8m-2.92 8H8c.35 1.25.8 2.45 1.4 3.56A8.008 8.008 0 0 1 5.08 16m-.82-2C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2c0 .68.06 1.34.14 2M12 4.03c.83 1.2 1.5 2.54 1.91 3.97h-3.82c.41-1.43 1.08-2.77 1.91-3.97M18.92 8h-2.95a15.65 15.65 0 0 0-1.38-3.56c1.84.63 3.37 1.9 4.33 3.56M12 2C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB