Swap
Swap parameters
Swaps (BUY/SELL) are possible using exacts amounts IN or OUT. That makes 4 types of swaps, handled as an enum in the program. This translates to the following type for Anchor:
/// Swap inputs are gathered in a single object (Anchor's conversion from the rust enum)
/// Every usual type of swap is supported:
// - buyExactIn: {amountIn: number, minAmountOut: number}
// - buyExactOut: {amountOut: number, maxAmountIn: number}
// - sellExactIn: {amountIn: number, minAmountOut: numer}
// - sellExactOut: {amountOut: number, maxAmountIn: number}
const swapParameters = {
buyExactIn: [
new anchor.BN(10_000_000), // 0.01 SOL
new anchor.BN(1),
],
};
We'll use buyExactIn
for the rest of this example.
SOL wrapping
If the quote token is WSOL, buying will require some wrapped SOL.
const transferIx = anchor.web3.SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: userTokenAccount1.address,
lamports: swapParameters.buyExactIn[0].toNumber(),
});
const syncNativeIx = createSyncNativeInstruction(userTokenAccount1.address);
const tx = new anchor.web3.Transaction().add(transferIx, syncNativeIx);
Fee addresses
Protocol and KOTM addresses are specified on the config account, that can be fetched on-chain.
const config = new PublicKey(process.env.CONFIG ?? "");
const configAccount = await program.account.tokenMillConfig.fetch(config);
const market = new PublicKey(process.env.MARKET ?? "");
const marketAccount = await program.account.market.fetch(market);
const baseTokenMint = marketAccount.tokenMint0;
// The market fee reserve can be set directly on the market account, but if it isn't, it falls back to the config account
const marketFeeReserve =
marketAccount.feeReserve ?? configAccount.creatorFeePool;
const userTokenAccount0 = await getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
baseTokenMint,
wallet.publicKey
);
const userTokenAccount1 = await getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
marketAccount.tokenMint1,
wallet.publicKey
);
Transaction
const swapIx = await program.methods
.swap(swapParameters)
.accountsPartial({
config,
market,
marketReserve0: marketAccount.reserve0,
marketReserve1: marketAccount.reserve1,
feeReserve: marketFeeReserve,
creatorFeePool: configAccount.creatorFeePool,
userTokenAccount0: userTokenAccount0.address,
userTokenAccount1: userTokenAccount1.address,
protocolFeeReserve: configAccount.protocolFeeReserve,
user: wallet.publicKey,
swapAuthority: null,
})
.signers([wallet.payer])
.instruction();
tx.push(swapIx);
const txSignature = await connection.sendTransaction(tx, [wallet.payer]);
await connection.confirmTransaction(txSignature);
Last updated