mirror of
https://github.com/Instadapp/smart-lookup.git
synced 2024-07-29 22:38:20 +00:00
refactor
This commit is contained in:
parent
b90e568d71
commit
829e6bcac5
223
composables/useLookup.ts
Normal file
223
composables/useLookup.ts
Normal file
|
@ -0,0 +1,223 @@
|
|||
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 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 networkProviderMap = Object.keys(networks).reduce((acc, curr) => {
|
||||
acc[curr] = new ethers.providers.JsonRpcProvider(networks[curr]);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
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 a 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 a 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 } };
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export function useLookup(addressOrEnsName: string) {
|
||||
|
||||
const taskResults = ref([]);
|
||||
const error = ref("");
|
||||
const mainnetProvider = new ethers.providers.JsonRpcProvider(networks.mainnet);
|
||||
|
||||
const address = ref(ethers.utils.isAddress(addressOrEnsName) ? addressOrEnsName : "");
|
||||
const shortAddress = computed(() => address.value ? address.value.substr(0, 8) + "..." + address.value.substr(-6) : "");
|
||||
|
||||
const ens = ref("");
|
||||
const detectedNetworks = computed(() => [
|
||||
...new Set(
|
||||
taskResults.value.flatMap(({ networkResults }) => {
|
||||
if (networkResults) {
|
||||
return Object.keys(networkResults).filter(
|
||||
(network) => !!networkResults[network].metadata
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
onMounted(async () => {
|
||||
if (!address.value) {
|
||||
try {
|
||||
address.value = await mainnetProvider.resolveName(addressOrEnsName);
|
||||
ens.value = addressOrEnsName;
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
if (!address.value) {
|
||||
error.value = "Invalid address or ENS name";
|
||||
return;
|
||||
}
|
||||
|
||||
if (address.value && !ens.value) {
|
||||
mainnetProvider
|
||||
.lookupAddress(address.value)
|
||||
.then(async (result) => {
|
||||
ens.value = result;
|
||||
})
|
||||
.catch((err) => { });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
return {
|
||||
address, ens, detectedNetworks, taskResults, error, shortAddress
|
||||
}
|
||||
}
|
|
@ -6,16 +6,8 @@ import {
|
|||
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 route = useRoute();
|
||||
|
||||
const networkScanBaseUrl = {
|
||||
mainnet: "https://etherscan.io/",
|
||||
|
@ -26,28 +18,6 @@ const networkScanBaseUrl = {
|
|||
arbitrum: "https://arbiscan.io/",
|
||||
};
|
||||
|
||||
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",
|
||||
|
@ -60,192 +30,7 @@ const statusIcon = {
|
|||
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 a 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 a 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 error = 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 = computed(() => [
|
||||
...new Set(
|
||||
taskResults.value.flatMap(({ networkResults }) => {
|
||||
if (networkResults) {
|
||||
return Object.keys(networkResults).filter(
|
||||
(network) => !!networkResults[network].metadata
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
onMounted(async () => {
|
||||
if (!address.value) {
|
||||
try {
|
||||
address.value = await mainnetProvider.resolveName(addressParam);
|
||||
ens.value = addressParam;
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
if (!address.value) {
|
||||
error.value = "Invalid address or ENS name";
|
||||
return;
|
||||
}
|
||||
|
||||
if (address.value && !ens.value) {
|
||||
mainnetProvider
|
||||
.lookupAddress(address.value)
|
||||
.then(async (result) => {
|
||||
ens.value = result;
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
const { address, ens, detectedNetworks, taskResults, error, shortAddress } = useLookup(String(route.params.address));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -266,7 +51,7 @@ onMounted(async () => {
|
|||
<div class="mt-8">
|
||||
<div class="text-center">
|
||||
<div class="text-gray-600 text-sm">
|
||||
<div class="font-bold">{{ shortenAddress() }}</div>
|
||||
<div class="font-bold">{{ shortAddress }}</div>
|
||||
<div class="text-gray-500" v-if="ens">({{ ens }})</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user