mirror of
https://github.com/Instadapp/smart-lookup.git
synced 2024-07-29 22:38:20 +00:00
init
This commit is contained in:
commit
627ab9fe56
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
node_modules
|
||||||
|
*.log*
|
||||||
|
.nuxt
|
||||||
|
.nitro
|
||||||
|
.cache
|
||||||
|
.output
|
||||||
|
.env
|
||||||
|
dist
|
42
README.md
Normal file
42
README.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# Nuxt 3 Minimal Starter
|
||||||
|
|
||||||
|
Look at the [nuxt 3 documentation](https://v3.nuxtjs.org) to learn more.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Make sure to install the dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# yarn
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# npm
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm install --shamefully-hoist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Server
|
||||||
|
|
||||||
|
Start the development server on http://localhost:3000
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
Build the application for production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Locally preview production build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
Checkout the [deployment documentation](https://v3.nuxtjs.org/guide/deploy/presets) for more information.
|
8
app.vue
Normal file
8
app.vue
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<template>
|
||||||
|
<Html class="h-full bg-gray-50">
|
||||||
|
<Body class="h-full" />
|
||||||
|
</Html>
|
||||||
|
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8">
|
||||||
|
<NuxtPage />
|
||||||
|
</div>
|
||||||
|
</template>
|
10
nuxt.config.ts
Normal file
10
nuxt.config.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { defineNuxtConfig } from 'nuxt'
|
||||||
|
|
||||||
|
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
modules: ['@nuxtjs/tailwindcss'],
|
||||||
|
|
||||||
|
build: {
|
||||||
|
transpile: [/ethers/, "@heroicons/vue"]
|
||||||
|
}
|
||||||
|
})
|
19
package.json
Normal file
19
package.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"generate": "nuxt generate",
|
||||||
|
"preview": "nuxt preview"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nuxtjs/tailwindcss": "^5.1.2",
|
||||||
|
"@tailwindcss/forms": "^0.5.2",
|
||||||
|
"nuxt": "3.0.0-rc.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@heroicons/vue": "^1.0.6",
|
||||||
|
"ethers": "^5.6.8",
|
||||||
|
"qrcode.vue": "^3.3.3"
|
||||||
|
}
|
||||||
|
}
|
354
pages/[address].vue
Normal file
354
pages/[address].vue
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import QrcodeVue from "qrcode.vue";
|
||||||
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
XIcon,
|
||||||
|
ExclamationIcon,
|
||||||
|
RefreshIcon,
|
||||||
|
} from "@heroicons/vue/solid";
|
||||||
|
import { ethers } from "ethers";
|
||||||
|
|
||||||
|
const networks = {
|
||||||
|
mainnet: "https://rpc.ankr.com/eth",
|
||||||
|
polygon: "https://rpc.ankr.com/polygon",
|
||||||
|
avalanche: "https://rpc.ankr.com/avalanche",
|
||||||
|
fantom: "https://rpc.ankr.com/fantom",
|
||||||
|
optimism: "https://rpc.ankr.com/optimism",
|
||||||
|
arbitrum: "https://rpc.ankr.com/arbitrum",
|
||||||
|
};
|
||||||
|
|
||||||
|
const networkProviderMap = Object.keys(networks).reduce((acc, curr) => {
|
||||||
|
acc[curr] = new ethers.providers.JsonRpcProvider(networks[curr]);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const gnosisSafeAbi = [
|
||||||
|
{
|
||||||
|
inputs: [],
|
||||||
|
name: "getOwners",
|
||||||
|
outputs: [{ internalType: "address[]", name: "", type: "address[]" }],
|
||||||
|
stateMutability: "view",
|
||||||
|
type: "function",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputs: [],
|
||||||
|
name: "getThreshold",
|
||||||
|
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
||||||
|
stateMutability: "view",
|
||||||
|
type: "function",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const statusIconBackground = {
|
||||||
|
success: "bg-green-500",
|
||||||
|
error: "bg-red-500",
|
||||||
|
warning: "bg-orange-500",
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusIcon = {
|
||||||
|
success: CheckIcon,
|
||||||
|
error: XIcon,
|
||||||
|
warning: ExclamationIcon,
|
||||||
|
};
|
||||||
|
|
||||||
|
type TaskCheckResponse = {
|
||||||
|
status: "success" | "error" | "warning";
|
||||||
|
metadata?: object;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TaskCheckFun = ({
|
||||||
|
address: string,
|
||||||
|
provider: any,
|
||||||
|
}) => PromiseLike<TaskCheckResponse>;
|
||||||
|
|
||||||
|
type Task = {
|
||||||
|
description: string;
|
||||||
|
networkResults?: {
|
||||||
|
[network: string]: TaskCheckResponse;
|
||||||
|
};
|
||||||
|
statusStrategy?: "some" | "every";
|
||||||
|
check: TaskCheckFun;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tasks: Array<Task> = [
|
||||||
|
{
|
||||||
|
description: "This is an EOA",
|
||||||
|
|
||||||
|
async check({ address, provider }) {
|
||||||
|
const code = await provider.getCode(address);
|
||||||
|
|
||||||
|
if (code != "0x") {
|
||||||
|
return { status: "error" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status: "success" };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
description: "This is an smart contract address",
|
||||||
|
|
||||||
|
statusStrategy: "some",
|
||||||
|
|
||||||
|
async check({ address, provider }) {
|
||||||
|
const code = await provider.getCode(address);
|
||||||
|
|
||||||
|
if (code === "0x") {
|
||||||
|
return { status: "error" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status: "success" };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
description: "This is an gnosis safe address",
|
||||||
|
|
||||||
|
statusStrategy: "some",
|
||||||
|
|
||||||
|
async check({ address, provider }) {
|
||||||
|
const contract = new ethers.Contract(address, gnosisSafeAbi, provider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [owners, threshold] = await Promise.all([
|
||||||
|
contract.getOwners(),
|
||||||
|
contract.getThreshold(),
|
||||||
|
]);
|
||||||
|
return {
|
||||||
|
status: "success",
|
||||||
|
metadata: { owners, threshold: threshold.toString() },
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { status: "error" };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
description: "This address has transactions",
|
||||||
|
|
||||||
|
statusStrategy: "some",
|
||||||
|
|
||||||
|
async check({ address, provider }) {
|
||||||
|
const count = await provider.getTransactionCount(address);
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
|
return { status: "error" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status: "success", metadata: { count } };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const taskResults = ref([]);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const addressParam = String(route.params.address);
|
||||||
|
const mainnetProvider = new ethers.providers.JsonRpcProvider(networks.mainnet);
|
||||||
|
|
||||||
|
const address = ref(ethers.utils.isAddress(addressParam) ? addressParam : "");
|
||||||
|
const shortenAddress = () => {
|
||||||
|
return address.value.substr(0, 8) + "..." + address.value.substr(-6);
|
||||||
|
};
|
||||||
|
const ens = ref("");
|
||||||
|
const detectedNetworks = ref(["mainnet", "polygon"]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
if (!address.value) {
|
||||||
|
try {
|
||||||
|
address.value = await mainnetProvider.resolveName(addressParam);
|
||||||
|
ens.value = addressParam;
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!address.value) {
|
||||||
|
// do something
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let index = 0; index < tasks.length; index++) {
|
||||||
|
const task = tasks[index];
|
||||||
|
|
||||||
|
taskResults.value.push({
|
||||||
|
description: task.description,
|
||||||
|
networkResults: {
|
||||||
|
mainnet: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
polygon: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
avalanche: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
fantom: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
optimism: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
arbitrum: {
|
||||||
|
status: "success",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status: "success",
|
||||||
|
loading: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.allSettled(
|
||||||
|
Object.keys(networks).map(async (network) => {
|
||||||
|
const result = await task.check({
|
||||||
|
address: address.value,
|
||||||
|
provider: networkProviderMap[network],
|
||||||
|
});
|
||||||
|
|
||||||
|
taskResults.value[index].networkResults[network] = result;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
taskResults.value[index].status = Object.values(
|
||||||
|
taskResults.value[index].networkResults
|
||||||
|
)[task.statusStrategy || "every"](({ status }) => status === "success")
|
||||||
|
? "success"
|
||||||
|
: "error";
|
||||||
|
taskResults.value[index].loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address.value) {
|
||||||
|
ens.value = await mainnetProvider.lookupAddress(address.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-xl">
|
||||||
|
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<QrcodeVue
|
||||||
|
:size="196"
|
||||||
|
:value="address"
|
||||||
|
class="rounded-lg p-2 border-2 border-gray-200"
|
||||||
|
foreground="#052740"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="mt-8">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-gray-600 text-sm">
|
||||||
|
<div class="font-bold">{{ shortenAddress() }}</div>
|
||||||
|
<div class="text-gray-500" v-if="ens">({{ ens }})</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<div class="text-center flex flex-wrap gap-2">
|
||||||
|
<div
|
||||||
|
v-for="network in detectedNetworks"
|
||||||
|
class="capitalize bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm shadow-sm"
|
||||||
|
>
|
||||||
|
{{ network }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-8 w-full px-4">
|
||||||
|
<div class="flow-root">
|
||||||
|
<ul role="list" class="-mb-5">
|
||||||
|
<li v-for="(task, taskIdx) in taskResults" :key="taskIdx">
|
||||||
|
<div class="relative pb-5">
|
||||||
|
<span
|
||||||
|
v-if="taskIdx !== taskResults.length - 1"
|
||||||
|
class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<div class="relative flex space-x-3">
|
||||||
|
<div v-if="task.loading">
|
||||||
|
<span
|
||||||
|
:class="[
|
||||||
|
'bg-gray-400',
|
||||||
|
'h-8 w-8 rounded-full flex items-center justify-center ring-8 ring-white',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<RefreshIcon
|
||||||
|
class="h-5 w-5 text-white animate-spin"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<span
|
||||||
|
:class="[
|
||||||
|
statusIconBackground[task.status],
|
||||||
|
'h-8 w-8 rounded-full flex items-center justify-center ring-8 ring-white',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="statusIcon[task.status]"
|
||||||
|
class="h-5 w-5 text-white"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="min-w-0 flex-1 pt-1.5">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{{ task.description }}
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="task.network"
|
||||||
|
class="text-gray-500 text-sm"
|
||||||
|
>
|
||||||
|
({{ task.network }})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ml-4 text-sm whitespace-nowrap text-gray-500 space-y-2"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-for="(result, network) in task.networkResults"
|
||||||
|
>
|
||||||
|
<div v-if="result.metadata">
|
||||||
|
<div class="capitalize text-bold">
|
||||||
|
{{ network }}
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<ul class="space-y-2 list-disc">
|
||||||
|
<li v-for="(value, key) in result.metadata">
|
||||||
|
<span class="font-semibold capitalize">{{
|
||||||
|
key
|
||||||
|
}}</span
|
||||||
|
>:
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="ml-10"
|
||||||
|
v-if="Array.isArray(value)"
|
||||||
|
>
|
||||||
|
<ul class="list-decimal">
|
||||||
|
<li v-for="val in value">
|
||||||
|
{{ val }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span v-else class="text-xs">{{
|
||||||
|
String(value)
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
7
pages/index.vue
Normal file
7
pages/index.vue
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
|
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
|
||||||
|
<div>Enter any address</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
8
tailwind.config.js
Normal file
8
tailwind.config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// tailwind.config.js
|
||||||
|
module.exports = {
|
||||||
|
// ...
|
||||||
|
plugins: [
|
||||||
|
// ...
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
],
|
||||||
|
}
|
4
tsconfig.json
Normal file
4
tsconfig.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
// https://v3.nuxtjs.org/concepts/typescript
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user