Use signature and address for state keys
This commit is contained in:
		
				
					committed by
					
						
						Michael Vines
					
				
			
			
				
	
			
			
			
						parent
						
							69502cc68e
						
					
				
				
					commit
					ef7be97540
				
			@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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 (
 | 
			
		||||
    <tr key={transaction.id}>
 | 
			
		||||
    <tr key={transaction.signature}>
 | 
			
		||||
      <td>
 | 
			
		||||
        <span className="badge badge-soft-dark badge-pill">
 | 
			
		||||
          {transaction.id}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<PublicKey> {
 | 
			
		||||
  const keys: Array<string> = [];
 | 
			
		||||
  return keys
 | 
			
		||||
function urlAddresses(): Array<string> {
 | 
			
		||||
  const addresses: Array<string> = [];
 | 
			
		||||
  return addresses
 | 
			
		||||
    .concat(findGetParameter("account")?.split(",") || [])
 | 
			
		||||
    .concat(findGetParameter("accounts")?.split(",") || [])
 | 
			
		||||
    .concat(findPathSegment("account")?.split(",") || [])
 | 
			
		||||
@@ -100,21 +102,27 @@ function urlPublicKeys(): Array<PublicKey> {
 | 
			
		||||
    .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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user