Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"transactionComplete": "Transaction complete!",
"transactionDenied": "Denied",
"coinDisableSpan1": "You can't disable {} while it has a swap in progress",
"confirmSending": "Confirm sending",
"confirmSending": "Confirm withdrawl",
"confirmSend": "Confirm send",
"confirm": "Confirm",
"confirmed": "Confirmed",
Expand Down
61 changes: 40 additions & 21 deletions lib/bloc/withdraw_form/withdraw_form_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:komodo_defi_types/komodo_defi_types.dart';
import 'package:web_dex/bloc/withdraw_form/withdraw_form_bloc.dart';
import 'package:web_dex/generated/codegen_loader.g.dart';
import 'package:web_dex/mm2/mm2_api/rpc/base.dart';
import 'package:web_dex/mm2/mm2_api/mm2_api.dart';
import 'package:web_dex/mm2/mm2_api/rpc/send_raw_transaction/send_raw_transaction_request.dart';
import 'package:web_dex/model/text_error.dart';
import 'package:web_dex/model/wallet.dart';
import 'package:web_dex/services/fd_monitor_service.dart';
Expand All @@ -21,12 +23,15 @@ import 'package:decimal/decimal.dart';
class WithdrawFormBloc extends Bloc<WithdrawFormEvent, WithdrawFormState> {
final KomodoDefiSdk _sdk;
final WalletType? _walletType;
final Mm2Api _mm2Api;

WithdrawFormBloc({
required Asset asset,
required KomodoDefiSdk sdk,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smk762 Thank you for this PR. Btw, for the future, the SDK has 1:1 type-safe mapping for most RPCs, which is accessible through the SDK, so passing _mm2Api isn't necessary here. e.g. _sdk.rpc.withdraw.withdraw or _sdk.rpc.withdraw.sendRawTransaction.

But in general, we want to avoid having to use RPCs instead of the abstracted/managed SDK features so that devs don't need to learn and understand KDF's API. With the SDK's withdrawal feature now unused, it suggests it doesn't meet our needs, and therefore won't meet the needs of other developers.

required Mm2Api mm2Api,
WalletType? walletType,
}) : _sdk = sdk,
_mm2Api = mm2Api,
_walletType = walletType,
super(
WithdrawFormState(
Expand Down Expand Up @@ -471,34 +476,48 @@ class WithdrawFormBloc extends Bloc<WithdrawFormEvent, WithdrawFormState> {
state.copyWith(
isSending: true,
transactionError: () => null,
// No second device interaction is needed on confirm
isAwaitingTrezorConfirmation: false,
),
);

// Show Trezor progress message for hardware wallets
if (_walletType == WalletType.trezor) {
emit(state.copyWith(isAwaitingTrezorConfirmation: true));
final preview = state.preview;
if (preview == null) {
throw Exception('Missing withdrawal preview');
}

await for (final progress in _sdk.withdrawals.withdraw(
state.toWithdrawParameters(),
)) {
if (progress.status == WithdrawalStatus.complete) {
emit(
state.copyWith(
step: WithdrawFormStep.success,
result: () => progress.withdrawalResult,
isSending: false,
isAwaitingTrezorConfirmation: false,
),
);
return;
}
final response = await _mm2Api.sendRawTransaction(
SendRawTransactionRequest(
coin: preview.coin,
txHex: preview.txHex,
),
);

if (progress.status == WithdrawalStatus.error) {
throw Exception(progress.errorMessage);
}
if (response.txHash == null) {
throw Exception(response.error?.message ?? 'Broadcast failed');
}

final result = WithdrawalResult(
txHash: response.txHash!,
balanceChanges: preview.balanceChanges,
coin: preview.coin,
toAddress: preview.to.first,
fee: preview.fee,
kmdRewardsEligible:
preview.kmdRewards != null &&
Decimal.parse(preview.kmdRewards!.amount) > Decimal.zero,
);

emit(
state.copyWith(
step: WithdrawFormStep.success,
result: () => result,
// Clear cached preview after successful broadcast
preview: () => null,
isSending: false,
isAwaitingTrezorConfirmation: false,
),
);
return;
} catch (e) {
// Capture FD snapshot when KDF withdrawal submission fails
if (PlatformTuner.isIOS) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:web_dex/bloc/coins_bloc/asset_coin_extension.dart';
import 'package:web_dex/bloc/withdraw_form/withdraw_form_bloc.dart';
import 'package:web_dex/generated/codegen_loader.g.dart';
import 'package:web_dex/mm2/mm2_api/rpc/base.dart';
import 'package:web_dex/mm2/mm2_api/mm2_api.dart';
import 'package:web_dex/model/text_error.dart';
import 'package:web_dex/model/wallet.dart';
import 'package:web_dex/shared/utils/extensions/kdf_user_extensions.dart';
Expand Down Expand Up @@ -50,6 +51,7 @@ class WithdrawForm extends StatefulWidget {
class _WithdrawFormState extends State<WithdrawForm> {
late final WithdrawFormBloc _formBloc;
late final _sdk = context.read<KomodoDefiSdk>();
late final _mm2Api = context.read<Mm2Api>();

@override
void initState() {
Expand All @@ -59,6 +61,7 @@ class _WithdrawFormState extends State<WithdrawForm> {
_formBloc = WithdrawFormBloc(
asset: widget.asset,
sdk: _sdk,
mm2Api: _mm2Api,
walletType: walletType,
);
}
Expand Down Expand Up @@ -698,7 +701,7 @@ class WithdrawFormConfirmSection extends StatelessWidget {
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: Text(LocaleKeys.confirm.tr()),
: Text(LocaleKeys.send.tr()),
),
),
],
Expand Down
Loading