CW-1146-Enable-Zano-buy-sell-for-DFX (#2458)

* feat(CW-1148): Add Zano wallet support for message * refactor(CW-1148): Simplify `signMessage` logic in Zano wallet API * fix: remove unsupported wallet types from DFX Buy provider * fix: correct DFX Buy provider parameter name from `amount` to `amount-in`

Konstantin Ullrich committed Aug 19, 2025 at 17:28 UTC cb53840332802156ccd7ffb29a45931d64a8c4ef
3 files changed +36 -7
cw_zano/lib/zano_wallet.dart
+2 -3
@@ -59,9 +59,8 @@ abstract class ZanoWalletBase
59 String get password => _password;
60
61 @override
62 - Future<String> signMessage(String message, {String? address = null}) {
63 - throw UnimplementedError();
64 - }
62 + Future<String> signMessage(String message, {String? address = null}) =>
63 + super.signMessage(message, address: address);
64
65 @override
66 Future<bool> verifyMessage(String message, String signature, {String? address = null}) {
cw_zano/lib/zano_wallet_api.dart
+30 -1
@@ -401,6 +401,35 @@ mixin ZanoWalletApi {
401 throw TransferException('Transfer error, empty result');
402 }
403
404 + Future<String> signMessage(String message, {String? address = null}) async {
405 + try {
406 + final messageBase64 = convert.base64.encode(convert.utf8.encode(message));
407 + final response = await invokeMethod('sign_message', {'buff': messageBase64});
408 + final responseData = convert.jsonDecode(response) as Map<String, dynamic>;
409 +
410 + if (responseData['error'] != null) {
411 + printV('ZANO sign_message error: ${responseData['error']}');
412 + throw Exception('Zano sign_message failed: ${responseData['error']}');
413 + }
414 +
415 + final result = responseData['result'] as Map<String, dynamic>?;
416 + if (result == null) {
417 + throw Exception('Invalid response from sign_message');
418 + }
419 +
420 + final signature = result['sig'] as String?;
421 +
422 + if (signature == null) {
423 + throw Exception('No signature in response');
424 + }
425 +
426 + return signature;
427 + } catch (e) {
428 + printV('ZANO signMessage error: $e');
429 + rethrow;
430 + }
431 + }
432 +
433 void _checkForErrors(Map<String, dynamic>? map) {
434 if (map == null) {
435 throw ZanoWalletException('Empty response');
@@ -510,4 +539,4 @@ Future<String> _closeWallet(int hWallet) async {
539 return str;
540 }
541
513 -Map<String, List<int>> debugCallLength() => zano.debugCallLength;
\ No newline at end of file
542 +Map<String, List<int>> debugCallLength() => zano.debugCallLength;
lib/buy/dfx/dfx_buy_provider.dart
+4 -3
@@ -62,9 +62,9 @@ class DFXBuyProvider extends BuyProvider {
62 String get blockchain {
63 switch (wallet.type) {
64 case WalletType.bitcoin:
65 - case WalletType.bitcoinCash:
66 - case WalletType.litecoin:
65 return 'Bitcoin';
66 + case WalletType.zano:
67 + return 'Zano';
68 default:
69 return walletTypeToString(wallet.type);
70 }
@@ -131,6 +131,7 @@ class DFXBuyProvider extends BuyProvider {
131 case WalletType.litecoin:
132 case WalletType.bitcoin:
133 case WalletType.bitcoinCash:
134 + case WalletType.zano:
135 return await wallet.signMessage(message, address: walletAddress);
136 default:
137 throw Exception("WalletType is not available for DFX ${wallet.type}");
@@ -345,7 +346,7 @@ class DFXBuyProvider extends BuyProvider {
346 'asset-out': isBuyAction ? quote.cryptoCurrency.toString() : quote.fiatCurrency.toString(),
347 'blockchain': blockchain,
348 'asset-in': isBuyAction ? quote.fiatCurrency.toString() : quote.cryptoCurrency.toString(),
348 - 'amount': amount.toString() //TODO: Amount does not work
349 + 'amount-in': amount.toString()
350 });
351
352 if (await canLaunchUrl(uri)) {