UNPKG

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
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); })