Add initial support for address:nonce search

This commit is contained in:
Willian Mitsuda 2022-01-22 15:02:00 -03:00
parent fe673bd0f8
commit 80ef1cf820
2 changed files with 72 additions and 7 deletions

View File

@ -2,6 +2,7 @@ import {
ChangeEventHandler, ChangeEventHandler,
FormEventHandler, FormEventHandler,
RefObject, RefObject,
useContext,
useRef, useRef,
useState, useState,
} from "react"; } from "react";
@ -12,6 +13,8 @@ import { isHexString } from "@ethersproject/bytes";
import useKeyboardShortcut from "use-keyboard-shortcut"; import useKeyboardShortcut from "use-keyboard-shortcut";
import { PAGE_SIZE } from "../params"; import { PAGE_SIZE } from "../params";
import { ProcessedTransaction, TransactionChunk } from "../types"; import { ProcessedTransaction, TransactionChunk } from "../types";
import { RuntimeContext } from "../useRuntime";
import { getTransactionBySenderAndNonceFetcher } from "../useErigonHooks";
export class SearchController { export class SearchController {
private txs: ProcessedTransaction[]; private txs: ProcessedTransaction[];
@ -206,9 +209,30 @@ export class SearchController {
} }
} }
const doSearch = (q: string, navigate: NavigateFunction) => { const doSearch = async (
if (isAddress(q)) { provider: JsonRpcProvider,
navigate(`/address/${q}`, { replace: true }); q: string,
navigate: NavigateFunction
) => {
// Cleanup
q = q.trim();
let maybeAddress = q;
let maybeIndex: string | undefined;
const sepIndex = q.lastIndexOf(":");
if (sepIndex !== -1) {
maybeAddress = q.substring(0, sepIndex);
maybeIndex = q.substring(sepIndex + 1);
}
if (isAddress(maybeAddress)) {
// Plain address + nonce?
if (await navigateToTx(provider, maybeAddress, maybeIndex, navigate)) {
return;
}
// Plain address
navigate(`/address/${maybeAddress}`, { replace: true });
return; return;
} }
@ -224,7 +248,47 @@ const doSearch = (q: string, navigate: NavigateFunction) => {
} }
// Assume it is an ENS name // Assume it is an ENS name
navigate(`/address/${q}`); const resolvedName = await provider.resolveName(maybeAddress);
if (resolvedName !== null) {
await navigateToTx(provider, resolvedName, maybeIndex, navigate);
}
// TODO: handle default
};
const navigateToTx = async (
provider: JsonRpcProvider,
maybeAddress: string,
maybeIndex: string | undefined,
navigate: NavigateFunction
): Promise<boolean> => {
if (maybeIndex !== undefined) {
try {
let nonce = 0;
if (maybeIndex === "latest") {
const count = await provider.getTransactionCount(maybeAddress);
if (count > 0) {
nonce = count - 1;
}
} else {
nonce = parseInt(maybeIndex);
}
const txHash = await getTransactionBySenderAndNonceFetcher({
provider,
sender: maybeAddress,
nonce,
});
if (txHash) {
navigate(`/tx/${txHash}`, { replace: true });
}
return true;
} catch (err) {
// ignore
}
}
return false;
}; };
export const useGenericSearch = (): [ export const useGenericSearch = (): [
@ -232,6 +296,7 @@ export const useGenericSearch = (): [
ChangeEventHandler<HTMLInputElement>, ChangeEventHandler<HTMLInputElement>,
FormEventHandler<HTMLFormElement> FormEventHandler<HTMLFormElement>
] => { ] => {
const { provider } = useContext(RuntimeContext);
const [searchString, setSearchString] = useState<string>(""); const [searchString, setSearchString] = useState<string>("");
const [canSubmit, setCanSubmit] = useState<boolean>(false); const [canSubmit, setCanSubmit] = useState<boolean>(false);
const navigate = useNavigate(); const navigate = useNavigate();
@ -244,14 +309,14 @@ export const useGenericSearch = (): [
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => { const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault(); e.preventDefault();
if (!canSubmit) { if (!canSubmit || !provider) {
return; return;
} }
if (searchRef.current) { if (searchRef.current) {
searchRef.current.value = ""; searchRef.current.value = "";
} }
doSearch(searchString, navigate); doSearch(provider, searchString, navigate);
}; };
const searchRef = useRef<HTMLInputElement>(null); const searchRef = useRef<HTMLInputElement>(null);

View File

@ -526,7 +526,7 @@ type TransactionBySenderAndNonceKey = {
nonce: number; nonce: number;
}; };
const getTransactionBySenderAndNonceFetcher = async ({ export const getTransactionBySenderAndNonceFetcher = async ({
provider, provider,
sender, sender,
nonce, nonce,