diff --git a/package.json b/package.json index e038a2b..12baef6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bnc-notify", - "version": "1.7.0", + "version": "1.7.0-0.1.0", "description": "Show web3 users realtime transaction notifications", "keywords": [ "ethereum", diff --git a/src/defaults.ts b/src/defaults.ts index 56ee840..38a4d44 100644 --- a/src/defaults.ts +++ b/src/defaults.ts @@ -13,6 +13,7 @@ export function eventToType(eventCode: string | undefined): NotificationType { case 'txConfirmReminder': case 'txStallPending': case 'txStallConfirmed': + case 'txStuck': return 'hint' case 'txError': case 'txSendFail': diff --git a/src/i18n.ts b/src/i18n.ts index 4f6781f..1b8c232 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -14,6 +14,7 @@ export const defaultNotifyMessages: any = { txSent: 'Your transaction has been sent to the network', txStallPending: 'Your transaction has stalled and has not entered the transaction pool', + txStuck: 'Your transaction is stuck due to a nonce gap', txPool: 'Your transaction has started', txStallConfirmed: "Your transaction has stalled and hasn't been confirmed", @@ -27,9 +28,9 @@ export const defaultNotifyMessages: any = { txPool: 'Your account is {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}', txSpeedUp: - 'Your account is {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}', + 'Transaction for {formattedValue} {asset} {preposition} {counterpartyShortened} has been sped up', txCancel: - 'Your account is {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}', + 'Transaction for {formattedValue} {asset} {preposition} {counterpartyShortened} has been canceled', txConfirmed: 'Your account successfully {verb} {formattedValue} {asset} {preposition} {counterpartyShortened}', txFailed: @@ -55,6 +56,7 @@ export const defaultNotifyMessages: any = { txSent: 'Su transacción ha sido enviada a la red.', txStallPending: 'Su transacción se ha estancado y no ha ingresado al grupo de transacciones', + txStuck: 'Su transacción está atascada debido a una brecha de nonce', txPool: 'Su transacción ha comenzado', txStallConfirmed: 'Su transacción se ha estancado y no ha sido confirmada.', diff --git a/src/interfaces.ts b/src/interfaces.ts index ad6f8eb..7f84c76 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -59,6 +59,7 @@ export interface TransactionData { monitorId?: string monitorVersion?: string nonce?: number + replaceHash?: string r?: string s?: string status?: string diff --git a/src/stores.ts b/src/stores.ts index 6bb2d1b..b790e85 100644 --- a/src/stores.ts +++ b/src/stores.ts @@ -32,9 +32,10 @@ export const notifications = createNotificationStore([]) function createTransactionStore(initialState: TransactionData[]) { const { subscribe, update } = writable(initialState) - function updateQueue(transaction: TransactionData) { - const predicate = (tx: TransactionData) => tx.id === transaction.id - + function updateQueue( + transaction: TransactionData, + predicate: (tx: TransactionData) => boolean + ) { update((store: TransactionData[]) => { return replaceOrAdd(store, predicate, transaction) }) @@ -88,10 +89,19 @@ function createNotificationStore( ) } + function updateId(oldId: string, newId: string) { + update((store: (NotificationObject & CustomNotificationObject)[]) => + store.map((n: NotificationObject & CustomNotificationObject) => + n.id === oldId ? { ...n, id: newId } : n + ) + ) + } + return { subscribe, add, remove, - update + update, + updateId } } diff --git a/src/transactions.ts b/src/transactions.ts index 02576c0..8aad6a7 100644 --- a/src/transactions.ts +++ b/src/transactions.ts @@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js' import uuid from 'uuid/v4' import { get } from 'svelte/store' -import { transactions, app } from './stores' +import { transactions, app, notifications } from './stores' import { createNotification } from './notifications' import { argsEqual, extractMessageFromError, localNetwork } from './utilities' import { validateNotificationObject } from './validation' @@ -73,13 +73,26 @@ export function handleTransactionEvent(event: { emitterResult: boolean | void | CustomNotificationObject }) { const { transaction, emitterResult } = event - transactions.updateQueue(transaction) + if (!transaction.id) { + transaction.id = transaction.hash || transaction.txid + } + + const predicate = (tx: TransactionData) => + transaction.replaceHash + ? tx.id === transaction.replaceHash + : tx.id === transaction.id + + transactions.updateQueue(transaction, predicate) + + // update notification id if replaced + if (transaction.replaceHash) { + notifications.updateId(transaction.replaceHash, transaction.hash) + } // create notification if dev hasn't opted out and not connected to a local network if (emitterResult !== false && !localNetwork(get(app).networkId)) { - const transactionObj = transactionQueue.find( - (tx: TransactionData) => tx.id === transaction.id - ) + const transactionObj = transactionQueue.find(predicate) + if (transactionObj) { createNotification(transactionObj, emitterResult) } diff --git a/src/utilities.ts b/src/utilities.ts index fdbccb2..f1b7450 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -19,7 +19,16 @@ export function replaceOrAdd( const index = clone.findIndex(predicate) if (index !== -1) { - const { startTime, contractCall } = clone[index] + const { startTime, contractCall, status } = clone[index] + + // if current transaction is a speedup or cancel and new status is pending, ignore update + if ( + data.status === 'pending' && + (status === 'speedup' || status === 'cancel') + ) { + return clone + } + const { startTime: serverStartTime } = data const contractCallMerge = contractCall ? { ...contractCall } : {}