CW-1175-Implement-swaps.xyz-swap-provider (#2526)

* Integrate SwapsXYZ

* Remove print

* enhance SwapsXyz EVM token swap handling

* Disable fixed rate support in SwapsXyz provider

* enable fixed rate swap

* fix timestamp parsing

* remove sender and recipient address from fetchRate

* Improve SwapsXYZ trade approval logic

* fix trade ID overflow

* add Base chain support for  swaps xyz

* Update lib/view_model/exchange/exchange_trade_view_model.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* add missing support for Base

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Serhii
2025-10-20 23:22:01 +02:00
committed by GitHub
co-authored by Omar Hatem
parent 697ec0ab82
commit ee0996f535
37 changed files with 1557 additions and 77 deletions
+1
View File
@@ -111,6 +111,7 @@ abstract class EVMChainClient {
sender: senderAddress,
to: toAddress,
value: value,
data: data,
);
return estimatedGas.toInt();
+76
View File
@@ -40,6 +40,7 @@ import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart';
import 'package:eth_sig_util/eth_sig_util.dart';
import 'contract/erc20.dart';
import 'evm_chain_transaction_info.dart';
import 'evm_erc20_balance.dart';
@@ -611,6 +612,50 @@ abstract class EVMChainWalletBase
return pendingEVMChainTransaction;
}
Future<PendingTransaction> createCallDataTransaction(
String to,
String dataHex,
BigInt valueWei,
EVMChainTransactionPriority priority,
) async {
// Estimate gas with the SAME call (sender, to, value, data)
final gas = await calculateActualEstimatedFeeForCreateTransaction(
amount: valueWei, // native value (usually 0 for ERC20 transfer)
receivingAddressHex: to,
priority: priority,
contractAddress: null,
data: _client.hexToBytes(dataHex),
);
final nativeCurrency = switch (_client.chainId) {
137 => CryptoCurrency.maticpoly,
8453 => CryptoCurrency.baseEth,
_ => CryptoCurrency.eth,
};
// Fallback for nodes that fail estimate (non-zero)
final gasUnits = gas.estimatedGasUnits == 0 ? 65000 : gas.estimatedGasUnits;
// Sign raw (native) tx with callData
return _client.signTransaction(
privateKey: _evmChainPrivateKey,
toAddress: to,
amount: valueWei,
gasFee: BigInt.from(gas.estimatedGasFee),
estimatedGasUnits: gasUnits,
maxFeePerGas: gas.maxFeePerGas,
priority: priority,
currency: nativeCurrency,
feeCurrency: nativeCurrency.title,
exponent: 18,
contractAddress: null,
data: dataHex,
gasPrice: gas.gasPrice,
);
}
Future<PendingTransaction> createApprovalTransaction(BigInt amount, String spender,
CryptoCurrency token, EVMChainTransactionPriority priority, String feeCurrency) async {
final CryptoCurrency transactionCurrency =
@@ -793,6 +838,37 @@ abstract class EVMChainWalletBase
}
}
Future<bool> isApprovalRequired(
String tokenContract,
String spender,
BigInt requiredAmount) async {
const zero = '0x0000000000000000000000000000000000000000';
const evmNative = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
final token = tokenContract.toLowerCase();
if (token == zero || token == evmNative.toLowerCase()) return false;
if (requiredAmount <= BigInt.zero) return false;
try {
final owner = _evmChainPrivateKey.address;
final erc20 = ERC20(
client: _client.getWeb3Client()!,
address: EthereumAddress.fromHex(tokenContract),
chainId: _client.chainId,
);
final allowance = await erc20.allowance(
owner,
EthereumAddress.fromHex(spender));
return allowance < requiredAmount;
} catch (e) {
printV('approval-check error: $e');
return true;
}
}
Future<EthPrivateKey> getPrivateKey({
String? mnemonic,
String? privateKey,
@@ -51,7 +51,15 @@ class PendingEVMChainTransaction with PendingTransaction {
return '0x${Hex.HEX.encode(txid)}';
}
@override
String? get evmTxHashFromRawHex {
final no0x = hex.startsWith('0x') ? hex.substring(2) : hex;
final bytes = Uint8List.fromList(Hex.HEX.decode(no0x));
final digest = keccak256(bytes);
return '0x${Hex.HEX.encode(digest)}';
}
@override
Future<Map<String, String>> commitUR() {
throw UnimplementedError();