133 lines
4.6 KiB
TypeScript
133 lines
4.6 KiB
TypeScript
import { PublicKey } from "@solana/web3.js";
|
|
import { BN } from "@coral-xyz/anchor";
|
|
|
|
// Objects prefixed with 'mock' are hoisted and allowed in jest.mock factory
|
|
const mockInternalConfig = {
|
|
connection: {},
|
|
wallet: { publicKey: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") },
|
|
poolAddress: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ"),
|
|
DRY_RUN: false,
|
|
SLIPPAGE_BPS: 100,
|
|
MAX_RETRIES: 3,
|
|
MIN_SOL_FOR_GAS: 0.1,
|
|
};
|
|
|
|
jest.mock("../../src/utils/config", () => mockInternalConfig);
|
|
|
|
jest.mock("@meteora-ag/dlmm");
|
|
jest.mock("@solana/web3.js", () => ({
|
|
...jest.requireActual("@solana/web3.js"),
|
|
sendAndConfirmTransaction: jest.fn(),
|
|
}));
|
|
jest.mock("../../src/utils/logger", () => ({
|
|
info: jest.fn(),
|
|
error: jest.fn(),
|
|
debug: jest.fn(),
|
|
warn: jest.fn(),
|
|
}));
|
|
|
|
import { MeteoraWrapper } from "../../src/meteora";
|
|
import DLMM from "@meteora-ag/dlmm";
|
|
import { sendAndConfirmTransaction } from "@solana/web3.js";
|
|
import logger from "../../src/utils/logger";
|
|
|
|
describe("MeteoraWrapper", () => {
|
|
let wrapper: MeteoraWrapper;
|
|
let mockDlmm: any;
|
|
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
wrapper = new MeteoraWrapper();
|
|
mockDlmm = {
|
|
getActiveBin: jest.fn(),
|
|
getPositionsByUserAndLbPair: jest.fn(),
|
|
removeLiquidity: jest.fn(),
|
|
initializePositionAndAddLiquidityByStrategy: jest.fn(),
|
|
claimAllRewardsByPosition: jest.fn(),
|
|
tokenX: { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } },
|
|
tokenY: { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } },
|
|
};
|
|
(DLMM.create as jest.Mock).mockResolvedValue(mockDlmm);
|
|
await wrapper.init();
|
|
});
|
|
|
|
it("should get active bin", async () => {
|
|
mockDlmm.getActiveBin.mockResolvedValue({ binId: 100 });
|
|
const bin = await wrapper.getActiveBin();
|
|
expect(bin.binId).toBe(100);
|
|
});
|
|
|
|
it("should withdraw all liquidity from positions", async () => {
|
|
const mockPosition = {
|
|
publicKey: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ"),
|
|
positionData: { lowerBinId: 90, upperBinId: 110 },
|
|
};
|
|
mockDlmm.getPositionsByUserAndLbPair.mockResolvedValue({
|
|
userPositions: [mockPosition],
|
|
});
|
|
mockDlmm.removeLiquidity.mockResolvedValue([{}]);
|
|
(sendAndConfirmTransaction as jest.Mock).mockResolvedValue("txHash");
|
|
|
|
await wrapper.withdrawAll();
|
|
|
|
expect(mockDlmm.removeLiquidity).toHaveBeenCalled();
|
|
expect(sendAndConfirmTransaction).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should deposit liquidity", async () => {
|
|
mockDlmm.initializePositionAndAddLiquidityByStrategy.mockResolvedValue({});
|
|
(sendAndConfirmTransaction as jest.Mock).mockResolvedValue("txHash");
|
|
|
|
await wrapper.deposit(
|
|
new BN(100),
|
|
new BN(100),
|
|
100
|
|
);
|
|
|
|
expect(
|
|
mockDlmm.initializePositionAndAddLiquidityByStrategy
|
|
).toHaveBeenCalled();
|
|
expect(sendAndConfirmTransaction).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should skip transactions in DRY_RUN mode", async () => {
|
|
mockInternalConfig.DRY_RUN = true;
|
|
|
|
mockDlmm.initializePositionAndAddLiquidityByStrategy.mockResolvedValue({});
|
|
|
|
await wrapper.deposit(
|
|
new BN(100),
|
|
new BN(100),
|
|
100
|
|
);
|
|
|
|
expect(sendAndConfirmTransaction).not.toHaveBeenCalled();
|
|
expect(logger.info).toHaveBeenCalledWith(
|
|
expect.stringContaining("[DRY RUN]")
|
|
);
|
|
|
|
mockInternalConfig.DRY_RUN = false; // Reset
|
|
});
|
|
|
|
it("should get token balances", async () => {
|
|
mockDlmm.tokenX = { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } };
|
|
mockDlmm.tokenY = { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } };
|
|
|
|
const balances = await wrapper.getBalances();
|
|
expect(balances).toBeDefined();
|
|
});
|
|
|
|
it("should log deposit details", async () => {
|
|
mockDlmm.initializePositionAndAddLiquidityByStrategy.mockResolvedValue({});
|
|
mockDlmm.tokenX = { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } };
|
|
mockDlmm.tokenY = { mint: { address: new PublicKey("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ") } };
|
|
(sendAndConfirmTransaction as jest.Mock).mockResolvedValue("txHash");
|
|
|
|
await wrapper.deposit(new BN(100), new BN(100), 100);
|
|
|
|
expect(logger.info).toHaveBeenCalledWith(
|
|
expect.stringContaining("Depositing liquidity")
|
|
);
|
|
});
|
|
});
|