Skip to content

Commit

Permalink
fix: add liquidity support native TON
Browse files Browse the repository at this point in the history
  • Loading branch information
chef-eric committed Feb 13, 2025
1 parent 7488fe0 commit a9365ba
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 111 deletions.
8 changes: 8 additions & 0 deletions apps/ton/public/lists/testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
"symbol": "PAN",
"decimals": 9,
"logoURI": "https://cache.tonapi.io/imgproxy/lDgkbWC5IEAEMkI7blExSx5wvL0-g9yrw2RwfUMKbSg/rs:fill:200:200:1/g:no/aHR0cHM6Ly93d3cucHJlbWllcmtpdGNoZW4uaW4vd3AtY29udGVudC91cGxvYWRzLzIwMjEvMDMvTlMtRnJ5cGFuLTEuanBn.webp"
},
{
"chainId": -3,
"address": "kQD0zbW5arqfo7uaNs7TiBckhPp0m8xZgsMs6qdBU85p9UVB",
"name": "claude",
"symbol": "CLAUDE",
"decimals": 9,
"logoURI": "https://cache.tonapi.io/imgproxy/cOMlJuViiVXDCkAghnyNj7plX8pAZ9pv3WhklvebpTY/rs:fill:200:200:1/g:no/aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RvbmtlZXBlci9vcGVudG9uYXBpL21hc3Rlci9wa2cvcmVmZXJlbmNlcy9tZWRpYS90b2tlbl9wbGFjZWhvbGRlci5wbmc.webp"
}
]
}
12 changes: 7 additions & 5 deletions apps/ton/src/hooks/swap/useAllCommonPairs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Currency, Token, Pair, CurrencyAmount } from '@pancakeswap/ton-v2-sdk'
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from 'config/constants/exchange'
import { useAtomValue } from 'jotai'
import { poolDataQueriesAtom } from 'ton/atom/liquidity/poolDataQueriesAtom'
import { useUserAddress } from 'hooks/useUserAddress'

export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): { isLoading: boolean; data: Pair[] } {
const chainId = currencyA?.chainId
Expand Down Expand Up @@ -83,20 +84,21 @@ export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): {
}

