Skip to content

Commit

Permalink
feat: update display of transaction method selectors to human readabl…
Browse files Browse the repository at this point in the history
…e names
  • Loading branch information
MexicanAce committed Dec 1, 2024
1 parent 0d144bc commit 801b8ca
Showing 1 changed file with 91 additions and 15 deletions.
106 changes: 91 additions & 15 deletions packages/app/src/components/transactions/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@
</span>
</TableBodyColumn>
<TableBodyColumn v-if="columns.includes('method')" :data-heading="t('transactions.table.method')">
<div class="transactions-data-method">
<span :data-testid="$testId.transactionsMethodName">{{ item.methodName }}</span>
</div>
<Tooltip>
<div class="transactions-data-method">
<span :data-testid="$testId.transactionsMethodName">{{ item.methodName }}</span>
</div>

<template #content>{{ item.methodName }}</template>
</Tooltip>
</TableBodyColumn>
<TableBodyColumn
v-if="columns.includes('age') && columns.length < 10"
Expand Down Expand Up @@ -194,11 +198,14 @@ import { computed, type PropType, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { $fetch } from "ohmyfetch";
import AddressLink from "@/components/AddressLink.vue";
import Badge from "@/components/common/Badge.vue";
import CopyButton from "@/components/common/CopyButton.vue";
import { shortenFitText } from "@/components/common/HashLabel.vue";
import Pagination from "@/components/common/Pagination.vue";
import Tooltip from "@/components/common/Tooltip.vue";
import ContentLoader from "@/components/common/loaders/ContentLoader.vue";
import Table from "@/components/common/table/Table.vue";
import TableBodyColumn from "@/components/common/table/TableBodyColumn.vue";
Expand Down Expand Up @@ -271,23 +278,92 @@ watch(
{ immediate: true }
);
const getTransactionMethod = (transaction: TransactionListItem) => {
interface OpenChainMethod {
name: string;
filtered: boolean;
}
interface OpenChainResponse {
ok: boolean;
result: {
function: Record<string, OpenChainMethod[]>;
};
}
const fetchMethodNames = async (sighashes: string[]): Promise<Record<string, string>> => {
try {
const response = await $fetch<OpenChainResponse>("https://api.openchain.xyz/signature-database/v1/lookup", {
method: "GET",
params: {
function: sighashes.join(","),
filter: true,
},
headers: {
accept: "application/json",
},
});
const result = response?.result?.function ?? {};
const methodNames: Record<string, string> = {};
Object.entries(result).forEach(([sighash, methods]) => {
// Ensure methods is an array of the expected shape
if (Array.isArray(methods)) {
methods.forEach((method) => {
if (typeof method === "object" && method.name && method.name.split("(").length > 1) {
methodNames[sighash] = method.name.split("(")[0];
}
});
}
});
return methodNames;
} catch (error) {
console.error("Error fetching method names:", error);
return {};
}
};
watch(
data,
async (newData) => {
if (!newData) return;
await loadMethodNames();
},
{ immediate: true }
);
const methodNames = ref<Record<string, string>>({});
const loadMethodNames = async () => {
if (!data.value) return;
const uniqueSighashes = [
...new Set(
data.value?.map((transaction) => transaction.data.slice(0, 10)).filter((sighash) => sighash !== "0x") ?? []
),
];
const fetchedMethodNames = await fetchMethodNames(uniqueSighashes);
methodNames.value = { ...methodNames.value, ...fetchedMethodNames };
};
const getTransactionMethod = (transaction: TransactionListItem, methodNames: Record<string, string>) => {
if (transaction.data === "0x") {
return t("transactions.table.transferMethodName");
}
const sighash = transaction.data.slice(0, 10);
if (props.contractAbi) {
return (
decodeDataWithABI(
{
calldata: transaction.data,
value: transaction.value,
},
props.contractAbi
)?.name ?? sighash
const decodedMethod = decodeDataWithABI(
{ calldata: transaction.data, value: transaction.value },
props.contractAbi
);
if (decodedMethod?.name) {
return decodedMethod.name;
}
}
return sighash;
return methodNames[sighash] ?? sighash;
};
type TransactionListItemMapped = TransactionListItem & {
Expand All @@ -301,7 +377,7 @@ type TransactionListItemMapped = TransactionListItem & {
const transactions = computed<TransactionListItemMapped[] | undefined>(() => {
return data.value?.map((transaction) => ({
...transaction,
methodName: getTransactionMethod(transaction),
methodName: getTransactionMethod(transaction, methodNames.value),
fromNetwork: transaction.isL1Originated ? "L1" : "L2",
toNetwork: "L2", // even withdrawals go through L2 addresses (800A or bridge addresses)
statusColor: transaction.status === "failed" ? "danger" : "dark-success",
Expand Down Expand Up @@ -432,7 +508,7 @@ function getDirection(item: TransactionListItem): Direction {
}
}
.transactions-data-method {
@apply w-[200px] truncate sm:w-auto;
@apply w-36 truncate border-slate-200 rounded border py-0.5 px-2 text-center bg-slate-400/10 text-xs text-slate-600 sm:w-28;
}
.transactions-data-transaction-amount,
.transactions-data-age {
Expand Down

0 comments on commit 801b8ca

Please sign in to comment.