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