diff --git a/explorer/src/components/AccountsCard.tsx b/explorer/src/components/AccountsCard.tsx
index 044342bbc7..9bf6afa634 100644
--- a/explorer/src/components/AccountsCard.tsx
+++ b/explorer/src/components/AccountsCard.tsx
@@ -29,7 +29,7 @@ function AccountsCard() {
}
dispatch({ type: ActionType.Input, pubkey });
- fetchAccountInfo(dispatch, idCounter + 1, pubkey, url);
+ fetchAccountInfo(dispatch, address, url);
const inputEl = addressInput.current;
if (inputEl) {
diff --git a/explorer/src/components/TransactionsCard.tsx b/explorer/src/components/TransactionsCard.tsx
index 7f51cfd1c9..8ad0b40956 100644
--- a/explorer/src/components/TransactionsCard.tsx
+++ b/explorer/src/components/TransactionsCard.tsx
@@ -35,7 +35,7 @@ function TransactionsCard() {
}
dispatch({ type: ActionType.InputSignature, signature });
- checkTransactionStatus(dispatch, idCounter + 1, signature, url);
+ checkTransactionStatus(dispatch, signature, url);
const inputEl = signatureInput.current;
if (inputEl) {
@@ -141,7 +141,7 @@ const renderTransactionRow = (transaction: Transaction) => {
const confirmationsText = `${transaction.confirmations || "-"}`;
return (
-
{transaction.id}
diff --git a/explorer/src/providers/accounts.tsx b/explorer/src/providers/accounts.tsx
index aaaab67730..adecc3c5a3 100644
--- a/explorer/src/providers/accounts.tsx
+++ b/explorer/src/providers/accounts.tsx
@@ -29,7 +29,7 @@ export interface Account {
details?: Details;
}
-type Accounts = { [id: number]: Account };
+type Accounts = { [address: string]: Account };
interface State {
idCounter: number;
accounts: Accounts;
@@ -42,7 +42,7 @@ export enum ActionType {
interface Update {
type: ActionType.Update;
- id: number;
+ address: string;
status: Status;
details?: Details;
}
@@ -58,10 +58,12 @@ type Dispatch = (action: Action) => void;
function reducer(state: State, action: Action): State {
switch (action.type) {
case ActionType.Input: {
+ const address = action.pubkey.toBase58();
+ if (!!state.accounts[address]) return state;
const idCounter = state.idCounter + 1;
const accounts = {
...state.accounts,
- [idCounter]: {
+ [address]: {
id: idCounter,
status: Status.Checking,
source: Source.Input,
@@ -71,7 +73,7 @@ function reducer(state: State, action: Action): State {
return { ...state, accounts, idCounter };
}
case ActionType.Update: {
- let account = state.accounts[action.id];
+ let account = state.accounts[action.address];
if (account) {
account = {
...account,
@@ -80,7 +82,7 @@ function reducer(state: State, action: Action): State {
};
const accounts = {
...state.accounts,
- [action.id]: account
+ [action.address]: account
};
return { ...state, accounts };
}
@@ -90,9 +92,9 @@ function reducer(state: State, action: Action): State {
return state;
}
-function urlPublicKeys(): Array {
- const keys: Array = [];
- return keys
+function urlAddresses(): Array {
+ const addresses: Array = [];
+ return addresses
.concat(findGetParameter("account")?.split(",") || [])
.concat(findGetParameter("accounts")?.split(",") || [])
.concat(findPathSegment("account")?.split(",") || [])
@@ -100,21 +102,27 @@ function urlPublicKeys(): Array {
.concat(findGetParameter("address")?.split(",") || [])
.concat(findGetParameter("addresses")?.split(",") || [])
.concat(findPathSegment("address")?.split(",") || [])
- .concat(findPathSegment("addresses")?.split(",") || [])
- .map(key => new PublicKey(key));
+ .concat(findPathSegment("addresses")?.split(",") || []);
}
function initState(): State {
let idCounter = 0;
- const pubkeys = urlPublicKeys();
- const accounts = pubkeys.reduce((accounts: Accounts, pubkey) => {
- const id = ++idCounter;
- accounts[id] = {
- id,
- status: Status.Checking,
- source: Source.Url,
- pubkey
- };
+ const addresses = urlAddresses();
+ const accounts = addresses.reduce((accounts: Accounts, address) => {
+ if (!!accounts[address]) return accounts;
+ try {
+ const pubkey = new PublicKey(address);
+ const id = ++idCounter;
+ accounts[address] = {
+ id,
+ status: Status.Checking,
+ source: Source.Url,
+ pubkey
+ };
+ } catch (err) {
+ // TODO display to user
+ console.error(err);
+ }
return accounts;
}, {});
return { idCounter, accounts };
@@ -133,8 +141,8 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
React.useEffect(() => {
if (status !== ClusterStatus.Connected) return;
- Object.values(state.accounts).forEach(account => {
- fetchAccountInfo(dispatch, account.id, account.pubkey, url);
+ Object.keys(state.accounts).forEach(address => {
+ fetchAccountInfo(dispatch, address, url);
});
}, [status, url]); // eslint-disable-line react-hooks/exhaustive-deps
@@ -149,20 +157,21 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
export async function fetchAccountInfo(
dispatch: Dispatch,
- id: number,
- pubkey: PublicKey,
+ address: string,
url: string
) {
dispatch({
type: ActionType.Update,
status: Status.Checking,
- id
+ address
});
let status;
let details;
try {
- const result = await new Connection(url).getAccountInfo(pubkey);
+ const result = await new Connection(url).getAccountInfo(
+ new PublicKey(address)
+ );
details = {
space: result.data.length,
executable: result.executable,
@@ -174,7 +183,7 @@ export async function fetchAccountInfo(
console.error("Failed to fetch account info", error);
status = Status.CheckFailed;
}
- dispatch({ type: ActionType.Update, status, details, id });
+ dispatch({ type: ActionType.Update, status, details, address });
}
export function useAccounts() {
diff --git a/explorer/src/providers/transactions.tsx b/explorer/src/providers/transactions.tsx
index 8c443410a2..5fb1af1ef2 100644
--- a/explorer/src/providers/transactions.tsx
+++ b/explorer/src/providers/transactions.tsx
@@ -27,7 +27,7 @@ export interface Transaction {
signature: TransactionSignature;
}
-type Transactions = { [id: number]: Transaction };
+type Transactions = { [signature: string]: Transaction };
interface State {
idCounter: number;
transactions: Transactions;
@@ -40,7 +40,7 @@ export enum ActionType {
interface UpdateStatus {
type: ActionType.UpdateStatus;
- id: number;
+ signature: TransactionSignature;
status: Status;
slot?: number;
confirmations?: Confirmations;
@@ -57,10 +57,12 @@ type Dispatch = (action: Action) => void;
function reducer(state: State, action: Action): State {
switch (action.type) {
case ActionType.InputSignature: {
+ if (!!state.transactions[action.signature]) return state;
+
const idCounter = state.idCounter + 1;
const transactions = {
...state.transactions,
- [idCounter]: {
+ [action.signature]: {
id: idCounter,
status: Status.Checking,
source: Source.Input,
@@ -70,7 +72,7 @@ function reducer(state: State, action: Action): State {
return { ...state, transactions, idCounter };
}
case ActionType.UpdateStatus: {
- let transaction = state.transactions[action.id];
+ let transaction = state.transactions[action.signature];
if (transaction) {
transaction = {
...transaction,
@@ -80,7 +82,7 @@ function reducer(state: State, action: Action): State {
};
const transactions = {
...state.transactions,
- [action.id]: transaction
+ [action.signature]: transaction
};
return { ...state, transactions };
}
@@ -108,12 +110,13 @@ function initState(): State {
const signatures = urlSignatures();
const transactions = signatures.reduce(
(transactions: Transactions, signature) => {
- const id = ++idCounter;
- transactions[id] = {
- id,
+ if (!!transactions[signature]) return transactions;
+ idCounter++;
+ transactions[signature] = {
+ id: idCounter,
+ signature,
status: Status.Checking,
- source: Source.Url,
- signature
+ source: Source.Url
};
return transactions;
},
@@ -140,8 +143,8 @@ export function TransactionsProvider({ children }: TransactionsProviderProps) {
createDevTransaction(dispatch, url);
}
- Object.values(state.transactions).forEach(tx => {
- checkTransactionStatus(dispatch, tx.id, tx.signature, url);
+ Object.keys(state.transactions).forEach(signature => {
+ checkTransactionStatus(dispatch, signature, url);
});
}, [status, url]); // eslint-disable-line react-hooks/exhaustive-deps
@@ -158,11 +161,12 @@ async function createDevTransaction(dispatch: Dispatch, url: string) {
try {
const connection = new Connection(url);
const signature = await connection.requestAirdrop(
- new PublicKey(0),
+ new PublicKey(1),
1,
"recent"
);
dispatch({ type: ActionType.InputSignature, signature });
+ checkTransactionStatus(dispatch, signature, url);
} catch (error) {
console.error("Failed to create dev transaction", error);
}
@@ -170,14 +174,13 @@ async function createDevTransaction(dispatch: Dispatch, url: string) {
export async function checkTransactionStatus(
dispatch: Dispatch,
- id: number,
signature: TransactionSignature,
url: string
) {
dispatch({
type: ActionType.UpdateStatus,
status: Status.Checking,
- id
+ signature
});
let status;
@@ -206,7 +209,13 @@ export async function checkTransactionStatus(
console.error("Failed to check transaction status", error);
status = Status.CheckFailed;
}
- dispatch({ type: ActionType.UpdateStatus, status, slot, confirmations, id });
+ dispatch({
+ type: ActionType.UpdateStatus,
+ status,
+ slot,
+ confirmations,
+ signature
+ });
}
export function useTransactions() {
|