navi-sdk
Version:
The NAVI SDK Client provides tools for interacting with the Sui blockchain networks, designed for handling transactions, accounts, and smart contracts efficiently. This documentation covers the setup, account management, and transaction handling within th
518 lines (447 loc) • 16.2 kB
text/typescript
import { describe, it, expect } from "vitest";
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client";
import { buildSwapPTBFromQuote, swapPTB } from "../src/libs/Aggregator/swapPTB";
import { getQuote } from "../src/libs/Aggregator/getQuote";
import { Dex } from "../src/types";
import { createTransaction, handleTransactionResult } from "./helper";
import { account } from "./client";
const localBaseUrl = "http://localhost:8000/find_routes";
const coins = {
sui: {
address: "0x2::sui::SUI",
holder: "0x80841329787fd577639add61cc955ace969af60fadfb05b8ff752c2de4a8aa65"
},
vSui: {
address: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT",
holder: "0xb2630a7cdbe44adb2844b7715c7e6c54ec67e4558249deb71ba7b2df3c85915e"
},
haSui: {
address: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d::hasui::HASUI",
holder: "0xb2630a7cdbe44adb2844b7715c7e6c54ec67e4558249deb71ba7b2df3c85915e"
},
deep: {
address: "0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP",
holder: "0x60dd01bc037e2c1ea2aaf02187701f9f4453ba323338d2f2f521957065b0984d"
},
};
describe("swap test", () => {
it("should successfully swap SUI through cetus using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.vSui.address, amountIn, undefined, {
dexList: [Dex.CETUS],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap SUI through magma using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.vSui.address, amountIn, undefined, {
dexList: [Dex.MAGMA],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap SUI through turbos using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.vSui.address, amountIn, undefined, {
baseUrl: localBaseUrl,
dexList: [Dex.TURBOS],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap DEEP through deepbook using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.deep.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get DEEP coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.deep.holder,
coinType: coins.deep.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.deep.address, coins.sui.address, amountIn, undefined, {
baseUrl: localBaseUrl,
dexList: [Dex.DEEPBOOK],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.deep.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.deep.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap SUI through haSui stake using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.haSui.address, amountIn, undefined, {
baseUrl: localBaseUrl,
dexList: [Dex.HASUI],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap haSui through haSui unstake using single route", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.haSui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get haSui coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.haSui.holder,
coinType: coins.haSui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const coinInStructBalance = coinInStruct.data[0].balance;
const quote = await getQuote(coins.haSui.address, coins.sui.address, coinInStructBalance, undefined, {
baseUrl: localBaseUrl,
dexList: [Dex.HASUI],
byAmountIn: true,
depth: 3,
});
// Use actual haSui coin
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [coinInStructBalance]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.haSui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.haSui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap SUI through vSui stake anyway", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.vSui.address, amountIn, undefined, {
baseUrl: localBaseUrl,
dexList: [Dex.VSUI, Dex.CETUS],
byAmountIn: true,
depth: 3,
});
expect(quote.routes[0].path[0].provider).toEqual(Dex.VSUI);
// Use SUI coin
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true // ifPrint
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(txb, account, testCaseName, true);
expect(tsRes).toEqual("success");
}, 500000);
});
describe("fee options test", () => {
it("should successfully swap SUI through cetus using single route with fee", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
const quote = await getQuote(coins.sui.address, coins.vSui.address, amountIn, undefined, {
dexList: [Dex.CETUS],
byAmountIn: true,
depth: 3,
});
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.sui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true, // ifPrint
undefined,
{
serviceFee: {
fee: 0.5,
receiverAddress:
"0x3be8db6ca4adf33387f16c86c443737e78fd14db85a4e1c68cc8f256ac68549c", // random address
},
}
);
txb.transferObjects([coinOut], coins.sui.holder);
const tsRes = await handleTransactionResult(
txb,
account,
testCaseName,
true,
true
);
expect(tsRes).toEqual("success");
}, 500000);
it("should successfully swap vSUI through cetus using single route with fee", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.vSui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get vSUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.vSui.holder,
coinType: coins.vSui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const coinInStructBalance = coinInStruct.data[0].balance;
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [
coinInStructBalance,
]);
const quote = await getQuote(coins.vSui.address, coins.sui.address, coinInStructBalance, undefined, {
dexList: [Dex.CETUS],
byAmountIn: true,
depth: 3,
});
const minAmountOut = 0;
const coinOut = await buildSwapPTBFromQuote(
coins.vSui.holder,
txb,
minAmountOut,
coinIn,
quote,
0, // referral
true, // ifPrint
undefined,
{
serviceFee: {
fee: 0.5,
receiverAddress:
"0x3be8db6ca4adf33387f16c86c443737e78fd14db85a4e1c68cc8f256ac68549c", // random address
},
}
);
txb.transferObjects([coinOut], coins.vSui.holder);
const tsRes = await handleTransactionResult(
txb,
account,
testCaseName,
true,
true
);
expect(tsRes).toEqual("success");
}, 500000);
it("should swap PTB with fee options successfully", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
// Test sui to vSui swap
const fromCoin = coins.sui.address;
const toCoin = coins.vSui.address;
const minAmountOut = 0;
const swapOptions = {
dexList: [],
byAmountIn: true,
depth: 3,
feeOption: {
fee: 0.5,
receiverAddress:
"0x3be8db6ca4adf33387f16c86c443737e78fd14db85a4e1c68cc8f256ac68549c",
},
};
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
// Execute swap
const result = await swapPTB(
coins.sui.holder,
txb,
fromCoin,
toCoin,
coinIn,
amountIn,
minAmountOut,
undefined,
swapOptions
);
// Transfer result back to holder
txb.transferObjects([result], coins.sui.holder);
// Verify transaction succeeded
const txResult = await handleTransactionResult(
txb,
account,
testCaseName,
true,
true
);
expect(txResult).toEqual("success");
}, 500000);
it("should swap PTB with service fee options successfully", async () => {
const testCaseName = expect.getState().currentTestName || "test_case";
const txb = createTransaction(account, coins.sui.holder);
const suiClient = new SuiClient({ url: getFullnodeUrl("mainnet") });
// Get SUI coins owned by the holder
const coinInStruct = await suiClient.getCoins({
owner: coins.sui.holder,
coinType: coins.sui.address
});
const coinInStructObjectId = coinInStruct.data[0].coinObjectId;
const amountIn = "1000000000";
// Test sui to vSui swap
const fromCoin = coins.sui.address;
const toCoin = coins.vSui.address;
const minAmountOut = 0;
const swapOptions = {
dexList: [],
byAmountIn: true,
depth: 3,
serviceFee: {
fee: 0.5,
receiverAddress:
"0x3be8db6ca4adf33387f16c86c443737e78fd14db85a4e1c68cc8f256ac68549c",
},
};
const coinIn = txb.splitCoins(txb.object(coinInStructObjectId), [1e9]);
// Execute swap
const result = await swapPTB(
coins.sui.holder,
txb,
fromCoin,
toCoin,
coinIn,
amountIn,
minAmountOut,
undefined,
swapOptions
);
// Transfer result back to holder
txb.transferObjects([result], coins.sui.holder);
// Verify transaction succeeded
const txResult = await handleTransactionResult(
txb,
account,
testCaseName,
true,
true
);
expect(txResult).toEqual("success");
}, 500000);
})