Skip to main content

Command Palette

Search for a command to run...

DeepBook: Placing Orders & Swap EP 3

Continue from the previous episode — execute limit and market orders, cancel orders, and perform swaps on DeepBook

Updated
3 min read
DeepBook: Placing Orders & Swap EP 3

กลับมาตามสัญญากับ EP สุดท้ายสำหรับ ซีรีย์ DeepBook ใครยังไม่ได้ตาม EP ก่อนหน้า เบรคไว้ตรงนี้ก่อนเลย ไปอ่านกันนะ ไม่งั่นทำไม่ได้นะเออ

ก่อนหน้านี้เราได้เรียนรู้วิธีการ Create balance manager, Deposit, Check balance และ Withdraw ไปแล้วใช่ไหม มาวันนี้ได้เวลาละกับการวาง Order ซึ่งง่ายมากเมื่อทำผ่าน SDK พร้อมละเริ่มกันเลย


  1. Create limit order

    เริ่มจากเตรียมข้อมูลต่างๆก่อน ซึ่งก็เหมือนครั้งที่แล้วเลย

     import "dotenv/config";
     import { deepbook, type BalanceManager } from "@mysten/deepbook-v3";
     import { SuiGrpcClient } from "@mysten/sui/grpc";
     import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";
     import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
     import { Transaction } from "@mysten/sui/transactions";
    
     const env = (process.env.NETWORK ?? "testnet") as "testnet" | "mainnet";
     const { scheme, secretKey } = decodeSuiPrivateKey(process.env.SUI_PRIVATE_KEY!);
     if (scheme !== "ED25519") throw new Error(`Unsupported scheme: ${scheme}`);
     const keypair = Ed25519Keypair.fromSecretKey(secretKey);
     const address = keypair.toSuiAddress();
    
     const BALANCE_MANAGER_KEY = "BM1";
     const BALANCE_MANAGER_ID = "0x09921a24e9fe239b194a109ed8b8812f86fefc3389f851c4d06f7e55bef79a9f";
     const balanceManagers: { [k: string]: BalanceManager } = {
       [BALANCE_MANAGER_KEY]: { address: BALANCE_MANAGER_ID },
     };
     const client = new SuiGrpcClient({
       network: env,
       baseUrl: env === "mainnet" ? "https://fullnode.mainnet.sui.io:443" : "https://fullnode.testnet.sui.io:443",
     }).$extend(
       deepbook({
         address,
         balanceManagers,
       }),
     );
     const POOL_KEY = "SUI_DBUSDC";
    

    ทำการตรวจสอบ Bid และ Ask order ว่ามีการวางคำสั่งซื้อขายที่ราคาเท่าไหร่

     //Query Bid, Ask order
     const bids = await client.deepbook.getLevel2Range(POOL_KEY, 0.9, 0.91, true);
     const asks = await client.deepbook.getLevel2Range(POOL_KEY, 0.91, 0.95, false);
    
     console.log("=== BIDS Order ===");
     console.dir(bids, { depth: null });
    
     console.log("=== ASKS Order ===");
     console.dir(asks, { depth: null });
    

    ซึ่งเราจะเรียกผ่าน getLevel2Range นั้นเอง ซึ่งสิ่งที่เราต้องใช้เพื่อเรียกดูข้อมูลคือ Pool ที่เราต้องการเรียกดูข้อมูล เเละช่วงของราคาซึ่งจะเป็น ช่วงที่ต่ำสุดเเละสูงที่สุด รวมถึง Boolean ซึ่งจะบ่งบอกว่าจะดึงข้อมูลฝั่งไหนระหว่าง Bid หรือ Ask เมื่อเราทราบช่วงราคาเเล้ว หรือจะไม่ต้องสนใจก็ได้เผื่อใครอยากวางช้อนซื้อลึกๆ หรือขายสูง ก็ปล่อยผ่านไปเลย

    ขั้นตอนต่อเราก็ต้องสร้างคำสั่งขาย SUI ของเรา ด้วยวิธีการตามด้านล่างนี้

     //Check SUI Balance
     const suiInManager = await client.deepbook.checkManagerBalance(BALANCE_MANAGER_KEY, "SUI");
     console.log("SUI in manager =", suiInManager);
    
     const tx = new Transaction();
    
     const expireTimestamp = Date.now() + 60 * 60 * 1000; //1 HR
     //Verify check if an order can be placed
     const checkCanPlaceOrder = await client.deepbook.canPlaceLimitOrder({
       poolKey: "SUI_DBUSDC",
       balanceManagerKey: "BM1",
       price: 1,
       quantity: 1.0,
       isBid: false, // false = sell
       payWithDeep: false, //Pay 
       expireTimestamp,
     });
     console.log("canPlaceLimitOrder = ", checkCanPlaceOrder);
    
     tx.add(
       client.deepbook.deepBook.placeLimitOrder({
         poolKey: "SUI_DBUSDC",
         balanceManagerKey: "BM1",
         clientOrderId: `${Date.now()}`,
         price: 1,
         quantity: 5.0,
         isBid: false,
         payWithDeep: false,
       }),
     );
    
     const res = await client.core.signAndExecuteTransaction({
       transaction: tx,
       signer: keypair,
       include: { effects: true, objectTypes: true },
     });
    
     //Get account information
     let acct = await client.deepbook.account(POOL_KEY, BALANCE_MANAGER_KEY);
     console.log("=== ACCOUNT (available/locked) ===");
     console.dir(acct);
    

    จากตัวอย่างนี้เราจะเริ่มจากตรวจก่อนว่าเราสามารถวาง Order ได้ไหม เช่นถ้าเรามี SUI ไม่พอใน Balance Manager ก็จะไม่สามารถวาง Order ได้นั้นเอง เเละขั้นตอนสุดท้ายเราจะเรียกดูของมูลของเราขึ้นมา ซึ่งนึงที่จะได้คือ Order ID นั้นเอง โดย Order ID ห้ามซ้ำนะ เราเลยใช้ timestamp เลย ส่วน payWithDeep คือใช้ DEEP Token จ่ายเป็นค่าธรรมเนียมซึ่งเราไม่มีเลยใช้ SUI จ่ายแทน

    ง่ายไหม เราวาง Order ได้เรียบร้อยแล้วก็รอให้ Order ของเราถูก Match ก็เรียบร้อย

  2. Cancel order

    การยกเลิก Order นั้นสามารถทำผ่าน SDK ได้เลยครับ มีตั้งแต่คำสั่งยกเลิกทีละ Order หรือยกเลิกทั้งหมดก็ได้ วิธีการก็มีดังนี้

     const cancelTx = new Transaction();
     cancelTx.add(client.deepbook.deepBook.cancelAllOrders(POOL_KEY, BALANCE_MANAGER_KEY));
    
     const resCancelOrder = await client.core.signAndExecuteTransaction({
       transaction: cancelTx,
       signer: keypair,
       include: { effects: true, objectTypes: true },
     });
    

    ถ้าหากเราต้องการยกเลิกทีละ Order ก็เปลี่ยนไปใช้งานฟังก์ชั่น cancelOrder หรือ cancelOrders นะ โดยเราสามารถนำ Order ID จากขั้นตอนที่แล้วมาใช้ได้เลย หลังจากนั้นลองเรียก deepbook.account ดูนะว่า Order ของเราได้ถูกยกเลิกไปหรือไม่

  3. Market order

    มีวาง Limit ไปแล้วก็ขาดเรื่องการวางเเบบ Market order ไม่ได้ ซึ่งเราได้อธิบายไปตั้งแต่ EP แรกเเล้วว่าขั้นตอนการทำงานของ Market order เป็นยังไง ลองดูนะ วิธิการก็ง่ายอีกเช่นกัน

     tx.add(
       client.deepbook.deepBook.placeMarketOrder({
         poolKey: POOL_KEY,
         balanceManagerKey: BALANCE_MANAGER_KEY,
         clientOrderId: `${Date.now()}`,
         quantity:1,
         isBid: false,
         payWithDeep: false,
       }),
     );
    

    ในกรณีตัวอย่างข้างต้นคือขาย SUI แบบ Market order เป็นจำนวน 1 SUI

  4. Swap token

    ส่วนนี้จะต่างจากการวาง Order นะ ซึ่งจำได้ไหมจาก EP ที่เเล้วเราต้องเริ่มจาก Deposit เงินที่ต้องการเทรดลงไปใน Balance manager จึงจะสามารถทำการสร้าง Order ได้ แต่กรณีของ Swap นั้นจะเเตกต่างกัน เพราะมีให้เลือกว่าจะใช้หรือไม่ใช้ ถ้าไม่ใช้ก็จะเป็นการ Swap โดยดูจาก token ที่อยู่ใน Wallet เราได้เลย ถ้าใครเคยใช้งานพวก Uniswap ก็น่าจะคุ้นเคยดี โดย DeepBook ได้คำสั่งสำหรับการ Swap ทั้งหมดดังนี้

    • swapExactBaseForQuote ระบุจำนวน Base token ที่ต้องการขาย แล้วระบบจะคำนวณให้ว่าได้ Quote เท่าไหร่

    • swapExactQuoteForBase ระบุจำนวน Quote token ที่ต้องการใช้ซื้อ แล้วระบบจะคำนวณว่าได้ Base เท่าไหร่

    • swapExactQuantity ใช้สำหรับ swap จำนวนที่กำหนด (exact quantity) ได้ทั้งสองทิศทาง

    • swapExactBaseForQuoteWithManager, swapExactQuoteForBaseWithManager, swapExactQuantityWithManager เหมือน ข้างบนแต่ใช้จาก Balance Manager

