Externalize url prefixes

This commit is contained in:
Willian Mitsuda 2021-07-09 13:54:59 -03:00
parent 83d64fc522
commit ea7b7a9f75
7 changed files with 54 additions and 21 deletions

View File

@ -1,3 +1,4 @@
{ {
"erigonURL": "http://localhost:8545" "erigonURL": "http://localhost:8545",
"assetsURLPrefix": "http://localhost:3001"
} }

View File

@ -1,10 +1,14 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { fourBytesURL } from "../url";
import { useRuntime } from "../useRuntime";
type MethodNameProps = { type MethodNameProps = {
data: string; data: string;
}; };
const MethodName: React.FC<MethodNameProps> = ({ data }) => { const MethodName: React.FC<MethodNameProps> = ({ data }) => {
const runtime = useRuntime();
const [name, setName] = useState<string>(); const [name, setName] = useState<string>();
useEffect(() => { useEffect(() => {
if (data === "0x") { if (data === "0x") {
@ -16,7 +20,13 @@ const MethodName: React.FC<MethodNameProps> = ({ data }) => {
// Try to resolve 4bytes name // Try to resolve 4bytes name
const fourBytes = _name.slice(2); const fourBytes = _name.slice(2);
const signatureURL = `http://localhost:3001/signatures/${fourBytes}`; const { config } = runtime;
if (!config) {
setName(_name);
return;
}
const signatureURL = fourBytesURL(config.assetsURLPrefix, fourBytes);
fetch(signatureURL) fetch(signatureURL)
.then(async (res) => { .then(async (res) => {
if (!res.ok) { if (!res.ok) {
@ -37,7 +47,7 @@ const MethodName: React.FC<MethodNameProps> = ({ data }) => {
// Use the default 4 bytes as name // Use the default 4 bytes as name
setName(_name); setName(_name);
}, [data]); }, [runtime, data]);
return ( return (
<div className="bg-blue-50 rounded-lg px-3 py-1 min-h-full flex items-baseline text-xs max-w-max"> <div className="bg-blue-50 rounded-lg px-3 py-1 min-h-full flex items-baseline text-xs max-w-max">

View File

@ -1,5 +1,7 @@
import React, { Suspense } from "react"; import React, { Suspense } from "react";
import { useImage } from "react-image"; import { useImage } from "react-image";
import { tokenLogoURL } from "../url";
import { useRuntime } from "../useRuntime";
type TokenLogoProps = { type TokenLogoProps = {
address: string; address: string;
@ -13,12 +15,14 @@ const TokenLogo: React.FC<TokenLogoProps> = (props) => (
); );
const InternalTokenLogo: React.FC<TokenLogoProps> = ({ address, name }) => { const InternalTokenLogo: React.FC<TokenLogoProps> = ({ address, name }) => {
const { src } = useImage({ const { config } = useRuntime();
srcList: [
`http://localhost:3001/assets/${address}/logo.png`, const srcList: string[] = [];
"/eth-diamond-black.png", if (config) {
], srcList.push(tokenLogoURL(config.assetsURLPrefix, address));
}); }
srcList.push("/eth-diamond-black.png");
const { src } = useImage({ srcList });
return ( return (
<div className="flex items-center justify-center w-5 h-5"> <div className="flex items-center justify-center w-5 h-5">

9
src/url.ts Normal file
View File

@ -0,0 +1,9 @@
export const fourBytesURL = (
assetsURLPrefix: string,
fourBytes: string
): string => `${assetsURLPrefix}/signatures/${fourBytes}`;
export const tokenLogoURL = (
assetsURLPrefix: string,
address: string
): string => `${assetsURLPrefix}/assets/${address}/logo.png`;

View File

@ -2,6 +2,7 @@ import { useState, useEffect } from "react";
export type OtterscanConfig = { export type OtterscanConfig = {
erigonURL: string; erigonURL: string;
assetsURLPrefix: string;
}; };
export const useConfig = (): [boolean?, OtterscanConfig?] => { export const useConfig = (): [boolean?, OtterscanConfig?] => {
@ -14,6 +15,8 @@ export const useConfig = (): [boolean?, OtterscanConfig?] => {
if (res.ok) { if (res.ok) {
const _config: OtterscanConfig = await res.json(); const _config: OtterscanConfig = await res.json();
console.info("Loaded app config");
console.info(_config);
setConfig(_config); setConfig(_config);
setConfigOK(res.ok); setConfigOK(res.ok);
} }

View File

@ -1,16 +1,11 @@
import { useMemo } from "react";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { OtterscanConfig } from "./useConfig";
export const DEFAULT_ERIGON_URL = "http://127.0.0.1:8545"; export const DEFAULT_ERIGON_URL = "http://127.0.0.1:8545";
export const useProvider = ( export const useProvider = (
config?: OtterscanConfig erigonURL?: string
): ethers.providers.JsonRpcProvider | undefined => { ): ethers.providers.JsonRpcProvider | undefined => {
if (!config) {
return undefined;
}
let erigonURL = config?.erigonURL;
if (erigonURL === "") { if (erigonURL === "") {
console.info(`Using default erigon URL: ${DEFAULT_ERIGON_URL}`); console.info(`Using default erigon URL: ${DEFAULT_ERIGON_URL}`);
erigonURL = DEFAULT_ERIGON_URL; erigonURL = DEFAULT_ERIGON_URL;
@ -18,5 +13,12 @@ export const useProvider = (
console.log(`Using configured erigon URL: ${erigonURL}`); console.log(`Using configured erigon URL: ${erigonURL}`);
} }
return new ethers.providers.JsonRpcProvider(erigonURL, "mainnet"); const provider = useMemo(
() => new ethers.providers.JsonRpcProvider(erigonURL, "mainnet"),
[erigonURL]
);
if (!erigonURL) {
return undefined;
}
return provider;
}; };

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useMemo } from "react";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { OtterscanConfig, useConfig } from "./useConfig"; import { OtterscanConfig, useConfig } from "./useConfig";
import { useProvider } from "./useProvider"; import { useProvider } from "./useProvider";
@ -10,13 +10,17 @@ export type OtterscanRuntime = {
export const useRuntime = (): OtterscanRuntime => { export const useRuntime = (): OtterscanRuntime => {
const [configOK, config] = useConfig(); const [configOK, config] = useConfig();
const provider = useProvider(config); const provider = useProvider(configOK ? config?.erigonURL : undefined);
const runtime = useMemo(
(): OtterscanRuntime => ({ config, provider }),
[config, provider]
);
if (!configOK) { if (!configOK) {
return {}; return {};
} }
return runtime;
return { config, provider };
}; };
export const RuntimeContext = React.createContext<OtterscanRuntime>(null!); export const RuntimeContext = React.createContext<OtterscanRuntime>(null!);