import 'package:web3dart/web3dart.dart';
import 'package:convert/convert.dart';
import 'package:web3dart/crypto.dart'; // For the bytes padding
Future<String> signEthTokenTransaction({
required int nonce,
required EthereumAddress contractAddress,
required EthereumAddress to,
required BigInt value,
required BigInt gasLimit,
required EtherAmount gasPrice,
required int wei,
required String privateKeyHex,
required int chainId,
}) async {
// Connect to the Ethereum client
final client = Web3Client('', Client());
// Format the 'value' to match the token's decimal places
final formattedValue = value * BigInt.from(10).pow(wei);
// Define the transfer function hash: keccak256("transfer(address,uint256)").take(4) => 'a9059cbb'
final functionSignature = hex.decode('a9059cbb');
// Format 'to' address (20 bytes) and 'value' (32 bytes)
final toBytes = hex.decode(to.hexEip55.substring(2)).padLeft(32, 0);
final valueBytes = hex.decode(formattedValue.toRadixString(16).padLeft(64, '0'));
// Combine function signature, to address, and value into transaction data
final transactionData = BytesBuilder();
transactionData.add(functionSignature);
transactionData.add(toBytes);
transactionData.add(valueBytes);
// Prepare the transaction
final transaction = Transaction(
nonce: nonce,
maxGas: gasLimit.toInt(),
gasPrice: gasPrice,
to: contractAddress,
value: EtherAmount.zero(), // For token transfer, ETH value is zero
data: transactionData.toBytes(),
);
// Convert private key and sign transaction
final privateKey = EthPrivateKey.fromHex(privateKeyHex);
final signedTx = await client.signTransaction(privateKey, transaction, chainId: chainId);
// Clean up the client and return serialized transaction
client.dispose();
return hex.encode(signedTx);
}