fix wasm verification

This commit is contained in:
Pham Tu 2024-03-29 14:36:54 +07:00
parent a639835288
commit 3576dff998
No known key found for this signature in database
GPG Key ID: 7460FD99133ADA1C
4 changed files with 301 additions and 35 deletions

View File

@ -35,7 +35,7 @@
<!-- Google tag (gtag.js) -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-SSBKVF3GMX"
src="https://www.googletagmanager.com/gtag/js?id=G-5VWD0SDXJE"
></script>
<script>
window.dataLayer = window.dataLayer || [];
@ -43,8 +43,13 @@
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-SSBKVF3GMX');
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
});
gtag('config', 'G-5VWD0SDXJE');
</script>
</body>
</html>

View File

@ -49,6 +49,7 @@
"postcss": "^8.4.23",
"qrcode": "^1.5.3",
"secretjs": "^1.12.4",
"shiki": "^1.2.1",
"tailwindcss": "^3.3.1",
"theme-change": "^2.5.0",
"vite-plugin-vue-layouts": "^0.7.0",

View File

@ -1,9 +1,12 @@
<script setup lang="ts">
import { get, post } from '@/libs/http';
import { useBaseStore } from '@/stores';
import { computed, onMounted, ref } from 'vue';
import DynamicComponent from '@/components/dynamic/DynamicComponent.vue';
import { get, post } from '@/libs/http';
import { useWasmStore } from '@/modules/[chain]/cosmwasm/WasmStore';
import { useBaseStore, useTxDialog } from '@/stores';
import { codeToHtml } from 'shiki';
import { computed, ref } from 'vue';
import { JsonViewer } from 'vue3-json-viewer';
interface Verification {
chainId?: string;
@ -14,6 +17,31 @@ interface Verification {
error?: string;
}
interface SourceCode<T> {
path: string;
isDirectory: boolean;
sourceCode?: T;
}
interface Argument {
format?: string;
type: string;
properties: Record<string, Argument>;
}
interface Method {
type: string;
required: string[];
properties: Record<string, Argument>;
additionalProperties: boolean;
}
interface Schema {
$schema: string;
title: string;
oneOf?: Method[];
}
const props = defineProps({
contract: { type: String },
});
@ -21,19 +49,70 @@ const props = defineProps({
const baseurl = 'https://prod.compiler.welldonestudio.io';
const verification = ref<Verification>({});
const sourceCode = ref<SourceCode<string>[]>([]);
const schemas = ref<SourceCode<string>[]>([]);
const wasmStore = useWasmStore();
const baseStore = useBaseStore();
const dialog = useTxDialog();
const result = ref<Record<string, any>>({});
onMounted(() => {
const base = useBaseStore();
const chainId = base.latest?.block?.header?.chainId || 'Oraichain';
// console.log("mounted", `${baseurl}/deploy-histories/neutron?contract=${props.contract}`, chainId.value)
const url = `${baseurl}/deploy-histories/${chainId}?contract=${props.contract}`;
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);
});
}
function fetchSchema() {
const base = useBaseStore();
const chainId = base.latest?.block?.header?.chainId || 'Oraichain';
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?.chainId || '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?.chainId) {
chain_id.value = s.latest?.block?.header?.chainId || 'unknown';
fetchVerification();
fetchSchema();
fetchSourceCode();
}
});
function verify() {
@ -42,20 +121,88 @@ function verify() {
const data = { contractAddress: props.contract, chainId: id };
post(`${baseurl}/verification/neutron`, data).then((x) => {
if (x.result) verification.value = x.result;
if (x.result) {
verification.value = x.result;
fetchSchema();
fetchSourceCode();
}
});
}
const tab = ref('verification');
function selectTab(tabName: string) {
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);
// 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;
});
function callFunction(title: string, method: string, arg: Argument) {
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;
}
});
//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,
});
} else {
// QueryMsg
wasmStore.wasmClient
.getWasmContractSmartQuery(
props.contract,
`{"${method}": ${JSON.stringify(args)}}`
)
.then((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 class="flex justify-between">
<span
><h2 class="card-title truncate w-full mt-4 text-left">
Verification
</h2></span
>
<span
class="avatar tooltip tooltip-left"
<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">
@ -64,8 +211,122 @@ function verify() {
alt="Powered By WELLDONE Studio"
/>
</div>
</span>
</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>
</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
class="text-[#00cfe8] bg-[rgba(0,207,232,0.12)] rounded shadow mt-4 alert-info"
@ -91,18 +352,5 @@ function verify() {
</ul>
</div>
</div>
<div><DynamicComponent :value="verification" /></div>
<div class="text-center">
<div v-if="Object.keys(verification).length == 0">
<Icon icon="mdi:emoticon-sad-outline"></Icon>Haven't found verification
</div>
<button
class="btn btn-primary mt-5"
@click="verify"
:disabled="verification.error !== undefined"
>
verify
</button>
</div>
</div>
</template>

View File

@ -3267,6 +3267,11 @@
"@noble/hashes" "~1.3.0"
"@scure/base" "~1.1.0"
"@shikijs/core@1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.2.1.tgz#df4bdfd20e0492681716eaca51c086a018b2bdb9"
integrity sha512-KaIS0H4EQ3KI2d++TjYqRNgwp8E3M/68e9veR4QtInzA7kKFgcjeiJqb80fuXW+blDy5fmd11PN9g9soz/3ANQ==
"@sinclair/typebox@^0.24.1":
version "0.24.51"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
@ -8116,6 +8121,13 @@ shelljs@0.8.5, shelljs@^0.8.5:
interpret "^1.0.0"
rechoir "^0.6.2"
shiki@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.2.1.tgz#d48bc631f4172afff62a36b2f395f29403b50e71"
integrity sha512-u+XW6o0vCkUNlneZb914dLO+AayEIwK5tI62WeS//R5HIXBFiYaj/Hc5xcq27Yh83Grr4JbNtUBV8W6zyK4hWg==
dependencies:
"@shikijs/core" "1.2.1"
shx@^0.3.2, shx@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02"