import { transferCommand } from "@rsksmart/rsk-cli/dist/src/commands/transfer.js";
interface TransferParams {
testnet: boolean;
toAddress: string;
value: number;
tokenAddress?: string;
walletName?: string;
walletData?: any;
walletPassword?: string;
}
interface TransferResult {
success: boolean;
data?: any;
error?: string;
responseType: string;
}
export class TransferService {
async processTransfer(params: TransferParams): Promise<TransferResult> {
try {
const missingInfo = [];
if (!params.toAddress) {
missingInfo.push("π― **Recipient Address**: Enter the recipient's address (0x... format)");
}
if (!params.value || params.value <= 0) {
missingInfo.push("π° **Transfer Amount**: Enter a positive amount to transfer");
}
if (!params.walletData && !params.walletName) {
missingInfo.push("πΌ **Wallet Information**: Provide wallet data or wallet name");
}
if (params.walletData && !params.walletPassword) {
missingInfo.push("π **Wallet Password**: Password is required to decrypt your wallet");
}
if (params.toAddress && !/^0x[a-fA-F0-9]{40}$/.test(params.toAddress)) {
return {
success: false,
error: `β **Invalid Recipient Address**\n\nThe address "${params.toAddress}" is not a valid Ethereum address format.\n\n**Expected format**: 0x followed by 40 hexadecimal characters\n**Example**: 0x1234567890abcdef1234567890abcdef12345678`,
responseType: "ErrorInvalidAddress"
};
}
if (params.tokenAddress && !/^0x[a-fA-F0-9]{40}$/.test(params.tokenAddress)) {
return {
success: false,
error: `β **Invalid Token Address**\n\nThe token address "${params.tokenAddress}" is not a valid contract address format.\n\n**Expected format**: 0x followed by 40 hexadecimal characters\n**Example**: 0x1234567890abcdef1234567890abcdef12345678`,
responseType: "ErrorInvalidTokenAddress"
};
}
if (missingInfo.length > 0) {
return {
success: false,
error: this.formatMissingInfoError(missingInfo),
responseType: "ErrorMissingInfo"
};
}
let processedWalletData = params.walletData;
if (typeof params.walletData === "string") {
try {
processedWalletData = JSON.parse(params.walletData);
} catch (error) {
return {
success: false,
error: `β **Invalid Wallet Data Format**\n\nError parsing wallet data: ${error instanceof Error ? error.message : String(error)}\n\nPlease provide valid JSON wallet data.`,
responseType: "ErrorInvalidWalletData"
};
}
}
const transferParams = {
testnet: params.testnet,
toAddress: params.toAddress,
value: params.value,
tokenAddress: params.tokenAddress,
name: params.walletName,
walletsData: processedWalletData,
password: params.walletPassword,
isExternal: true
};
const result = await transferCommand(transferParams);
if (result?.success && result.data) {
return {
success: true,
data: result.data,
responseType: "TransferCompletedSuccessfully"
};
}
return {
success: false,
error: result?.error || "Transfer failed with unknown error",
responseType: "ErrorTransferFailed"
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
responseType: "ErrorTransferFailed"
};
}
}
private formatMissingInfoError(missingInfo: string[]): string {
return `β **Missing Required Information**\n\nTo complete the transfer, please provide the following:\n\n${missingInfo.map(info => `β’ ${info}`).join('\n')}\n\nOnce you provide all required information, try the transfer again.`;
}
formatTransferResponse(data: any): string {
const networkName = data.network || (data.testnet ? "Rootstock Testnet" : "Rootstock Mainnet");
const tokenInfo = data.token === "RBTC" ? "RBTC" : `${data.token} tokens`;
return `β
**Transfer Completed Successfully!**
πΈ **Transfer Details:**
β’ **Amount**: ${data.amount} ${data.token}
β’ **From**: ${data.from}
β’ **To**: ${data.to}
β’ **Network**: ${networkName}
π¦ **Transaction Details:**
β’ **Transaction Hash**: \`${data.transactionHash}\`
β’ **Block Number**: ${data.blockNumber}
β’ **Gas Used**: ${data.gasUsed}
π **View on Explorer**: [${data.transactionHash}](${data.explorerUrl})
β¨ Your ${tokenInfo} ${data.token === "RBTC" ? "has" : "have"} been successfully transferred!`;
}
formatTransferErrorResponse(error: string): string {
if (error.includes("Insufficient balance")) {
return `β **Insufficient Balance**
${error}
π‘ **Suggestions:**
β’ Check your current balance using the check-balance tool
β’ Ensure you have enough tokens/RBTC for the transfer
β’ Remember that gas fees are deducted from RBTC balance for all transfers
π Please verify your balance and try again with a valid amount.`;
}
if (error.includes("not a valid ERC20 token")) {
return `β **Invalid Token Contract**
${error}
π‘ **Suggestions:**
β’ Verify the token contract address is correct
β’ Ensure the address is a valid ERC20 token contract
β’ Check the token address on the blockchain explorer
π Please provide a valid ERC20 token address and try again.`;
}
return `β **Transfer Failed**
${error}
π‘ **Common Issues:**
β’ Invalid recipient address format
β’ Insufficient balance (including gas fees)
β’ Network connectivity issues
β’ Invalid token contract address
π Please check the transfer details and try again.`;
}
}