From 6ea2dbc471c9fd056107a6d0e7b5ab9c21878cff Mon Sep 17 00:00:00 2001 From: lukaw3d Date: Thu, 20 Feb 2025 19:10:47 +0700 Subject: [PATCH 1/4] Fix paratime deposit transaction status in the first few seconds --- .changelog/2123.bugfix.md | 1 + src/vendors/nexus.ts | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changelog/2123.bugfix.md diff --git a/.changelog/2123.bugfix.md b/.changelog/2123.bugfix.md new file mode 100644 index 0000000000..4116494232 --- /dev/null +++ b/.changelog/2123.bugfix.md @@ -0,0 +1 @@ +Fix paratime transaction status in the first few seconds diff --git a/src/vendors/nexus.ts b/src/vendors/nexus.ts index b4ff0cd112..c73ce71ff8 100644 --- a/src/vendors/nexus.ts +++ b/src/vendors/nexus.ts @@ -260,7 +260,12 @@ function parseTransactionsList(list: (NexusTransaction | ExtendedRuntimeTransact from: t.sender_0_eth || t.sender_0, hash: t.hash, level: undefined, - status: t.success ? TransactionStatus.Successful : TransactionStatus.Failed, + status: + t.success === undefined + ? TransactionStatus.Pending + : t.success + ? TransactionStatus.Successful + : TransactionStatus.Failed, timestamp: transactionDate.getTime(), to: (t.body as { to?: string }).to ?? undefined, type: getTransactionType(t.method), From ac87b39cf50dd3e11354c9a67cef18ad2e9225a7 Mon Sep 17 00:00:00 2001 From: lukaw3d Date: Thu, 20 Feb 2025 19:54:33 +0700 Subject: [PATCH 2/4] Refresh deposit transaction status until Nexus has step2 status --- src/app/state/account/selectors.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/state/account/selectors.ts b/src/app/state/account/selectors.ts index d4bd684a64..00dc585c28 100644 --- a/src/app/state/account/selectors.ts +++ b/src/app/state/account/selectors.ts @@ -4,6 +4,7 @@ import { RootState } from 'types' import { initialState } from '.' import { selectSelectedNetwork } from '../network/selectors' import { TRANSACTIONS_LIMIT } from '../../../config' +import { TransactionStatus } from '../transaction/types' const selectSlice = (state: RootState) => state.account || initialState @@ -31,6 +32,11 @@ export const hasAccountUnknownPendingTransactions = createSelector( // Account have nonce and 0 transactions due to last correctly indexed block 16817956 (2023-11-29) return false } + if (transactions.some(tx => tx.status === TransactionStatus.Pending)) { + // After paratime deposit transaction is submitted, Nexus API returns empty status until one block later. + // https://github.com/oasisprotocol/explorer/issues/528 + return true + } const noncesFromTxs = transactions .filter(tx => !tx.runtimeId) .filter(tx => tx.from !== undefined) From a4d9f473d9a3123e5f3d27b1757300920ab659e1 Mon Sep 17 00:00:00 2001 From: lukaw3d Date: Thu, 20 Feb 2025 19:52:03 +0700 Subject: [PATCH 3/4] Refresh transactions multiple times after making a paratime transaction After a consensus deposit API sometimes returned only allowance transaction, and then account nonce + latest transaction matched, so transactions were no longer continuously refreshed. --- src/app/state/account/saga.test.ts | 4 ++++ src/app/state/account/saga.ts | 7 +++++++ src/app/state/transaction/saga.ts | 5 +---- src/app/state/wallet/saga.test.ts | 2 ++ src/app/state/wallet/saga.ts | 2 ++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/app/state/account/saga.test.ts b/src/app/state/account/saga.test.ts index a197a31982..221d7f26d0 100644 --- a/src/app/state/account/saga.test.ts +++ b/src/app/state/account/saga.test.ts @@ -14,6 +14,7 @@ import { DeepPartialRootState } from 'types/RootState' import * as matchers from 'redux-saga-test-plan/matchers' import { getExplorerAPIs } from '../network/saga' import { getAccountBalanceWithFallback } from '../../lib/getAccountBalanceWithFallback' +import delayP from '@redux-saga/delay-p' const address = 'oasis1qz0k5q8vjqvu4s4nwxyj406ylnflkc4vrcjghuwk' const state: DeepPartialRootState = { @@ -46,6 +47,9 @@ describe('Account Sagas', () => { it('Should refresh account on paraTime transaction', () => { return expectSaga(accountSaga) .withState(state) + .provide([ + [matchers.call.fn(delayP), null], // https://github.com/jfairbank/redux-saga-test-plan/issues/257 + ]) .dispatch(transactionActions.paraTimeTransactionSent('dummyAddress')) .put.actionType(accountActions.fetchAccount.type) .put.actionType(stakingActions.fetchAccount.type) diff --git a/src/app/state/account/saga.ts b/src/app/state/account/saga.ts index b43c6415e0..3e897cf2d6 100644 --- a/src/app/state/account/saga.ts +++ b/src/app/state/account/saga.ts @@ -90,6 +90,13 @@ export function* refreshAccountOnParaTimeTransaction() { while (true) { const { payload } = yield* take(transactionActions.paraTimeTransactionSent) + // Increase the chance to get updated transactions from API. + // Note: We can't rely on nonce to detect pending paratime transactions + yield* delay(3000) + yield* call(refreshAccount, payload) + yield* delay(6000) + yield* call(refreshAccount, payload) + yield* delay(6000) yield* call(refreshAccount, payload) } } diff --git a/src/app/state/transaction/saga.ts b/src/app/state/transaction/saga.ts index b64ccdc5a0..74ad9d2e27 100644 --- a/src/app/state/transaction/saga.ts +++ b/src/app/state/transaction/saga.ts @@ -5,7 +5,7 @@ import { hex2uint, isValidAddress, parseRoseStringToBaseUnitString, uint2bigintS import { LedgerSigner } from 'app/lib/ledger' import { OasisTransaction, signerFromEthPrivateKey, signerFromPrivateKey, TW } from 'app/lib/transaction' import { getEvmBech32Address, privateToEthAddress } from 'app/lib/eth-helpers' -import { call, delay, put, race, select, take, takeEvery } from 'typed-redux-saga' +import { call, put, race, select, take, takeEvery } from 'typed-redux-saga' import { ErrorPayload, ExhaustedTypeError, WalletError, WalletErrors } from 'types/errors' import { transactionActions } from '.' import { sign } from '../importaccounts/saga' @@ -275,8 +275,6 @@ export function* setAllowance( } } -const transactionSentDelay = 1000 // to increase a chance to get updated account data from BE - export function* submitParaTimeTransaction(runtime: Runtime, transaction: ParaTimeTransaction) { const fromAddress = transaction.ethPrivateKey ? yield* call(getEvmBech32Address, privateToEthAddress(transaction.ethPrivateKey)) @@ -302,7 +300,6 @@ export function* submitParaTimeTransaction(runtime: Runtime, transaction: ParaTi yield* call(OasisTransaction.signParaTime, chainContext, paraTimeTransactionSigner as Signer, rtw) yield* call(OasisTransaction.submit, nic, rtw) - yield* delay(transactionSentDelay) yield* put(transactionActions.paraTimeTransactionSent(transaction.recipient)) } diff --git a/src/app/state/wallet/saga.test.ts b/src/app/state/wallet/saga.test.ts index 4dd782c698..c343529837 100644 --- a/src/app/state/wallet/saga.test.ts +++ b/src/app/state/wallet/saga.test.ts @@ -9,6 +9,7 @@ import { addWallet, rootWalletSaga } from './saga' import { AddWalletPayload, WalletType } from './types' import { importAccountsActions } from '../importaccounts' import { getAccountBalanceWithFallback } from '../../lib/getAccountBalanceWithFallback' +import delayP from '@redux-saga/delay-p' describe('Wallet Sagas', () => { const validPrivateKeyHex = @@ -18,6 +19,7 @@ describe('Wallet Sagas', () => { const providers: (EffectProviders | StaticProvider)[] = [ [matchers.call.fn(getAccountBalanceWithFallback), {}], + [matchers.call.fn(delayP), null], // https://github.com/jfairbank/redux-saga-test-plan/issues/257 ] const state: DeepPartialRootState = { importAccounts: { diff --git a/src/app/state/wallet/saga.ts b/src/app/state/wallet/saga.ts index d43c2397f6..04b33131df 100644 --- a/src/app/state/wallet/saga.ts +++ b/src/app/state/wallet/saga.ts @@ -152,6 +152,8 @@ function* refreshAccountOnParaTimeTransaction() { while (true) { const { payload } = yield* take(transactionActions.paraTimeTransactionSent) + // Increase the chance to get updated balance from API. + yield* delay(3000) yield* call(refreshAccount, payload) } } From ea0d13d477ee4d614159bfcbd7a96b210aff12ea Mon Sep 17 00:00:00 2001 From: lukaw3d Date: Thu, 20 Feb 2025 20:11:22 +0700 Subject: [PATCH 4/4] Display eth address in paratime deposits --- src/vendors/nexus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vendors/nexus.ts b/src/vendors/nexus.ts index c73ce71ff8..e6a196264e 100644 --- a/src/vendors/nexus.ts +++ b/src/vendors/nexus.ts @@ -267,7 +267,7 @@ function parseTransactionsList(list: (NexusTransaction | ExtendedRuntimeTransact ? TransactionStatus.Successful : TransactionStatus.Failed, timestamp: transactionDate.getTime(), - to: (t.body as { to?: string }).to ?? undefined, + to: t.to_eth ?? t.to ?? (t.body as { to?: string }).to ?? undefined, type: getTransactionType(t.method), runtimeName: t.runtimeName, runtimeId: t.runtimeId,