# DeepBook: Understanding BalanceManager EP 2

ขอโทษที่ล่าช้าครับ เริ่มไม่มั่นใจละว่าที่ลงช้า เพราะ ป่วย หรืองานเยอะ จนขี้เกียจ หรือป่วยการเมือง เเต่มาช้าก็มานะ วันนี้เราจะมาตามสัญญา ถึงเวลาลงมือเขียนโค๊ดกันเเหละ โดยเราจะเริ่มกันที่ Balance Manager ก่อน ทบทวนกันอีกนิด จากบทความที่แล้ว อย่าลืมไปอ่านกันก่อนนะ จะได้เข้าใจว่า Balance Manager คืออะไร

* [https://onthemove.contributiondao.com/deepbook-ep1](https://onthemove.contributiondao.com/deepbook-ep1)
    

พร้อมแล้วก็มาเริ่มกันเลย

---

1. **Create project and setup configuration**
    
    ```typescript
    mkdir deepbook-basic && cd deepbook-basic
    npm init -y
    npm i @mysten/sui @mysten/deepbook-v3 dotenv
    npm i -D typescript tsx @types/node
    ```
    
    สร้าง .env โดย private key สามารถไป export จาก Slush wallet ได้นะครับ และเราแนะนำให้เเยกกระเป๋าที่ใช้ทดสอบกับกระเป๋าส่วนตัวนะ จะได้ไม่พลาด
    
    ```typescript
    SUI_PRIVATE_KEY=suiprivkeyxxxxx
    NETWORK=testnet
    ```
    
    เราจะทดสอบกันที่ Testnet อย่าลืมไปขอ Faucet SUI testnet token ด้วยนะ เพราะนอกจากจะต้องใช้เพื่อจ่ายค่าทำธุรกรรมแล้ว เราจะต้องใช้เพื่อฝากเข้าไปยัง BalanceManager ด้วย
    
2. **Create Balance Manager**
    
    ```typescript
    import "dotenv/config";
    import { deepbook, type DeepBookClient } 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 client = new SuiGrpcClient({
      network: env,
      baseUrl: env === "mainnet" ? "https://fullnode.mainnet.sui.io:443" : "https://fullnode.testnet.sui.io:443",
    }).$extend(
      deepbook({
        address: keypair.toSuiAddress(),
      }),
    );
    
    const tx = new Transaction();
    tx.add(client.deepbook.balanceManager.createAndShareBalanceManager());
    
    const result = await client.core.signAndExecuteTransaction({
      transaction: tx,
      signer: keypair,
      include: { effects: true, objectTypes: true },
    });
    
    console.dir(result, { depth: null });
    ```
    
    ขั้นตอนนี้เราจะได้ `BalanceManager objectId` สำคัญให้เก็บเอาไว้นะครับ โดยการสร้าง Balance Manager จะมีทั้งหมด 3 ประเภทด้วยกันคือ
    
    * createAndShareBalanceManager สร้าง + เเชร์ ในขั้นตอนเดียว เอาไว้ใช้งานทั่วไป
        
    * createBalanceManagerWithOwner สร้างแบบ Private เอาไว้ควบคุมหรือเตรียม object ก่อนจะเเชร์ภายหลัง
        
    * shareBalanceManager เอาไว้เเชร์จากขั้นตอน createBalanceManagerWithOwner นั้นเอง
        
    
    และตัวอย่างของเราจะได้เป็นเเบบนี้
    
    ```plaintext
    '0x09921a24e9fe239b194a109ed8b8812f86fefc3389f851c4d06f7e55bef79a9f': '0xfb28c4cbc6865bd1c897d26aecbe1f8792d1509a20ffec692c800660cbec6982::balance_manager::BalanceManager'
    ```
    
3. **Deposit SUI into Balance Manager**
    
    หลังจากที่เราสร้าง Balance Manager เรียบร้อยแล้ว เราก็จะต้องทำการฝาก SUI testnet token เข้าไปยัง Balance MAnager ของเรา จริงๆมีหลายเหรียญให้ใช้ทดสอบ เช่น DEEP, WAL เพียงแต่มันจะวุ่นวายหน่อย เพราะหา testnet token ลำบากเลยใช้ SUI testnet token ไปเลย ง่ายดี
    
    ```typescript
    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 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: keypair.toSuiAddress(),
        balanceManagers,
      }),
    );
    const tx = new Transaction();
    tx.add(client.deepbook.balanceManager.depositIntoManager(BALANCE_MANAGER_KEY, "SUI", 0.5));
    
    const res = await client.core.signAndExecuteTransaction({
      transaction: tx,
      signer: keypair,
      include: { effects: true, objectTypes: true },
    });
    
    console.dir(res, { depth: null });
    ```
    
    สังเกตุไหมว่า BALANCE\_MANAGER\_ID คือค่าที่เราได้จาก step 2 นั้นเองส่วน BALANCE\_MANAGER\_KEY คือ ชื่อที่เราสามรถอะไรก็ได้ ไว้สำหรับ อ้างอิงไปยัง BalanceManager object ไหนบน chain เเละในขั้นตอนนี้เราจะฝาก 0.5 SUI testnet token นะครับ ขั้นตอนนี้เมื่อสำเร็จเราจะได้ digest ของ transaction ซึ่งสามารถนำไปเปิดดูผ่าน [https://suiscan.xyz/](https://suiscan.xyz/) ได้นะ แต่อย่าลืมเปลี่ยจาก Mainnet เป็น Testnet ด้วยนะ
    
4. **Read pool balance and Withdraw**
    
    เมื่อเราทำการฝากเงินเข้าไปแล้ว เราก็จะมาทดสอบ อ่านข้อมูลกันสักหน่อย ว่าตัวเลขถูกต้องใหม และทำการถอนเงินออกมาด้วยเลย
    
    ```typescript
    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 suiBalance = await client.deepbook.checkManagerBalance(BALANCE_MANAGER_KEY, "SUI");
    console.log("SUI in manager =", suiBalance);
    
    const tx = new Transaction();
    client.deepbook.balanceManager.withdrawAllFromManager(BALANCE_MANAGER_KEY, "SUI", address)(tx);
    
    const res = await client.core.signAndExecuteTransaction({
      transaction: tx,
      signer: keypair,
      include: { effects: true, objectTypes: true },
    });
    
    console.dir(res, { depth: null });
    ```
    
    ซึ่งผลลัพธ์ที่ได้นั้น เราจะเห็นว่ามีอยู่ 0.5 SUI testnet token และเมื่อเราสั่งถอน เเละลองทดสอบรันอีกรอบจะเหลือ 0 SUI testnet token ซึ่งถ้ามี 0 token เราจะไม่สามารถวางคำสั่งเพื่อขาย SUI ได้นะ เพราะเราไม่มีเงินเพียงพอที่จะทำขายนั้นเอง ตามที่เคยอธิบายไปแล้วในบล็อคก่อนหน้า (Funding account = 0)
    

---

เป็นไงบ้างง่ายใช้ไหม เท่านี้เราก็พร้อมเเล้วที่เตรียมจะไปขั้นตอนถัดไปคือ การวางคำสั่งซื้อเเละขายนั้นเอง เอาไว้ต่อกันตอนหน้านะ ซึ่งน่าจะเป็นตอนสุดท้ายละ คิดว่าจะพยายามเขียนให้จบก่อนวัน ศุกร์ นี้

และก่อนจะจบบทความ ขอประชาสัมพันธ์หน่อย ON THE MOVE จะมี MOVE Workshop เร็วๆนี้ที่ CONTRIBUTIONDAO Office นะครับ ใครอยากลองมานั่งเขียนโค๊ดร่วมกันมากันได้น๊าา มีของกินตลอดทั้งวัน :P

* [https://luma.com/j743avm7](https://luma.com/j743avm7)
    

แล้วเจอกันนะครับ :)
