Skip to content

Commit 10a9200

Browse files
dlipicaralaibe
authored andcommitted
fix(wallet)_: refresh balances on sent transaction state change
1 parent e3d18b1 commit 10a9200

File tree

4 files changed

+107
-4
lines changed

4 files changed

+107
-4
lines changed

services/wallet/reader.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package wallet
44

55
import (
66
"context"
7+
"encoding/json"
78
"math"
89
"math/big"
910
"sync"
@@ -23,6 +24,7 @@ import (
2324
tokenTypes "github.com/status-im/status-go/services/wallet/token/types"
2425
"github.com/status-im/status-go/services/wallet/transfer"
2526
"github.com/status-im/status-go/services/wallet/walletevent"
27+
"github.com/status-im/status-go/transactions"
2628
)
2729

2830
// WalletTickReload emitted every 15mn to reload the wallet balance and history
@@ -185,10 +187,25 @@ func (r *Reader) startWalletEventsWatcher() {
185187
return
186188
}
187189

188-
// Respond to ETH/Token transfers
190+
// Respond to ETH/Token transfers or any sent transaction
189191
walletEventCb := func(event walletevent.Event) {
190-
if event.Type != transfer.EventInternalETHTransferDetected &&
191-
event.Type != transfer.EventInternalERC20TransferDetected {
192+
delayed := true
193+
switch event.Type {
194+
case transfer.EventInternalETHTransferDetected, transfer.EventInternalERC20TransferDetected:
195+
// Delayed refresh
196+
case transactions.EventPendingTransactionUpdate:
197+
var p transactions.PendingTxUpdatePayload
198+
err := json.Unmarshal([]byte(event.Message), &p)
199+
if err != nil {
200+
return
201+
}
202+
if p.Deleted {
203+
// Immediate refresh
204+
delayed = false
205+
}
206+
// Delayed refresh
207+
default:
208+
// Unrelated event, do not trigger a reload
192209
return
193210
}
194211

@@ -200,8 +217,12 @@ func (r *Reader) startWalletEventsWatcher() {
200217
}
201218

202219
if !ok || event.At > timecheck {
203-
r.triggerDelayedWalletReload()
204220
r.invalidateBalanceCache()
221+
if delayed {
222+
r.triggerDelayedWalletReload()
223+
} else {
224+
r.triggerWalletReload()
225+
}
205226
break
206227
}
207228
}

tests-functional/clients/signals.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class WalletEventType(Enum):
3232
WALLET_ACTIVITY_SESSION_UPDATED = "wallet-activity-session-updated"
3333
TRANSACTIONS_PENDING_TRANSACTION_UPDATE = "pending-transaction-update"
3434
TRANSACTIONS_PENDING_TRANSACTION_STATUS_CHANGED = "pending-transaction-status-changed"
35+
WALLET_TICK_RELOAD = "wallet-tick-reload"
3536

3637

3738
class LocalPairingEventType(Enum):

tests-functional/pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ markers =
2020
create_account
2121
reliability
2222
activity
23+
assets
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import uuid as uuid_lib
2+
import json
3+
import pytest
4+
import resources.constants as constants
5+
6+
from steps.status_backend import StatusBackendSteps
7+
from clients.signals import SignalType, WalletEventType
8+
from utils import wallet_utils
9+
10+
11+
@pytest.mark.rpc
12+
@pytest.mark.assets
13+
@pytest.mark.wallet
14+
class TestWalletAssets(StatusBackendSteps):
15+
await_signals = [
16+
SignalType.NODE_LOGIN.value,
17+
SignalType.WALLET.value,
18+
SignalType.WALLET_SUGGESTED_ROUTES.value,
19+
SignalType.WALLET_ROUTER_SIGN_TRANSACTIONS.value,
20+
SignalType.WALLET_ROUTER_SENDING_TRANSACTIONS_STARTED.value,
21+
SignalType.WALLET_ROUTER_TRANSACTIONS_SENT.value,
22+
]
23+
24+
@classmethod
25+
def setup_class(cls, skip_login=False):
26+
super().setup_class(skip_login)
27+
cls.wallet_service.start_wallet()
28+
29+
@pytest.mark.skip("cryptocompare limit reached")
30+
def test_balance_refresh_ticker_after_sending_transaction(self):
31+
uuid = str(uuid_lib.uuid4())
32+
amount_in = "0xde0b6b3a7640000"
33+
34+
input_params = {
35+
"uuid": uuid,
36+
"sendType": 0,
37+
"addrFrom": constants.user_1.address,
38+
"addrTo": constants.user_2.address,
39+
"amountIn": amount_in,
40+
"amountOut": "0x0",
41+
"tokenID": "ETH",
42+
"tokenIDIsOwnerToken": False,
43+
"toTokenID": "",
44+
"fromChainID": 31337,
45+
"toChainID": 31337,
46+
"gasFeeMode": 1,
47+
# params for building tx from route
48+
"slippagePercentage": 0,
49+
}
50+
51+
# Prepare to send tx
52+
routes = wallet_utils.get_suggested_routes(self.rpc_client, **input_params)
53+
assert "Route" in routes, f"No route found: {routes}"
54+
build_tx = wallet_utils.build_transactions_from_route(self.rpc_client, input_params.get("uuid"))
55+
tx_signatures = wallet_utils.sign_messages(self.rpc_client, build_tx["signingDetails"]["hashes"], input_params.get("addrFrom"))
56+
57+
# Send tx, listen to reload tick signal
58+
method = "wallet_sendRouterTransactionsWithSignatures"
59+
params = [{"uuid": uuid, "Signatures": tx_signatures}]
60+
61+
def accept_fn(signal):
62+
match signal["event"]["type"]:
63+
case WalletEventType.TRANSACTIONS_PENDING_TRANSACTION_STATUS_CHANGED.value:
64+
tx_status = json.loads(signal["event"]["message"].replace("'", '"'))
65+
return tx_status["status"] == "Success"
66+
case WalletEventType.WALLET_TICK_RELOAD.value:
67+
return True
68+
case _:
69+
return False
70+
71+
self.rpc_client.prepare_wait_for_signal(
72+
SignalType.WALLET.value,
73+
2,
74+
accept_fn,
75+
)
76+
_ = self.rpc_client.rpc_valid_request(method, params)
77+
signals = self.rpc_client.wait_for_signal(SignalType.WALLET.value)
78+
79+
# Verify
80+
assert len(signals) == 2

0 commit comments

Comments
 (0)