const usePairs = (pairs: [Token, Token][]) => {
const userAddress = useUserAddress()
const pairsAddress = useMemo(
() =>
pairs.map(([token0, token1]) =>
token0.sortsBefore(token1)
? {
token0Address: token0.wrapped.address,
token1Address: token1.wrapped.address,
token0Address: token0.isNative ? userAddress.toString() : token0.wrapped.address,
token1Address: token1.isNative ? userAddress.toString() : token1.wrapped.address,
}
: {
token0Address: token1.wrapped.address,
token1Address: token0.wrapped.address,
token1Address: token0.isNative ? userAddress.toString() : token0.wrapped.address,
token0Address: token1.isNative ? userAddress.toString() : token1.wrapped.address,
},
),
[pairs],
[pairs, userAddress],
)
const result = useAtomValue(poolDataQueriesAtom(pairsAddress))
return useMemo(() => {
Expand Down
8 changes: 8 additions & 0 deletions apps/ton/src/hooks/useUserAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useAtomValue } from 'jotai'
import { addressAtom } from 'ton/atom/addressAtom'
import { parseAddress } from 'ton/utils/address'

export const useUserAddress = () => {
const userAddress = useAtomValue(addressAtom)
return parseAddress(userAddress)
}
7 changes: 2 additions & 5 deletions apps/ton/src/ton/generateQueryId.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { Address } from '@ton/core'

export function generateQueryId(userAddress: Address): bigint {
export function generateQueryId(): bigint {
const timestamp = BigInt(Date.now()) // Current time in milliseconds
const randomPart = BigInt(Math.floor(Math.random() * 1000)) // Random 3 digits
const addressPart = BigInt(parseInt(userAddress.toString().slice(-6), 16)) // Last 6 hex digits of the address
return (timestamp * 1000n + randomPart) ^ addressPart
return timestamp * 100000n + randomPart
}
142 changes: 46 additions & 96 deletions apps/ton/src/ton/logic/liquidity/useAddLiquidity.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Currency, storeAddLiquidity } from '@pancakeswap/ton-v2-sdk'
import { storeJettonTransferMessage } from '@ton-community/assets-sdk'
import { JETTON_TRANSFER_NOTIFICATION_OPCODE, storeJettonTransferMessage } from '@ton-community/assets-sdk'
import { beginCell, toNano } from '@ton/core'
import { SendTransactionRequest, useTonConnectUI } from '@tonconnect/ui-react'
import { useUserAddress } from 'hooks/useUserAddress'
import { useAtomValue } from 'jotai'
import { useCallback } from 'react'
import { addressAtom } from 'ton/atom/addressAtom'
import { routerContractAtom } from 'ton/atom/contracts/routerContractAtom'
import { TonContext } from 'ton/context/TonContext'
import { getJettonWalletAddress, parseAddress } from 'ton/utils/address'
import { generateQueryId } from 'ton/generateQueryId'
import { getJettonWalletAddress } from 'ton/utils/address'

interface AddLiquidityArgs {
token0: Currency
Expand All @@ -20,23 +21,24 @@ interface AddLiquidityArgs {
export const useAddLiquidity = () => {
const [tonUI] = useTonConnectUI()

const userAddress_ = useAtomValue(addressAtom)
const userAddress = useUserAddress()
const routerAddress = useAtomValue(routerContractAtom).address

const addLiquidity = useCallback(
async ({ token0, token1, amount0, amount1 }: AddLiquidityArgs) => {
const client = TonContext.instance.getClient()
const userAddress = parseAddress(userAddress_)

const userJettonWallet0 = await getJettonWalletAddress(client, userAddress, token0)
const userJettonWallet1 = await getJettonWalletAddress(client, userAddress, token1)
const routerJettonWallet0 = await getJettonWalletAddress(client, routerAddress, token0)
const routerJettonWallet1 = await getJettonWalletAddress(client, routerAddress, token1)

const newForwardPayload0 = beginCell()
const queryId = generateQueryId()

const forwardPayload0 = beginCell()
.store(
storeAddLiquidity({
queryId: 1n,
queryId,
$$type: 'AddLiquidity',
minLPOut: 2n,
tokenWallet: routerJettonWallet1,
Expand All @@ -46,21 +48,21 @@ export const useAddLiquidity = () => {
const payload0 = beginCell()
.store(
storeJettonTransferMessage({
queryId: 1n,
queryId,
amount: amount0,
destination: routerAddress,
responseDestination: userAddress,
customPayload: null,
forwardAmount: toNano('0.3'),
forwardPayload: newForwardPayload0,
forwardPayload: forwardPayload0,
}),
)
.endCell()

const newForwardPayload1 = beginCell()
const forwardPayload1 = beginCell()
.store(
storeAddLiquidity({
queryId: 2n,
queryId,
$$type: 'AddLiquidity',
minLPOut: 2n,
tokenWallet: routerJettonWallet0,
Expand All @@ -70,108 +72,56 @@ export const useAddLiquidity = () => {
const payload1 = beginCell()
.store(
storeJettonTransferMessage({
queryId: 2n,
queryId,
amount: amount1,
destination: routerAddress,
responseDestination: userAddress,
customPayload: null,
forwardAmount: toNano('0.3'),
forwardPayload: newForwardPayload1,
forwardPayload: forwardPayload1,
}),
)
.endCell()

const txRequest: SendTransactionRequest = {
validUntil: Math.floor(Date.now() / 1000) + 60 * 2,
messages: [
{
address: userJettonWallet0.toString(),
amount: toNano('0.2').toString(),
payload: payload0.toBoc().toString('base64'),
},
{
address: userJettonWallet1.toString(),
amount: toNano('0.2').toString(),
payload: payload1.toBoc().toString('base64'),
},
token0.isNative
? {
address: routerAddress.toString(),
amount: (BigInt(amount0) + toNano('0.3')).toString(), // TON amount + gas
payload: beginCell()
.storeUint(JETTON_TRANSFER_NOTIFICATION_OPCODE, 32)
.storeUint(queryId, 64)
.storeCoins(amount0)
.storeAddress(userAddress)
.storeMaybeRef(forwardPayload0)
.endCell()
.toBoc()
.toString('base64'),
}
: {
address: userJettonWallet0.toString(),
amount: toNano('0.6').toString(),
payload: payload0.toBoc().toString('base64'),
},
token1.isNative
? {
address: routerAddress.toString(),
amount: (BigInt(amount1) + toNano('0.3')).toString(), // TON amount + gas
payload: forwardPayload1.toBoc().toString('base64'),
}
: {
address: userJettonWallet1.toString(),
amount: toNano('0.6').toString(),
payload: payload1.toBoc().toString('base64'),
},
],
}

tonUI.sendTransaction(txRequest)

/// NEW WAY OF SENDING ADD LIQUIDITY TXN

// const newForwardPayload0 = beginCell()
// .store(
// storeAddLiquidity({
// queryId: 1n,
// $$type: 'AddLiquidity',
// minLPOut: 0n,
// newAmount0: amount0,
// newAmount1: amount1,
// }),
// )
// .endCell()

// const payload0 = beginCell()
// .store(
// storeJettonTransferMessage({
// queryId: 1n,
// amount: amount0,
// destination: routerAddress,
// responseDestination: walletAddress,
// customPayload: null,
// forwardAmount: toNano('0.1'),
// forwardPayload: newForwardPayload0,
// }),
// )
// .endCell()

// const newForwardPayload1 = beginCell()
// .store(
// storeAddLiquidity({
// queryId: 2n,
// $$type: 'AddLiquidity',
// minLPOut: 0n,
// newAmount0: amount0,
// newAmount1: amount1,
// }),
// )
// .endCell()

// const payload1 = beginCell()
// .store(
// storeJettonTransferMessage({
// queryId: 2n,
// amount: amount1,
// destination: routerAddress,
// responseDestination: walletAddress,
// customPayload: null,
// forwardAmount: toNano('0.1'),
// forwardPayload: newForwardPayload1,
// }),
// )
// .endCell()

const newTxRequest: SendTransactionRequest = {
validUntil: Math.floor(Date.now() / 1000) + 60 * 2,
messages: [
{
address: userJettonWallet0.toString(),
amount: toNano('0.6').toString(),
payload: payload0.toBoc().toString('base64'),
},
{
address: userJettonWallet1.toString(),
amount: toNano('0.6').toString(),
payload: payload1.toBoc().toString('base64'),
},
],
}

tonUI.sendTransaction(newTxRequest)
},
[tonUI, userAddress_, routerAddress],
[tonUI, userAddress, routerAddress],
)

return {
Expand Down
8 changes: 3 additions & 5 deletions apps/ton/src/ton/logic/swap/useSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { Contracts, Currency, TonContractNames, storeSwap } from '@pancakeswap/t
import { storeJettonTransferMessage } from '@ton-community/assets-sdk'
import { beginCell, toNano } from '@ton/core'
import { SendTransactionRequest, useTonConnectUI } from '@tonconnect/ui-react'
import { useAtomValue } from 'jotai'
import { useUserAddress } from 'hooks/useUserAddress'
import { useCallback } from 'react'
import { addressAtom } from 'ton/atom/addressAtom'
import { TonContext } from 'ton/context/TonContext'
import { getJettonWalletAddress, parseAddress } from 'ton/utils/address'

Expand All @@ -16,13 +15,12 @@ interface SwapArgs {
}

export const useSwap = () => {
const userAddress_ = useAtomValue(addressAtom)
const [tonUI] = useTonConnectUI()
const userAddress = useUserAddress()

const swap = useCallback(
async ({ amount0, minOut, token0, token1 }: SwapArgs) => {
const client = TonContext.instance.getClient()
const userAddress = parseAddress(userAddress_)
const routerAddress = parseAddress(Contracts[TonContractNames.PCSRouter].testnet.address)

const userJettonWallet0 = await getJettonWalletAddress(client, userAddress, token0)
Expand Down Expand Up @@ -73,7 +71,7 @@ export const useSwap = () => {

tonUI.sendTransaction(txRequest)
},
[userAddress_, tonUI],
[userAddress, tonUI],
)

return {
Expand Down

0 comments on commit a9365ba

Please sign in to comment.