mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-13 17:01:02 +00:00
fix: use NATIVE_TOKEN_ID (-1) for pool matching and XCM Location for swaps
- Changed HEZ assetId from 0 to -1 (NATIVE_TOKEN_ID) for correct pool matching - Updated swap transactions to use XCM MultiLocation format - Added multi-hop support for PEZ ↔ USDT through HEZ
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
|||||||
formatTokenBalance,
|
formatTokenBalance,
|
||||||
getAmountOut,
|
getAmountOut,
|
||||||
calculatePriceImpact,
|
calculatePriceImpact,
|
||||||
|
formatAssetLocation,
|
||||||
} from '@pezkuwi/utils/dex';
|
} from '@pezkuwi/utils/dex';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
|
|
||||||
@@ -24,9 +25,10 @@ interface SwapInterfaceProps {
|
|||||||
|
|
||||||
type TransactionStatus = 'idle' | 'signing' | 'submitting' | 'success' | 'error';
|
type TransactionStatus = 'idle' | 'signing' | 'submitting' | 'success' | 'error';
|
||||||
|
|
||||||
// User-facing tokens (wHEZ is hidden from users, shown as HEZ)
|
// User-facing tokens
|
||||||
|
// Native HEZ uses NATIVE_TOKEN_ID (-1) for pool matching
|
||||||
const USER_TOKENS = [
|
const USER_TOKENS = [
|
||||||
{ symbol: 'HEZ', emoji: '🟡', assetId: 0, name: 'HEZ', decimals: 12, displaySymbol: 'HEZ' }, // actually wHEZ (asset 0)
|
{ symbol: 'HEZ', emoji: '🟡', assetId: -1, name: 'HEZ', decimals: 12, displaySymbol: 'HEZ' }, // Native HEZ (NATIVE_TOKEN_ID)
|
||||||
{ symbol: 'PEZ', emoji: '🟣', assetId: 1, name: 'PEZ', decimals: 12, displaySymbol: 'PEZ' },
|
{ symbol: 'PEZ', emoji: '🟣', assetId: 1, name: 'PEZ', decimals: 12, displaySymbol: 'PEZ' },
|
||||||
{ symbol: 'USDT', emoji: '💵', assetId: 1000, name: 'USDT', decimals: 6, displaySymbol: 'USDT' },
|
{ symbol: 'USDT', emoji: '💵', assetId: 1000, name: 'USDT', decimals: 6, displaySymbol: 'USDT' },
|
||||||
] as const;
|
] as const;
|
||||||
@@ -227,58 +229,78 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
|
|||||||
|
|
||||||
let tx;
|
let tx;
|
||||||
|
|
||||||
|
// Native HEZ uses NATIVE_TOKEN_ID (-1) for XCM Location
|
||||||
|
// assetConversion pallet expects XCM MultiLocation format for swap paths
|
||||||
|
const nativeLocation = formatAssetLocation(-1); // { parents: 1, interior: 'Here' }
|
||||||
|
const pezLocation = formatAssetLocation(1); // PEZ asset
|
||||||
|
const usdtLocation = formatAssetLocation(1000); // wUSDT asset
|
||||||
|
|
||||||
if (fromToken === 'HEZ' && toToken === 'PEZ') {
|
if (fromToken === 'HEZ' && toToken === 'PEZ') {
|
||||||
// HEZ → PEZ: wrap(HEZ→wHEZ) then swap(wHEZ→PEZ)
|
// HEZ → PEZ: Direct swap using native token
|
||||||
const wrapTx = assetHubApi.tx.tokenWrapper.wrap(amountIn.toString());
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
[nativeLocation, pezLocation],
|
||||||
[0, 1], // wHEZ → PEZ
|
|
||||||
amountIn.toString(),
|
amountIn.toString(),
|
||||||
minAmountOut.toString(),
|
minAmountOut.toString(),
|
||||||
account,
|
account,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
tx = assetHubApi.tx.utility.batchAll([wrapTx, swapTx]);
|
|
||||||
|
|
||||||
} else if (fromToken === 'PEZ' && toToken === 'HEZ') {
|
} else if (fromToken === 'PEZ' && toToken === 'HEZ') {
|
||||||
// PEZ → HEZ: swap(PEZ→wHEZ) then unwrap(wHEZ→HEZ)
|
// PEZ → HEZ: Direct swap to native token
|
||||||
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
[1, 0], // PEZ → wHEZ
|
[pezLocation, nativeLocation],
|
||||||
amountIn.toString(),
|
amountIn.toString(),
|
||||||
minAmountOut.toString(),
|
minAmountOut.toString(),
|
||||||
account,
|
account,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const unwrapTx = assetHubApi.tx.tokenWrapper.unwrap(minAmountOut.toString());
|
|
||||||
tx = assetHubApi.tx.utility.batchAll([swapTx, unwrapTx]);
|
|
||||||
|
|
||||||
} else if (fromToken === 'HEZ') {
|
} else if (fromToken === 'HEZ' && toToken === 'USDT') {
|
||||||
// HEZ → Any Asset: wrap(HEZ→wHEZ) then swap(wHEZ→Asset)
|
// HEZ → USDT: Direct swap using native token
|
||||||
const wrapTx = assetHubApi.tx.tokenWrapper.wrap(amountIn.toString());
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
[nativeLocation, usdtLocation],
|
||||||
[0, toAssetId!], // wHEZ → target asset
|
|
||||||
amountIn.toString(),
|
amountIn.toString(),
|
||||||
minAmountOut.toString(),
|
minAmountOut.toString(),
|
||||||
account,
|
account,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
tx = assetHubApi.tx.utility.batchAll([wrapTx, swapTx]);
|
|
||||||
|
|
||||||
} else if (toToken === 'HEZ') {
|
} else if (fromToken === 'USDT' && toToken === 'HEZ') {
|
||||||
// Any Asset → HEZ: swap(Asset→wHEZ) then unwrap(wHEZ→HEZ)
|
// USDT → HEZ: Direct swap to native token
|
||||||
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
[fromAssetId!, 0], // source asset → wHEZ
|
[usdtLocation, nativeLocation],
|
||||||
|
amountIn.toString(),
|
||||||
|
minAmountOut.toString(),
|
||||||
|
account,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if (fromToken === 'PEZ' && toToken === 'USDT') {
|
||||||
|
// PEZ → USDT: Multi-hop through HEZ (PEZ → HEZ → USDT)
|
||||||
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
|
[pezLocation, nativeLocation, usdtLocation],
|
||||||
|
amountIn.toString(),
|
||||||
|
minAmountOut.toString(),
|
||||||
|
account,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if (fromToken === 'USDT' && toToken === 'PEZ') {
|
||||||
|
// USDT → PEZ: Multi-hop through HEZ (USDT → HEZ → PEZ)
|
||||||
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
|
[usdtLocation, nativeLocation, pezLocation],
|
||||||
amountIn.toString(),
|
amountIn.toString(),
|
||||||
minAmountOut.toString(),
|
minAmountOut.toString(),
|
||||||
account,
|
account,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const unwrapTx = assetHubApi.tx.tokenWrapper.unwrap(minAmountOut.toString());
|
|
||||||
tx = assetHubApi.tx.utility.batchAll([swapTx, unwrapTx]);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Direct swap between assets (PEZ ↔ USDT, etc.)
|
// Generic swap using XCM Locations
|
||||||
|
const fromLocation = formatAssetLocation(fromAssetId!);
|
||||||
|
const toLocation = formatAssetLocation(toAssetId!);
|
||||||
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
|
||||||
[fromAssetId!, toAssetId!],
|
[fromLocation, toLocation],
|
||||||
amountIn.toString(),
|
amountIn.toString(),
|
||||||
minAmountOut.toString(),
|
minAmountOut.toString(),
|
||||||
account,
|
account,
|
||||||
|
|||||||
Reference in New Issue
Block a user