diff --git a/lib/bloc/withdraw_form/withdraw_form_state.dart b/lib/bloc/withdraw_form/withdraw_form_state.dart index 59b1191d75..b40e393a2f 100644 --- a/lib/bloc/withdraw_form/withdraw_form_state.dart +++ b/lib/bloc/withdraw_form/withdraw_form_state.dart @@ -247,6 +247,11 @@ class WithdrawFormState extends Equatable { } WithdrawParameters toWithdrawParameters() { + final derivationPath = selectedSourceAddress?.derivationPath; + final supportsHdSourceSelection = + asset.protocol.supportsMultipleAddresses && + asset.protocol is! SiaProtocol; + return WithdrawParameters( asset: asset.id.id, toAddress: recipientAddress, @@ -255,10 +260,8 @@ class WithdrawFormState extends Equatable { : Decimal.parse(normalizeDecimalString(amount)), fee: isCustomFee ? customFee : null, feePriority: isCustomFee ? null : selectedFeePriority, - from: selectedSourceAddress?.derivationPath != null - ? WithdrawalSource.hdDerivationPath( - selectedSourceAddress!.derivationPath!, - ) + from: supportsHdSourceSelection && derivationPath != null + ? WithdrawalSource.hdDerivationPath(derivationPath) : null, memo: memo, ibcTransfer: isIbcTransfer ? true : null, diff --git a/sdk b/sdk index b8555f1dd4..6dddeee0b0 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit b8555f1dd4dd19e7d04b2cdf7248ddfdbf36a1bc +Subproject commit 6dddeee0b004024ba8746d451f2baad332df778d diff --git a/test_units/tests/wallet/coin_details/withdraw_form_bloc_test.dart b/test_units/tests/wallet/coin_details/withdraw_form_bloc_test.dart index 061218ee8a..1a80f683c2 100644 --- a/test_units/tests/wallet/coin_details/withdraw_form_bloc_test.dart +++ b/test_units/tests/wallet/coin_details/withdraw_form_bloc_test.dart @@ -8,6 +8,7 @@ import 'package:komodo_defi_sdk/src/withdrawals/withdrawal_manager.dart'; import 'package:komodo_defi_types/komodo_defi_types.dart'; import 'package:web_dex/bloc/withdraw_form/withdraw_form_bloc.dart'; import 'package:web_dex/mm2/mm2_api/mm2_api.dart'; +import 'package:web_dex/model/wallet.dart'; Map _utxoConfig({ String coin = 'KMD', @@ -44,6 +45,21 @@ Map _trxConfig() => { 'nodes': >[], }; +Map _siaConfig() => { + 'coin': 'SC', + 'type': 'SIA', + 'name': 'Siacoin', + 'fname': 'Siacoin', + 'wallet_only': false, + 'mm2': 1, + 'chain_id': 2024, + 'decimals': 24, + 'required_confirmations': 1, + 'nodes': const [ + {'url': 'https://api.siascan.com/wallet/api'}, + ], +}; + BalanceInfo _balance(String amount) { final value = Decimal.parse(amount); return BalanceInfo(total: value, spendable: value, unspendable: Decimal.zero); @@ -1047,6 +1063,88 @@ void testWithdrawFormBloc() { contains('notEnoughBalanceForGasError'), ); }); + + test( + 'SIA preview omits source derivation path in request params', + () async { + final asset = _assetFromConfig(_siaConfig()); + final withdrawals = _FakeWithdrawalManager( + previewWithdrawalHandler: (_) async => _utxoPreview( + assetId: asset.id.id, + txHash: 'preview-sia', + toAddress: 'recipient-1', + timestamp: 1, + ), + ); + + final bloc = WithdrawFormBloc( + asset: asset, + sdk: _FakeSdk( + addresses: _FakeAddressOperations(), + withdrawals: withdrawals, + pubkeys: _FakePubkeyManager({ + asset.id: _assetPubkeys(asset, balance: '5'), + }), + balances: _FakeBalanceManager({asset.id: _balance('5')}), + ), + mm2Api: _FakeMm2Api(), + ); + addTearDown(bloc.close); + + await _primeFillState(bloc, recipient: 'recipient-1', amount: '1'); + bloc.add(const WithdrawFormPreviewSubmitted()); + await bloc.stream.firstWhere( + (state) => state.step == WithdrawFormStep.confirm, + ); + + expect(withdrawals.previewRequests.single.from, isNull); + }, + ); + + test('Trezor blocks SIA preview and submit', () async { + final asset = _assetFromConfig(_siaConfig()); + final withdrawals = _FakeWithdrawalManager( + previewWithdrawalHandler: (_) async => _utxoPreview( + assetId: asset.id.id, + txHash: 'preview-sia', + toAddress: 'recipient-1', + timestamp: 1, + ), + ); + + final bloc = WithdrawFormBloc( + asset: asset, + sdk: _FakeSdk( + addresses: _FakeAddressOperations(), + withdrawals: withdrawals, + pubkeys: _FakePubkeyManager({ + asset.id: _assetPubkeys(asset, balance: '5'), + }), + balances: _FakeBalanceManager({asset.id: _balance('5')}), + ), + mm2Api: _FakeMm2Api(), + walletType: WalletType.trezor, + ); + addTearDown(bloc.close); + + await _primeFillState(bloc, recipient: 'recipient-1', amount: '1'); + + bloc.add(const WithdrawFormPreviewSubmitted()); + final previewBlocked = await bloc.stream.firstWhere( + (state) => state.previewError != null, + ); + + expect(previewBlocked.previewError?.message, contains('SIA is not')); + expect(withdrawals.previewCallCount, 0); + + bloc.add(const WithdrawFormSubmitted()); + final submitBlocked = await bloc.stream.firstWhere( + (state) => state.transactionError != null, + ); + + expect(submitBlocked.transactionError?.message, contains('SIA is not')); + expect(withdrawals.executeCallCount, 0); + }); }); }