fix send ETH
This commit is contained in:
@@ -669,12 +669,33 @@ export const sendTokenImpl = async (
|
||||
chainId?: number,
|
||||
): Promise<string> => {
|
||||
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
|
||||
const tokenData = GetToken(ticker);
|
||||
|
||||
if (!tokenData) {
|
||||
throw new Error(`Token not found: ${ticker}`);
|
||||
}
|
||||
// Check if sender has sufficient allowance for the token transfer
|
||||
const senderAllowance = await getTokenAllowance(senderAddress, tokenData.address, senderAddress);
|
||||
|
||||
// If insufficient allowance, approve the token first
|
||||
if (senderAllowance < amount) {
|
||||
console.log(`Insufficient allowance (${senderAllowance}). Approving token for amount: ${amount}`);
|
||||
@@ -682,27 +703,17 @@ export const sendTokenImpl = async (
|
||||
senderAddress,
|
||||
tokenData.address,
|
||||
senderAddress, // Approve self to spend tokens
|
||||
chainId ?? ARBITRUM,
|
||||
chainId,
|
||||
amount
|
||||
);
|
||||
console.log('Token approval completed');
|
||||
}
|
||||
|
||||
// Create contract interface for ERC20 token
|
||||
const contractInterface = new ethers.Interface(Token.abi);
|
||||
|
||||
// Convert amount to the correct decimal format
|
||||
const transferAmount = ethers.parseUnits(amount.toString(), tokenData.decimals);
|
||||
|
||||
// Amount is already in the smallest units (wei), so we don't need to convert it
|
||||
const transferAmount = amount;
|
||||
// Encode the transfer function call
|
||||
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
|
||||
const { hash } = await privy.walletApi.ethereum.sendTransaction({
|
||||
address: senderAddress as Address,
|
||||
@@ -714,7 +725,6 @@ export const sendTokenImpl = async (
|
||||
chainId: chainId,
|
||||
},
|
||||
} as any);
|
||||
|
||||
return hash;
|
||||
} catch (error) {
|
||||
console.error('Error sending token:', error);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import {FastifyPluginAsyncTypebox, Type} from '@fastify/type-provider-typebox'
|
||||
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) => {
|
||||
fastify.post(
|
||||
@@ -108,8 +110,37 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
|
||||
async function (request, reply) {
|
||||
try {
|
||||
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);
|
||||
} catch (error) {
|
||||
return handleError(request, reply, error, 'privy/send-token');
|
||||
|
||||
Reference in New Issue
Block a user