Skip to content

Commit

Permalink
Show rejected/pending/conrimed txn badges (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
its-saeed authored Jun 11, 2024
1 parent 1497c74 commit 05333d2
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 52 deletions.
79 changes: 72 additions & 7 deletions src/components/header/MenuBar/Transactions.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
<template>
<q-btn-dropdown dense icon="dns" unelevated no-caps label="Transactions">
<q-btn-dropdown
dense
icon="dns"
unelevated
no-caps
@hide="
rejectedCount = 0;
confirmedCount = 0;
"
>
<template v-slot:label>
Transactions
<q-badge
v-if="pendingCount > 0"
color="orange-5"
class="q-ml-xs text-bold"
rounded
>{{ pendingCount }}
<q-tooltip>Pending</q-tooltip>
</q-badge>
<q-badge
v-if="confirmedCount > 0"
color="green-5"
class="q-ml-xs text-bold"
rounded
>{{ confirmedCount }}
<q-tooltip>Confirmed</q-tooltip>
</q-badge>
<q-badge
v-if="rejectedCount > 0"
color="red-5"
class="q-ml-xs text-bold"
rounded
>{{ rejectedCount }}
<q-tooltip>Rejected</q-tooltip>
</q-badge>
</template>

<q-list dense>
<div v-for="transaction in store.transactions" :key="transaction.id">
<q-item>
<q-item :class="`bg-${listItemBgColor(transaction.status)}`">
<q-item-section>
<q-item-label>
<truncated-text
Expand All @@ -15,7 +52,7 @@
</q-item-label>
<q-item-label caption>
<q-badge
:color="txStatusColor(transaction.statusMessage)"
:color="txStatusColor(transaction.status)"
class="text-bold"
>
{{ transaction.statusMessage }} </q-badge
Expand Down Expand Up @@ -55,29 +92,57 @@ import CopyToClipboardBtn from 'src/components/CopyToClipboardBtn.vue';
import TruncatedText from 'components/TruncatedText.vue';
import { useBlockchainStore } from 'src/stores/blockchain';
import { onMounted, onUnmounted } from 'vue';
import { TransactionStatus } from 'src/utils';
import { ref } from 'vue';
import { eventBus } from 'src/event-bus';
const store = useTransactionsStore();
const blockchainStore = useBlockchainStore();
let intervalId: NodeJS.Timeout;
const pendingCount = ref(0);
const confirmedCount = ref(0);
const rejectedCount = ref(0);
onMounted(() => {
intervalId = setInterval(async () => {
await store.refreshPendingTxns();
}, 5000);
eventBus.on(
'pending-txn-status-changed',
(pending: number, confirmed: number, rejected: number) => {
pendingCount.value = pending;
confirmedCount.value = confirmed;
rejectedCount.value = rejected;
}
);
});
onUnmounted(() => clearInterval(intervalId));
const txStatusColor = (statusMessage: string) => {
switch (statusMessage) {
case 'Initialised':
const txStatusColor = (status: TransactionStatus) => {
switch (status) {
case 'Initialized':
return 'blue';
case 'Confirmed':
return 'green';
case 'Pending':
return 'yellow';
return 'orange';
case 'Rejected':
return 'red';
}
};
const listItemBgColor = (status: TransactionStatus) => {
switch (status) {
case 'Initialized':
return 'blue-2';
case 'Confirmed':
return 'white';
case 'Pending':
return 'yellow-2';
case 'Rejected':
return 'red-2';
}
};
</script>
5 changes: 5 additions & 0 deletions src/event-bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ import { ScillaFile } from './utils';

export const eventBus = new EventBus<{
'scilla-file-selected': (file: ScillaFile) => void;
'pending-txn-status-changed': (
pending: number,
confirmed: number,
rejected: number
) => void;
}>();
24 changes: 22 additions & 2 deletions src/stores/blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import { useNetworksStore } from './networks';
import { BN, bytes, units } from '@zilliqa-js/util';
import { TxParams, Zilliqa, toChecksumAddress } from '@zilliqa-js/zilliqa';
import { useTransactionsStore } from './transactions';
import Long from 'long';
import { zilpayHelper } from 'src/utils';
import {
TransactionStatus,
interpretTransactionStatus,
zilpayHelper,
} from 'src/utils';
import { ledgerHelper } from 'src/utils';
import { Notify } from 'quasar';
import Long from 'long';

export const useBlockchainStore = defineStore('blockchain', {
state: () => ({
Expand Down Expand Up @@ -156,6 +160,21 @@ export const useBlockchainStore = defineStore('blockchain', {
return response.result;
};
},
getTransactionStatus: (state) => {
return async (
txHash: string
): Promise<{ status: TransactionStatus; statusMessage: string }> => {
if (state.zilliqa === null) {
throw new Error('Please select a network');
}

const response = await state.zilliqa.blockchain.getTransactionStatus(
txHash
);

return interpretTransactionStatus(response);
};
},
minimumGasPrice: async (state) => {
if (state.zilliqa === null) {
throw new Error('Please select a network');
Expand Down Expand Up @@ -364,6 +383,7 @@ export const useBlockchainStore = defineStore('blockchain', {
const store = useTransactionsStore();
store.add({
id: txnId,
status: 'Initialized',
statusMessage: 'Initialized',
network: this.selectedNetworkName,
amount: txParams.amount,
Expand Down
21 changes: 9 additions & 12 deletions src/stores/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { defineStore } from 'pinia';
import { Contract, PendingContract, TransitionCalls } from '../utils/models';
import { Init, TxParams, Value, toChecksumAddress } from '@zilliqa-js/zilliqa';
import { useBlockchainStore } from './blockchain';
import { useTransactionsStore } from './transactions';
import { Notify } from 'quasar';

export const useContractsStore = defineStore('contracts', {
Expand Down Expand Up @@ -65,21 +64,19 @@ export const useContractsStore = defineStore('contracts', {
return;
}

const transactions = useTransactionsStore();
const blockchain = useBlockchainStore();
const responses = await Promise.all(
this.pending.map((c) => {
return transactions.refreshTransactionStatus(c.txHash);
this.pending.map((c: PendingContract) => {
return blockchain.getTransactionStatus(c.txHash);
})
);

const deployed = this.pending.filter((c, i) => {
const statusMessage = responses[i].statusMessage;
return statusMessage === 'Confirmed';
const deployed = this.pending.filter((_: PendingContract, i: number) => {
return responses[i].status === 'Confirmed';
});

const contractAddresses = await Promise.all(
deployed.map((c) => {
deployed.map((c: PendingContract) => {
return blockchain.getContractAddressFromTransactionID(c.txHash);
})
);
Expand All @@ -96,16 +93,16 @@ export const useContractsStore = defineStore('contracts', {
});
});

this.pending = this.pending.filter((c, i) => {
this.pending = this.pending.filter((c: PendingContract, i: number) => {
const statusMessage = responses[i].statusMessage;
const id = responses[i].ID;
const id = c.txHash;
if (statusMessage === 'Confirmed') {
return false; // To filter out
} else if (statusMessage.startsWith('Rejected')) {
// TODO: Show the exact message.
Notify.create({
type: 'warning',
message: `Contract deployment failed, id: ${id}, reason: ${statusMessage}`,
message: `Contract deployment failed, txHash: ${id}, reason: ${statusMessage}`,
});
return false; // To filter out
}
Expand Down Expand Up @@ -137,7 +134,7 @@ export const useContractsStore = defineStore('contracts', {
);

if (id === undefined) {
throw new Error('Invalid transaction hash: ', id);
throw new Error(`Invalid transaction hash: ${id}`);
}

this.pending.push({
Expand Down
9 changes: 0 additions & 9 deletions src/stores/networks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { defineStore } from 'pinia';
import { Zilliqa } from '@zilliqa-js/zilliqa';
import { Network } from '../utils/models';

export const useNetworksStore = defineStore('networks', {
Expand Down Expand Up @@ -43,14 +42,6 @@ export const useNetworksStore = defineStore('networks', {
] as Network[],
}),
getters: {
getZilliqa: (state) => (name: string) => {
const network = state.networks.find((network) => network.name === name);
if (network === undefined) {
throw new Error(`No network with name of ${name}`);
}

return new Zilliqa(network.url);
},
getByName: (state) => (name: string) => {
return state.networks.find((network) => network.name === name);
},
Expand Down
93 changes: 73 additions & 20 deletions src/stores/transactions.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
import { defineStore } from 'pinia';
import { WaitingTransaction } from '../utils/models';
import { useNetworksStore } from './networks';
import { Transaction } from '../utils/models';
import { useBlockchainStore } from './blockchain';
import { eventBus } from 'src/event-bus';

export const useTransactionsStore = defineStore('transactions', {
state: () => ({
transactions: [] as WaitingTransaction[],
transactions: [] as Transaction[],
pending: 0 as number,
rejected: 0 as number,
confirmed: 0 as number,
}),
getters: {
pendingTransactions: (state) => {
try {
return state.transactions.filter(
(tx: Transaction) =>
tx.status &&
(tx.status === 'Pending' || tx.status === 'Initialized')
);
} catch (error) {
console.log('hererererere');
console.log(state.transactions);
return [];
}
},
getTransactionById: (state) => (txHash: string) => {
return state.transactions.find((item) => item.id === txHash);
},
pending: (state) => {
return state.transactions.filter((tx) =>
tx.statusMessage.startsWith('Pending')
);
},
},
actions: {
add(tx: WaitingTransaction) {
this.transactions.push(tx);
add(tx: Transaction) {
this.transactions = [tx, ...this.transactions];
},
delete(txHash: string) {
this.transactions = this.transactions.filter((tx) => tx.id !== txHash);
},
async refreshPendingTxns() {
await Promise.all(
this.pending.map((tx) => this.refreshTransactionStatus(tx.id))
this.transactions = this.transactions.filter(
(tx: Transaction) => tx.id !== txHash
);
},
async refreshTransactionStatus(txHash: string) {
Expand All @@ -34,12 +43,56 @@ export const useTransactionsStore = defineStore('transactions', {
throw new Error(`No transaction with id: ${txHash}`);
}

const networksStore = useNetworksStore();
const zilliqa = networksStore.getZilliqa(txn.network);
const blockchainStore = useBlockchainStore();
const { status, statusMessage } =
await blockchainStore.getTransactionStatus(txHash);
txn.status = status;
txn.statusMessage = statusMessage;
},
async refreshPendingTxns() {
const blockchainStore = useBlockchainStore();
let confirmedCount = 0;
let rejectedCount = 0;
let pendingCount = 0;
if (this.pendingTransactions.length === 0) {
return;
}

const response = await zilliqa.blockchain.getTransactionStatus(txHash);
txn.statusMessage = response.statusMessage;
return response;
await Promise.all(
this.pendingTransactions.map(async (tx: Transaction) => {
const { status, statusMessage } =
await blockchainStore.getTransactionStatus(tx.id);
tx.status = status;
tx.statusMessage = statusMessage;
switch (status) {
case 'Confirmed':
confirmedCount++;
break;
case 'Rejected':
rejectedCount++;
break;
case 'Pending':
pendingCount++;
break;
}
})
);

if (
confirmedCount !== this.confirmed ||
rejectedCount !== this.rejected ||
pendingCount !== this.pending
) {
this.confirmed = confirmedCount;
this.rejected = rejectedCount;
this.pending = pendingCount;
eventBus.emit(
'pending-txn-status-changed',
this.pending,
this.confirmed,
this.rejected
);
}
},
},
persist: true,
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './string';
export * from './file';
export * from './zilpay';
export * from './ledger';
export * from './txns';
Loading

0 comments on commit 05333d2

Please sign in to comment.