fix send ETH

This commit is contained in:
2025-07-06 16:22:36 +07:00
parent 218901672e
commit 344d0b9b12
2 changed files with 59 additions and 18 deletions

View File

@@ -669,12 +669,33 @@ export const sendTokenImpl = async (
chainId?: number, chainId?: number,
): Promise<string> => { ): Promise<string> => {
try { try {
chainId = chainId ?? ARBITRUM;
const networkName = getChainName(chainId);
const privy = getPrivyClient();
if (ticker === 'ETH') {
// Native ETH transfer: no allowance, no data, value is amount as hex string
const { hash } = await privy.walletApi.ethereum.sendTransaction({
address: senderAddress as Address,
chainType: 'ethereum',
caip2: networkName as string,
transaction: {
to: recipientAddress as Address,
value: '0x' + amount.toString(16), // value in wei as hex string
chainId: chainId,
},
} as any);
return hash;
}
// ERC20 logic
// Get token data from ticker // Get token data from ticker
const tokenData = GetToken(ticker); const tokenData = GetToken(ticker);
if (!tokenData) {
throw new Error(`Token not found: ${ticker}`);
}
// Check if sender has sufficient allowance for the token transfer // Check if sender has sufficient allowance for the token transfer
const senderAllowance = await getTokenAllowance(senderAddress, tokenData.address, senderAddress); const senderAllowance = await getTokenAllowance(senderAddress, tokenData.address, senderAddress);
// If insufficient allowance, approve the token first // If insufficient allowance, approve the token first
if (senderAllowance < amount) { if (senderAllowance < amount) {
console.log(`Insufficient allowance (${senderAllowance}). Approving token for amount: ${amount}`); console.log(`Insufficient allowance (${senderAllowance}). Approving token for amount: ${amount}`);
@@ -682,27 +703,17 @@ export const sendTokenImpl = async (
senderAddress, senderAddress,
tokenData.address, tokenData.address,
senderAddress, // Approve self to spend tokens senderAddress, // Approve self to spend tokens
chainId ?? ARBITRUM, chainId,
amount amount
); );
console.log('Token approval completed'); console.log('Token approval completed');
} }
// Create contract interface for ERC20 token // Create contract interface for ERC20 token
const contractInterface = new ethers.Interface(Token.abi); const contractInterface = new ethers.Interface(Token.abi);
// Amount is already in the smallest units (wei), so we don't need to convert it
// Convert amount to the correct decimal format const transferAmount = amount;
const transferAmount = ethers.parseUnits(amount.toString(), tokenData.decimals);
// Encode the transfer function call // Encode the transfer function call
const data = contractInterface.encodeFunctionData("transfer", [recipientAddress, transferAmount]); const data = contractInterface.encodeFunctionData("transfer", [recipientAddress, transferAmount]);
chainId = chainId ?? ARBITRUM;
// Get chain name in CAIP-2 format
const networkName = getChainName(chainId);
const privy = getPrivyClient();
// Send the transaction // Send the transaction
const { hash } = await privy.walletApi.ethereum.sendTransaction({ const { hash } = await privy.walletApi.ethereum.sendTransaction({
address: senderAddress as Address, address: senderAddress as Address,
@@ -714,7 +725,6 @@ export const sendTokenImpl = async (
chainId: chainId, chainId: chainId,
}, },
} as any); } as any);
return hash; return hash;
} catch (error) { } catch (error) {
console.error('Error sending token:', error); console.error('Error sending token:', error);

View File

@@ -1,5 +1,7 @@
import {FastifyPluginAsyncTypebox, Type} from '@fastify/type-provider-typebox' import {FastifyPluginAsyncTypebox, Type} from '@fastify/type-provider-typebox'
import {handleError} from '../../../utils/errorHandler.js' import {handleError} from '../../../utils/errorHandler.js'
import {TOKENS} from '../../../generated/gmxsdk/configs/tokens.js'
import {ARBITRUM} from '../../../generated/gmxsdk/configs/chains.js'
const plugin: FastifyPluginAsyncTypebox = async (fastify) => { const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
fastify.post( fastify.post(
@@ -108,8 +110,37 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
async function (request, reply) { async function (request, reply) {
try { try {
const { senderAddress, recipientAddress, ticker, amount, chainId } = request.body; const { senderAddress, recipientAddress, ticker, amount, chainId } = request.body;
// Convert amount string to bigint
const amountBigInt = BigInt(amount); // Handle decimal numbers with comma separators and convert to proper token units
let amountBigInt: bigint;
if (typeof amount === 'string') {
// Replace comma with period for decimal parsing
const normalizedAmount = amount.replace(',', '.');
// Parse as float first
const amountFloat = parseFloat(normalizedAmount);
if (isNaN(amountFloat)) {
throw new Error(`Invalid amount format: ${amount}`);
}
// Get token decimals from GMX configuration
const chainTokens = TOKENS[ARBITRUM];
const token = chainTokens.find(t => t.symbol === ticker);
if (!token) {
throw new Error(`Token not found: ${ticker}`);
}
const tokenDecimals = token.decimals;
const amountInSmallestUnit = Math.floor(amountFloat * Math.pow(10, tokenDecimals));
amountBigInt = BigInt(amountInSmallestUnit);
} else {
amountBigInt = BigInt(amount);
}
return await request.sendToken(reply, senderAddress, recipientAddress, ticker, amountBigInt, chainId); return await request.sendToken(reply, senderAddress, recipientAddress, ticker, amountBigInt, chainId);
} catch (error) { } catch (error) {
return handleError(request, reply, error, 'privy/send-token'); return handleError(request, reply, error, 'privy/send-token');