fix send ETH
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
Reference in New Issue
Block a user