Skip to content

Commit

Permalink
Fixes for a couple of issues (#104)
Browse files Browse the repository at this point in the history
* (feat) Issue #101
(feat) Issue #83

* (feat) #101 - force network by hostname,
(feat) #83 - reload scilla contract state.

* (fix) Lint

* (fix) main-pr-check is no longer appropriate since we renamed branches
  • Loading branch information
rrw-zilliqa authored Jan 24, 2025
1 parent bc8c87d commit 55c5a2f
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 83 deletions.
13 changes: 0 additions & 13 deletions .github/workflows/main-pr-check.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions README.zilliqa.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ errors due to their absence.
You can now pass `network=` and `name=` parameters to preload a network into `localStorage`.
For large sets of prewritten parameters, there is a list of connection objects in `config.json`.

These are overridden if we select network from your hostname.

## Configuration

There are some extra config options - see `public/config.json` for an example. In particular, `connections` is a list of potential connections, each of which is a dictionary:

- `menuName` - name that will appear in the connection menu for this option
- `url` - the URL to query
- `hostnames` - an array of hostnames. If the `window.location` hostname has one of these as a prefix, the `url` will be force-selected and the connections menu will not appear.

## Starting for development

.. because I keep forgetting!
Expand Down
2 changes: 1 addition & 1 deletion public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
{ "menuName": "zq1-mainnet", "url": "https://mainnet-v934-fireblocks.mainnet-20240103-ase1.zq1.network", "hostnames": ["otterscan.zilliqa.com"] },
{ "menuName": "zq1-testnet", "url": "https://testnet-v932-fireblocks.testnet-ase1.zq1.dev", "hostnames": ["otterscan.testnet.zilliqa.com"] },
{ "menuName": "zq2-prototestnet", "url": "https://api.zq2-prototestnet.zilliqa.com", "hostnames": ["explorer.zq2-prototestnet.zilliqa.com" ] },
{ "menuName": "zq2-protomainnet", "url": "https://api.zq2-protomainnet.zilliqa.com", "hostnames": ["explorer.zq2-protomainnet.zilliqa.com"] }
{ "menuName": "zq2-protomainnet", "url": "https://api.zq2-protomainnet.zilliqa.com", "hostnames": ["explorer.zq2-protomainnet.zilliqa.com" ] }
]
}
16 changes: 10 additions & 6 deletions src/ConnectionErrorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ const ConnectionErrorPanel: FC<ConnectionErrorPanelProps> = ({
</Step>
</>
)}
<div className="flex space-x-2 mt-2">
<span className="text-blue-600">
<FontAwesomeIcon icon={faBarsProgress} size="1x" />
</span>
<NetworkMenuWithConfig config={config} />
</div>
{config?.displayConnectionMenu ? (
<div className="flex space-x-2 mt-2">
<span className="text-blue-600">
<FontAwesomeIcon icon={faBarsProgress} size="1x" />
</span>
<NetworkMenuWithConfig config={config} />
</div>
) : (
<div />
)}
</div>
</div>
);
Expand Down
10 changes: 7 additions & 3 deletions src/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ const Header: FC<HeaderProps> = ({ sourcifyPresent }) => {
</div>
</Link>
</div>
<div className="pt-2 flex items-center justify-center">
<NetworkMenu />
</div>
{config.displayConnectionMenu ? (
<div className="pt-2 flex items-center justify-center">
<NetworkMenu />
</div>
) : (
<div />
)}
<div className="flex items-baseline gap-x-3">
{(provider._network.chainId === 1n ||
config.priceOracleInfo?.nativeTokenPrice?.ethUSDOracleAddress) && (
Expand Down
2 changes: 1 addition & 1 deletion src/execution/address/ScillaContract.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ContractProps = {
};

const ScillaContract: React.FC<ContractProps> = ({ address, content }) => {
let [loadContractState, setLoadContractState] = React.useState<boolean>();
let [loadContractState, setLoadContractState] = React.useState<number>(0);

return (
<div>
Expand Down
58 changes: 35 additions & 23 deletions src/execution/address/ScillaState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { ContractState, useSmartContractState } from "../../useZilliqaHooks";

type ScillaStateProps = {
address: string;
loadContractState: boolean | undefined;
setLoadContractState: (arg0: boolean) => void;
loadContractState: number | undefined;
setLoadContractState: React.Dispatch<React.SetStateAction<number>>;
};

type ScillaStateRowProps = {
Expand Down Expand Up @@ -39,10 +39,10 @@ export const ScillaState: FC<ScillaStateProps> = ({
const [contractState, setContractState] = useState<ContractState | null>(
null,
);

const { data, isLoading } = useSmartContractState(
loadContractState ? zilliqa : undefined,
address,
loadContractState ?? 0,
);
if (data && contractState == null) {
setContractState(data);
Expand All @@ -53,7 +53,7 @@ export const ScillaState: FC<ScillaStateProps> = ({
<div className="mt-6">
<button
className="text-link-blue hover:text-link-blue-hover"
onClick={() => setLoadContractState(true)}
onClick={() => setLoadContractState((prev: number) => prev + 1)}
>
Load Contract State
</button>
Expand All @@ -67,25 +67,37 @@ export const ScillaState: FC<ScillaStateProps> = ({

return (
<div className="mt-6">
<table className="w-ful border">
<thead>
<tr className="grid grid-cols-12 gap-x-2 bg-gray-100 py-2 text-left">
<th className="col-span-3 pl-1">name</th>
<th className="col-span-8 pr-1">value</th>
</tr>
</thead>
<tbody className="divide-y">
{contractState
? Object.keys(contractState).map((val) => (
<ScillaStateParamRow
key={val}
name={val}
value={formatJsonValue(contractState[val])}
/>
))
: undefined}
</tbody>
</table>
<button
className="text-link-blue hover:text-link-blue-hover"
onClick={() => {
setContractState(null);
setLoadContractState((prev: number) => prev + 1);
}}
>
Refresh
</button>

<div className={isLoading ? "opacity-50" : ""}>
<table className="w-ful border">
<thead>
<tr className="grid grid-cols-12 gap-x-2 bg-gray-100 py-2 text-left">
<th className="col-span-3 pl-1">name</th>
<th className="col-span-8 pr-1">value</th>
</tr>
</thead>
<tbody className="divide-y">
{contractState
? Object.keys(contractState).map((val) => (
<ScillaStateParamRow
key={val}
name={val}
value={formatJsonValue(contractState[val])}
/>
))
: undefined}
</tbody>
</table>
</div>
</div>
);
};
87 changes: 52 additions & 35 deletions src/useConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ export type OtterscanConfig = {
/** Chain connections
*/
connections?: ChainConnection[];

/** Should we display the connection menu?
*/
displayConnectionMenu?: boolean;
};

/**
Expand Down Expand Up @@ -325,6 +329,9 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
const data = await res.json();
// Override config for local dev
var config: OtterscanConfig = { ...data };
console.log(
`DEV = ${import.meta.env.DEV} ${import.meta.env.VITE_ERIGON_URL}`,
);
if (import.meta.env.DEV) {
config.erigonURL = import.meta.env.VITE_ERIGON_URL ?? config.erigonURL;
config.beaconAPI =
Expand All @@ -339,6 +346,7 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
);
}
}
console.log(`Erigon = ${config.erigonURL}`);
if (config.version === undefined) {
config.version = "(unknown)";
}
Expand All @@ -354,13 +362,13 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
}
//console.log(JSON.stringify(config));
var storageConfiguration: any = {};
var hostForcesConnection: boolean = false;
try {
var storage = window["localStorage"];
if (storage !== undefined) {
storageConfiguration = JSON.parse(
storage.getItem("otterscanConfig") ?? "{}",
);
// console.log("storage Config " + JSON.stringify(storageConfiguration));
}
} catch (err) {
console.log(`Failed to get localStorage config - ${err}`);
Expand All @@ -369,17 +377,16 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
// Default by hostname
try {
var host = window.location.host;
var connections =
storageConfiguration["connections"] ?? config.connections;
// Ignore locally stored connections when matching hostnames.
var connections: ChainConnection[] | undefined = config.connections;
if (connections !== undefined) {
for (var c of connections) {
const hosts = c.hostnames;
if (hosts !== undefined) {
for (var h of hosts) {
if (host.startsWith(h)) {
if (!("erigonURL" in storageConfiguration)) {
storageConfiguration["erigonURL"] = c.url;
}
storageConfiguration["erigonURL"] = c.url;
hostForcesConnection = true;
}
}
}
Expand All @@ -392,7 +399,7 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
// If we've still not got a connection, use the first one.
try {
if (config.erigonURL === undefined || config.erigonURL == null) {
var connections =
var connections: ChainConnection[] | undefined =
storageConfiguration["connections"] ?? config.connections;
if (connections !== undefined) {
if (!("erigonURL" in storageConfiguration)) {
Expand All @@ -406,39 +413,44 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
}

// Set up URL parameters.
try {
var params = new URLSearchParams(window.location.search);
// Historical - this is the parameter devex used to use.
if (params.has("network")) {
const url = params.get("network");
storageConfiguration["erigonURL"] = url;
var connections =
storageConfiguration["connections"] ?? config.connections;
var found = false;
for (var c of connections) {
if (c.url === url) {
if (params.has("name")) {
let name = params.get("name");
connections = connections.map((c: ChainConnection) => {
if (c.url == url) {
c.menuName = name!;
if (!hostForcesConnection) {
try {
var params = new URLSearchParams(window.location.search);
// Historical - this is the parameter devex used to use.
if (params.has("network")) {
const url = params.get("network");
storageConfiguration["erigonURL"] = url;
var connections: ChainConnection[] | undefined =
storageConfiguration["connections"] ?? config.connections;
var found = false;
if (connections) {
for (var c of connections) {
if (c.url === url) {
if (params.has("name")) {
let name = params.get("name");
connections = connections.map((c: ChainConnection) => {
if (c.url == url) {
c.menuName = name!;
}
return c;
});
}
return c;
});
found = true;
break;
}
}
if (!found) {
var name = params.get("name") ?? url;
if (name && url) {
connections.push({ menuName: name, url });
}
}
found = true;
break;
}
storageConfiguration["connections"] = connections;
}
if (!found) {
var name = params.get("name") ?? url;
connections.push({ menuName: name, url });
}
storageConfiguration["connections"] = connections;
console.log("sc = " + JSON.stringify(storageConfiguration));
} catch (err) {
console.log(`Error parsing parameters - ${err}`);
}
} catch (err) {
console.log(`Error parsing parameters - ${err}`);
}

// Stash
Expand All @@ -454,7 +466,12 @@ export const loadOtterscanConfig = async (): Promise<OtterscanConfig> => {
console.log(`Error storing back to local storage - ${err}`);
}
config = { ...config, ...storageConfiguration };
// We deliberately do not store this, so that we have a fighting chance of
// being able to pop the menu back up again if a connection host was in the
// config file and is no longer there.
config.displayConnectionMenu = !hostForcesConnection;
console.log(JSON.stringify(config));

console.info("Loaded app config");
console.info(config);
return config;
Expand Down
5 changes: 4 additions & 1 deletion src/useZilliqaHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,12 @@ export const smartContractStateFetcher: Fetcher<
export const useSmartContractState = (
zilliqa: Zilliqa | undefined,
address: string,
generation: number,
): { data: ContractState | undefined; isLoading: boolean } => {
const { data, error, isLoading } = useSWRImmutable(
zilliqa !== undefined ? [zilliqa, "useSmartContractState", address] : null,
zilliqa !== undefined
? [zilliqa, "useSmartContractState", address, generation]
: null,
smartContractStateFetcher,
{ keepPreviousData: true },
);
Expand Down

0 comments on commit 55c5a2f

Please sign in to comment.