ซึ่งแน่นอนเราจะไม่ใช้จาก Balance Manager มาดูวิธีกันเลย

    const swapTx = new Transaction();

    const [baseOut, quoteOut, deepOut] = client.deepbook.deepBook.swapExactBaseForQuote({
        poolKey: "SUI_DBUSDC",
        amount: 1,       
        deepAmount: 1,  
        minOut: 0.5   
    })(swapTx);
    swapTx.transferObjects([baseOut, quoteOut, deepOut], keypair.toSuiAddress());

    const swapRes = await client.core.signAndExecuteTransaction({
        transaction: swapTx,
        signer: keypair,
        include: { effects: true, events: true, objectTypes: true },
    });
    console.log("=== SWAP RESULT ===");
    console.dir(swapRes, { depth: null });

จากตัวอย่างก็คือเราจะ SWAP 1 SUI ไปเป็น DBUSDC นั้นเอง แต่จะมีปัญหา เพราะว่า…เราไม่มี DEEP Token ใช้ไหม วิธีการก็ไม่ยากลองเอาทั้งหมดที่เรียนรู้มาลองดูนะ ไบ้ให้ว่าก็ทำลองทำพวก Market order แล้วถอนออกมายังกระเป๋าของเราเอง เราก็จะได้ DEEP Token สำหรับจ่ายค่าธรรมเนียมแล้ว

เป็นไงหวังว่าจะเห็นภาพรวมทั้งหมดนะ สมัยนี้อะไรๆก็ Build ง่ายยย เพราะเครื่องมือไม้เครื่องมือพร้อมไปหมดละ เเละถ้าใครคันมือลองไปลองไปประลองฝีมือได้ที่นี้ https://x.com/SuiNetwork/status/2021269860211400801 นะกับโครงการ DeFi Moonshoot ซึ่งมี incentive ให้สูงถึง $500k ด้วยกัน

เอาละไว้เจอกันในบทความหน้า เอาเรื่องอะไรดี เเล้วก็อย่าลืมมาเรียนกันนะกับ กับโครงการ ON THE MOVE: Getting Started with Move on Sui

สมัครเลยที่นี้จ้า https://luma.com/j743avm7

มากินหมูสะเต๊ะกัน

เจอกันนะ