DEX
Prepare
if(!process.env.MNEMONIC) {
throw new Error('MNEMINIC IS REQUIRED!');
}
// init wallet
const mnemonic = process.env.MNEMONIC.split(" ");
const keys = await mnemonicToPrivateKey(mnemonic);
const wallet = tonClient.open(
WalletContractV4.create({
workchain: 0,
publicKey: keys.publicKey
})
);
// get config
const apiConfig = await getApiConfig();
// get listed assets
const apiAssets = await getApiAssets();
// init factory
const dexFactory = tonClient.open(DexFactory.createFromAddress(apiConfig.dex_factory));
// select assets
const asset1_id = null; // ton
const asset2_id = Address.parse(apiAssets[1].asset_id); // usdt, in this case
// get pool address
const poolAddr = await dexFactory.getPool(asset1_id, asset2_id);
// init pool
const dexPool = tonClient.open(DexPool.createFromAddress(poolAddr));
TON swap
// simple swap 1 TON to USDT
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('1'));
// complex swap
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 321, toNano('2'), {
gas: toNano('0.25'), // custom gas
min_out: 1000n, // custom min_out
deadline: 1743889864, // unix time
excess: someAddr, // all excesses from this hop will be sent to this address
referral: refAddr, // referral cut will be sent to this address
next_fulfill: someCell, // if swap succeed, this payload will be sent to specified address
next_reject: someCell // if swap failed, this payload will be sent to specified address
});
// multi hop. TON -> USDT -> BOLT
const nextFulfillCell = beginCell()
.storeAddress(nextPool) // USDT-BOLT pool
.storeMaybeRef(packSwapPayloadJetton({ // payload which will be sent, in this case swap payload
min_out: 1000n,
}))
.endCell()
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('10'), {
gas: toNano('0.3'), // each hop should have 0.15 ton
excess: wallet.address,
next_fulfill: nextFulfillCell
});
// you can create as many hops ask you like
const nextFulfillCell = beginCell()
.storeAddress(nextPool)
.storeMaybeRef(packSwapPayloadJetton({
min_out: 1000n,
excess: wallet.address, // always specify excess on hops! otherwise will be sent to previous pool
nextFulfill: beginCell()
.storeAddress(nextPool2)
.storeMaybeRef(packSwapPayloadJetton({
min_out: 2000n,
nextFulfill: beginCell()
.storeAddress(nextPool3)
.storeMaybeRef(packSwapPayloadTon(123, toNano('0.5'), {
nextFulfill: beginCell()
.storeAddress(nextPool4)
.storeMaybeRef(......)
.endCell()
}))
.endCell()
}))
.endCell()
}))
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('13'), {
gas: toNano('0.15') * hops_count, // each hop = 0.15 ton - excess
excess: wallet.address,
next_fulfill: nextFulfillCell
});
JETTON swap
// Same logic, but we have to init jetton wallet for specified jetton
// init master
const jettonMaster = tonClient.open(JettonMinter.createFromAddress(asset2_id));
// init wallet
const jettonWallet = await jettonMaster.getWallet(wallet.address);
// simple swap 1 USDT to TON
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 123, 1000000n);
// complex jetton swap
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
forward_amount: toNano('0.3'), // each hop should have 0.15 ton
min_out: 100n,
deadline: 1743889864,
excess: wallet.address,
referral: null,
next_fulfill: someCell,
next_reject: otherCell
});
// same thing for hops
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
forward_amount: toNano('0.3'), // each hop should have 0.15 ton
min_out: 100n,
deadline: 1743889864,
excess: wallet.address,
referral: null,
next_fulfill: beginCell()
.storeAddress(nextAddress)
.storeMaybeRef(
packSwapPayloadJetton({
min_out: 1000n
})
)
.endCell()
});
// or any custom payload
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
forward_amount: toNano('0.3'), // each hop should have 0.15 ton
min_out: 100n,
deadline: 1743965438,
excess: wallet.address,
next_fulfill: beginCell()
.storeAddress(someAddress)
.storeMaybeRef(
beginCell()
.storeUint(333, 32)
.storeUint(777, 32)
.storeAddress(durovAddress)
.endCell()
)
.endCell()
});
TON deposit liquidity
await dexPool.sendDepositLiquidityTon(
wallet.sender(keys.secretKey),
123, // query_id
toNano('2'), // amount
1000n // min_lp_out
);
JETTON deposit liquidity
await dexPool.sendDepositLiquidityJetton(
wallet.sender(keys.secretKey),
jettonWallet,
123, // query_id
1000000n, // amount
100n, // min_lp_out
);
Withdraw liquidity (burn LP)
await dexPool.sendBurnLp(
wallet.sender(keys.secretKey),
lpJettonWallet,
123, // query_id
1230000n, // amount
);
Create booster for pool
const boosterFactory = tonClient.open(DexBoosterFactory.createFromAddress(apiConfig.booster_factory));
// iteration_amount = boost_amount / iterations
await boosterFactory.sendCreateBoosterTon(
wallet.sender(keys.secretKey),
123, // query_id
dexPool.address, // pool
toNano('5'), // total boost_amount
2, // iterations
3600, // period
);
await boosterFactory.sendCreateBoosterJetton(
wallet.sender(keys.secretKey),
jettonWallet,
123, // query_id,
dexPool.address, // pool
toNano('10'), // total boost_amount
5, // iterations
5000, // period (seconds between iterations)
);
Getters
dexPool.getPool(); // all data in one call
dexPool.getEstimatedLp(asset1_id, asset1_amount, asset2_id, asset2_amount);
dexPool.getEstimatedLpBurn(lp_amount);
dexPool.getEstimatedSwapOut(asset_id, asset_amount);
dexPool.getFees();
dexPool.getAssets();
dexPool.getWallets();
dexPool.getReserves();
dexPool.getLpTotal();
dexPool.getLpAccount(owner);
dexPool.getWalletAddress(owner);
Last updated