@cks-systems/manifest-sdk
Version:
TypeScript SDK for Manifest
87 lines (86 loc) • 5.35 kB
JavaScript
import { Connection, Keypair, sendAndConfirmTransaction, Transaction, } from '@solana/web3.js';
import { ManifestClient } from '../src/client';
import { createMarket } from './createMarket';
import { Market } from '../src/market';
import { createAssociatedTokenAccountIdempotent, getAssociatedTokenAddress, mintTo, } from '@solana/spl-token';
import { assert } from 'chai';
import { placeOrder } from './placeOrder';
import { airdropSol } from '../src/utils/solana';
import { depositGlobal } from './globalDeposit';
import { createGlobal } from './createGlobal';
import { OrderType } from '../src/manifest/types';
import { NO_EXPIRATION_LAST_VALID_SLOT } from '../src/constants';
async function testSwap() {
const connection = new Connection('http://127.0.0.1:8899', 'confirmed');
const payerKeypair = Keypair.generate();
const marketAddress = await createMarket(connection, payerKeypair);
const market = await Market.loadFromAddress({
connection,
address: marketAddress,
});
const traderTokenAccount = await createAssociatedTokenAccountIdempotent(connection, payerKeypair, market.baseMint(), payerKeypair.publicKey);
// Initialize so trader can receive.
await createAssociatedTokenAccountIdempotent(connection, payerKeypair, market.quoteMint(), payerKeypair.publicKey);
const amountAtoms = 1_000_000_000;
const mintSig = await mintTo(connection, payerKeypair, market.baseMint(), traderTokenAccount, payerKeypair.publicKey, amountAtoms);
console.log(`Minted ${amountAtoms} to ${traderTokenAccount} in ${mintSig}`);
await swap(connection, payerKeypair, marketAddress, amountAtoms / 10, false);
await market.reload(connection);
market.prettyPrint();
// Asks are sorted worst to best.
assert(market.openOrders().length == 0, 'Swap does not rest order');
}
export async function swap(connection, payerKeypair, marketAddress, amountAtoms, isBid, minOutAtoms = 0) {
const client = await ManifestClient.getClientForMarket(connection, marketAddress, payerKeypair);
const swapIx = client.swapIx(payerKeypair.publicKey, {
inAtoms: amountAtoms,
outAtoms: minOutAtoms,
isBaseIn: !isBid,
isExactIn: true,
});
const signature = await sendAndConfirmTransaction(connection, new Transaction().add(swapIx), [payerKeypair]);
console.log(`Swapped in ${signature}`);
}
async function testSwapGlobal() {
const connection = new Connection('http://127.0.0.1:8899', 'confirmed');
const payerKeypair = Keypair.generate();
const restingOrderTraderKeypair = Keypair.generate();
await airdropSol(connection, restingOrderTraderKeypair.publicKey);
const marketAddress = await createMarket(connection, payerKeypair);
const market = await Market.loadFromAddress({
connection,
address: marketAddress,
});
const traderBaseTokenAccount = await createAssociatedTokenAccountIdempotent(connection, payerKeypair, market.baseMint(), payerKeypair.publicKey);
// Initialize trader quote so they can receive.
await createAssociatedTokenAccountIdempotent(connection, payerKeypair, market.quoteMint(), payerKeypair.publicKey);
const amountBaseAtoms = 1_000_000_000;
const mintSig = await mintTo(connection, payerKeypair, market.baseMint(), traderBaseTokenAccount, payerKeypair.publicKey, amountBaseAtoms);
console.log(`Minted ${amountBaseAtoms} to ${traderBaseTokenAccount} in ${mintSig}`);
// Note that this is a self-trade for simplicity.
await airdropSol(connection, payerKeypair.publicKey);
await createGlobal(connection, payerKeypair, market.quoteMint());
await depositGlobal(connection, restingOrderTraderKeypair, market.quoteMint(), 10_000, payerKeypair);
await placeOrder(connection, restingOrderTraderKeypair, marketAddress, 5, 5, true, OrderType.Global, 1, NO_EXPIRATION_LAST_VALID_SLOT);
await swap(connection, payerKeypair, marketAddress, amountBaseAtoms, false);
await market.reload(connection);
market.prettyPrint();
// Verify that the resting order got matched and resulted in deposited base on
// the market. Quote came from global and got withdrawn in the swap. Seat
// results in no net deposit.
assert(market.getWithdrawableBalanceTokens(payerKeypair.publicKey, false) == 0, `Expected quote ${0} actual quote ${market.getWithdrawableBalanceTokens(payerKeypair.publicKey, false)}`);
assert(market.getWithdrawableBalanceTokens(payerKeypair.publicKey, true) == 0, `Expected base ${0} actual base ${market.getWithdrawableBalanceTokens(payerKeypair.publicKey, true)}`);
const swapperBaseBalance = (await connection.getTokenAccountBalance(await getAssociatedTokenAddress(market.baseMint(), payerKeypair.publicKey))).value.uiAmount;
const swapperQuoteBalance = (await connection.getTokenAccountBalance(await getAssociatedTokenAddress(market.quoteMint(), payerKeypair.publicKey))).value.uiAmount;
assert(swapperBaseBalance == 0, `Expected wallet base ${0} actual base ${swapperBaseBalance}`);
// 5, received from matching the global order.
assert(swapperQuoteBalance == 5, `Expected quote ${5} actual quote ${swapperQuoteBalance}`);
}
describe('Swap test', () => {
it('Swap', async () => {
await testSwap();
});
it('Swap against global', async () => {
await testSwapGlobal();
});
});