DeepBook: Understanding BalanceManager EP 2
Create, fund, monitor, and withdraw from your on-chain trading account

ขอโทษที่ล่าช้าครับ เริ่มไม่มั่นใจละว่าที่ลงช้า เพราะ ป่วย หรืองานเยอะ จนขี้เกียจ หรือป่วยการเมือง เเต่มาช้าก็มานะ วันนี้เราจะมาตามสัญญา ถึงเวลาลงมือเขียนโค๊ดกันเเหละ โดยเราจะเริ่มกันที่ Balance Manager ก่อน ทบทวนกันอีกนิด จากบทความที่แล้ว อย่าลืมไปอ่านกันก่อนนะ จะได้เข้าใจว่า Balance Manager คืออะไร
พร้อมแล้วก็มาเริ่มกันเลย
Create project and setup configuration
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 ได้นะครับ และเราแนะนำให้เเยกกระเป๋าที่ใช้ทดสอบกับกระเป๋าส่วนตัวนะ จะได้ไม่พลาด
SUI_PRIVATE_KEY=suiprivkeyxxxxx NETWORK=testnetเราจะทดสอบกันที่ Testnet อย่าลืมไปขอ Faucet SUI testnet token ด้วยนะ เพราะนอกจากจะต้องใช้เพื่อจ่ายค่าทำธุรกรรมแล้ว เราจะต้องใช้เพื่อฝากเข้าไปยัง BalanceManager ด้วย
Create Balance Manager
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 นั้นเอง
และตัวอย่างของเราจะได้เป็นเเบบนี้
'0x09921a24e9fe239b194a109ed8b8812f86fefc3389f851c4d06f7e55bef79a9f': '0xfb28c4cbc6865bd1c897d26aecbe1f8792d1509a20ffec692c800660cbec6982::balance_manager::BalanceManager'
Deposit SUI into Balance Manager
หลังจากที่เราสร้าง Balance Manager เรียบร้อยแล้ว เราก็จะต้องทำการฝาก SUI testnet token เข้าไปยัง Balance MAnager ของเรา จริงๆมีหลายเหรียญให้ใช้ทดสอบ เช่น DEEP, WAL เพียงแต่มันจะวุ่นวายหน่อย เพราะหา testnet token ลำบากเลยใช้ SUI testnet token ไปเลย ง่ายดี
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/ ได้นะ แต่อย่าลืมเปลี่ยจาก Mainnet เป็น Testnet ด้วยนะ
Read pool balance and Withdraw
เมื่อเราทำการฝากเงินเข้าไปแล้ว เราก็จะมาทดสอบ อ่านข้อมูลกันสักหน่อย ว่าตัวเลขถูกต้องใหม และทำการถอนเงินออกมาด้วยเลย
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
แล้วเจอกันนะครับ :)




