Skip to content

Commit

Permalink
feat: check contract source code verifications
Browse files Browse the repository at this point in the history
Use Etherscan API to check whether the contract is verified on a given chain
  • Loading branch information
Destiner committed Nov 16, 2024
1 parent 218bc54 commit 657a719
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 57 deletions.
32 changes: 32 additions & 0 deletions app/components/__common/ScanButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<button :disabled>
<slot />
</button>
</template>

<script setup lang="ts">
const { disabled = false } = defineProps<{
disabled?: boolean;
}>();
</script>

<style scoped>
button {
padding: 8px 6px;
border: 1px solid var(--color-border-primary);
border-radius: var(--border-radius-medium);
background: var(--color-background-primary);
color: var(--color-text-primary);
font-size: 14px;
cursor: pointer;
&:hover {
background: var(--color-background-secondary);
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
}
</style>
15 changes: 15 additions & 0 deletions app/components/__common/icon/Cross.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M11.782 4.032a.575.575 0 1 0-.813-.814L7.5 6.687L4.032 3.218a.575.575 0 0 0-.814.814L6.687 7.5l-3.469 3.468a.575.575 0 0 0 .814.814L7.5 8.313l3.469 3.469a.575.575 0 0 0 .813-.814L8.313 7.5z"
clip-rule="evenodd"
/>
</svg>
</template>
15 changes: 15 additions & 0 deletions app/components/__common/icon/QuestionMark.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M5.075 4.1c0-1.189 1.182-2.175 2.425-2.175s2.425.986 2.425 2.175c0 1.099-.557 1.614-1.306 2.279l-.031.027C7.845 7.065 6.925 7.88 6.925 9.5a.575.575 0 1 0 1.15 0c0-1.085.554-1.594 1.307-2.26l.02-.02c.748-.662 1.673-1.482 1.673-3.12C11.075 2.128 9.219.775 7.5.775S3.925 2.128 3.925 4.1a.575.575 0 1 0 1.15 0M7.5 13.358a.875.875 0 1 0 0-1.75a.875.875 0 0 0 0 1.75"
clip-rule="evenodd"
/>
</svg>
</template>
44 changes: 36 additions & 8 deletions app/components/contract/BlockInfo.vue
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
<template>
<div class="block">
<BlockStatus status="success">exact bytecode match</BlockStatus>
<BlockStatus status="warning">different bytecode</BlockStatus>
<BlockStatus status="error">failed to get code</BlockStatus>
<BlockStatus status="empty">not deployed (no code)</BlockStatus>
<BlockStatus status="progress">querying</BlockStatus>
<div class="root">
<div class="block">
<BlockStatus status="success">exact bytecode match</BlockStatus>
<BlockStatus status="warning">different bytecode</BlockStatus>
<BlockStatus status="error">failed to get code</BlockStatus>
<BlockStatus status="empty">not deployed (no code)</BlockStatus>
<BlockStatus status="progress">querying</BlockStatus>
</div>
<div class="block">
<div class="block-part"><IconCheck class="icon" /> verified</div>
<div class="block-part"><IconCross class="icon" /> unverified</div>
<div class="block-part"><IconQuestionMark class="icon" /> unknown</div>
</div>
</div>
</template>

<script setup lang="ts">
import BlockStatus from './BlockStatus.vue';
import IconCheck from '@/components/__common/icon/Check.vue';
import IconCross from '@/components/__common/icon/Cross.vue';
import IconQuestionMark from '@/components/__common/icon/QuestionMark.vue';
</script>

<style scoped>
.block {
.root {
display: flex;
flex-wrap: wrap;
gap: 8px;
gap: 12px;
padding: 12px 9px;
border: 1px solid var(--color-border-primary);
border-radius: var(--border-radius-medium);
background: var(--color-background-secondary);
}
.block {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
@media (width >= 768px) {
.block {
gap: 20px;
}
}
.block-part {
display: flex;
gap: 4px;
align-items: center;
}
.icon {
width: 16px;
height: 16px;
}
</style>
41 changes: 38 additions & 3 deletions app/components/contract/ChainItem.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
<template>
<div>
<BlockStatus :status="status">
<div class="item">
<IconCheck
v-if="verification === 'verified'"
class="verification icon"
/>
<IconCross
v-else-if="verification === 'unverified'"
class="verification icon"
/>
<IconQuestionMark
v-else-if="verification === 'unknown'"
class="verification icon icon-toned-down"
/>
<BlockStatus
:status="status"
class="block"
>
<div class="item-details">
{{ getChainName(chain) }}
<a
Expand All @@ -22,23 +37,34 @@ import { computed } from 'vue';
import BlockStatus, { type Status } from './BlockStatus.vue';
import IconCheck from '@/components/__common/icon/Check.vue';
import IconCross from '@/components/__common/icon/Cross.vue';
import IconExternalLink from '@/components/__common/icon/ExternalLink.vue';
import IconQuestionMark from '@/components/__common/icon/QuestionMark.vue';
import {
type Chain,
getChainName,
getAddressExplorerUrl,
} from '@/utils/chains';
import type { VerificationStatus } from '@/utils/verification';
const { address, chain } = defineProps<{
const { address, chain, verification } = defineProps<{
address: Address;
chain: Chain;
status: Status;
verification: VerificationStatus | null;
}>();
const explorerUrl = computed(() => getAddressExplorerUrl(chain, address));
</script>

<style scoped>
.item {
display: flex;
position: relative;
align-items: center;
}
.item-details {
display: flex;
gap: 8px;
Expand All @@ -54,4 +80,13 @@ a {
width: 15px;
height: 15px;
}
.icon-toned-down {
opacity: 0.4;
}
.verification {
position: absolute;
left: -20px;
}
</style>
3 changes: 3 additions & 0 deletions app/components/contract/ChainList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:chain="chain.id"
:status="chain.status"
:address="address"
:verification="chain.verification"
/>
</div>
</template>
Expand All @@ -18,12 +19,14 @@ import type { Status } from './BlockStatus.vue';
import ChainItem from './ChainItem.vue';
import type { Chain } from '@/utils/chains';
import type { VerificationStatus } from '@/utils/verification';
const { chains } = defineProps<{
address: Address;
chains: {
id: Chain;
status: Status;
verification: VerificationStatus | null;
}[];
}>();
Expand Down
Loading

0 comments on commit 657a719

Please sign in to comment.