Xây agent trading TON: đọc số dư, báo giá, swap phi lưu ký
Agent trading TON trên MCP: cách agent đọc số dư, lấy báo giá chắc chắn và dựng swap phi lưu ký — get_balance, get_swap_quote, build_swap_tx.
Vấn đề mà mọi agent trading trên TON đều vấp phải đầu tiên
Bạn bảo AI agent "swap 50 USDT sang GRAM khi giá giảm" — và nó gửi đi một giao dịch 50 000 USDT thay vì 50. Lý do: USDT trên TON có decimals = 6 (50 USDT = 50 000 000 đơn vị raw), còn agent thì mặc định tính như một jetton thông thường với chín số 0 — và thổi số tiền lên gấp 1000 lần. Sai lệch 1000 lần, tiền thật, giao dịch không thể đảo ngược. Lỗi ngược lại cũng cùng một gốc rễ: agent nhìn thấy giá trị raw 1000000000 trong số dư rồi dõng dạc báo cáo "bạn có một tỷ USDT", trong khi thực tế chỉ có 1000.
Đây không phải mấy chuyện hù dọa bịa ra, mà đúng là cái bẫy mà bất kỳ ai nối LLM thẳng vào DeFi trên TON qua RPC thô cũng giẫm phải: decimals lẫn lộn, không đọc nổi số dư jetton nếu chưa có địa chỉ jetton wallet, private key rò rỉ qua context. Dưới đây là cách dựng một agent trading TON (trading agent TON) biết đọc số dư, lấy báo giá chắc chắn và dựng swap mà không một lần chạm vào khóa của bạn. Công cụ: TONNode, MCP server hosted cho TON.
Agent trading trên TON là gì và tại sao nó cần MCP
Agent trading là một LLM (Claude, Cursor, Codex hay bất kỳ MCP client nào) biết đọc trạng thái mạng và chuẩn bị giao dịch theo yêu cầu của người dùng: "cho xem số dư USDT của tôi", "500 USDT đổi được bao nhiêu GRAM?", "dựng lệnh swap đi". Bản thân model không nhìn thấy blockchain — nó cần công cụ.
Và đó chính xác là việc của MCP (Model Context Protocol) — chuẩn để agent gọi các công cụ bên ngoài. Thay vì dạy model tự soạn request ADNL thô rồi parse cell BOC, bạn đưa cho nó một bộ hàm đã định kiểu: "lấy số dư", "lấy báo giá", "dựng giao dịch". TONNode cắm vào như nguồn cung cấp những công cụ đó và đưa cho agent đúng 16 hàm để làm việc với mạng: đọc dữ liệu, swap, cross-chain, tạo ví.
Agent trading chỉ cần năm hàm trong số đó, và cả năm đều dùng được ngay trên gói miễn phí:
đọc (get_balance, get_jetton_balance)
-> xác định decimals (get_jetton_info)
-> báo giá (get_swap_quote)
-> dựng swap (build_swap_tx)
-> ví ký qua TonConnect
Chi tiết mấu chốt ở bước cuối: người ký là ví của người dùng, không phải server. TONNode trả về các message chưa ký — vì sao đây là chuyện nguyên tắc, ta sẽ mổ xẻ ở cuối bài.
Bước 1: agent đọc số dư (get_balance, get_jetton_balance)
Trước khi swap bất cứ thứ gì, agent phải hiểu mình đang có gì trong tay. Hai công cụ:
get_balance— số dư GRAM trên một địa chỉ. GRAM chính là Toncoin được đổi tên hồi tháng 6/2026; bản thân mạng thì vẫn gọi là TON.get_jetton_balance— số dư jetton: USDT, NOT, hay bất kỳ token nào khác. Điều hay ho ở đây là địa chỉ jetton wallet được tính on-chain. Bạn truyền vào địa chỉ chủ sở hữu và địa chỉ master của jetton, còn TONNode tự suy ra địa chỉ jetton wallet rồi đọc số dư của nó. Không cần biết trước địa chỉ đó, cũng không cần lưu nó ở đâu cả.
Prompt cho agent trông đúng như thế này:
Kiểm tra số dư của ví UQAbc...xyz:
có bao nhiêu GRAM và bao nhiêu USDT?
Bên dưới, model gọi get_balance cho số dư native và get_jetton_balance cho USDT. Có một điều phiền toái: thứ trả về vẫn chưa phải con số "cho người đọc", mà là đơn vị raw. Và đây mới là chỗ quan trọng nhất. Về chuyện lấy số dư USDT chỉ bằng một lời gọi, khỏi phải vật lộn với địa chỉ jetton wallet, có bài phân tích riêng: /blog/usdt-balance-ton-one-call.
decimals quyết định tất cả: get_jetton_info và vì sao USDT = 6
Số dư và số tiền trên TON được lưu ở dạng đơn vị raw — số nguyên, không có phần thập phân. Muốn có con số người đọc được, bạn phải chia giá trị raw cho 10^decimals. Và đây là cái bẫy: mỗi jetton lại có số decimals khác nhau.
- USDT có
decimals = 6. Tức là1 USDT = 1 000 000đơn vị raw. - Đa số jetton trên TON có
decimals = 9(giống GRAM). Tức là1 jetton = 1 000 000 000đơn vị raw.
Nhầm 6 với 9 nghĩa là sai số tiền đúng 1000 lần. Chính là cái "một tỷ USDT" ở đầu bài. Với agent trading thì đây không phải chuyện làm đẹp, mà là gốc rễ của niềm tin: nếu nó nhầm bậc số thì không thể giao cho nó dựng giao dịch được.
Vì vậy ta gắn get_jetton_info vào pipeline — nó trả về metadata của jetton: tên, ký hiệu, tổng cung và — quan trọng nhất — decimals. Logic đúng bên trong agent là thế này:
raw = get_jetton_balance(...) // ví dụ, 1000000000
decimals = get_jetton_info(...) // với USDT → 6
human = raw / 10 ** decimals // 1000000000 / 1e6 = 1000 USDT
Vẫn giá trị raw đó, nhưng với decimals = 9 thì kết quả lại là 1 token — khác biệt một trời một vực. Đừng hardcode decimals vào prompt, cũng đừng để model "tự suy ra" theo trí nhớ: gặp jetton mới là nó sai. Hãy bắt nó kéo từ get_jetton_info mỗi lần và tính lại theo dữ liệu thật. Chi tiết về cái bẫy này và vì sao nó khiến người ta mất tiền thật: /blog/jetton-decimals-ton.
Bước 2: báo giá chắc chắn qua Omniston (get_swap_quote)
Số dư đã đọc xong và quy đổi đúng đơn vị — giờ agent cần giá. Trong DeFi, "giá áng chừng trong đầu" không dùng được: thanh khoản trải rộng trên nhiều DEX, tỷ giá thì chạy liên tục, và agent phải dựa vào báo giá thời điểm hiện tại chứ không phải phỏng đoán.
get_swap_quote đưa ra báo giá chắc chắn cho lệnh swap GRAM ⇄ jetton thông qua giao thức Omniston, vốn gộp thanh khoản của cả hai DEX lớn nhất TON — STON.fi và DeDust. Agent không phải tự đi hỏi từng pool, so giá rồi tính trượt giá: Omniston trả về tuyến tốt nhất từ khối thanh khoản đã hợp nhất.
Cho tôi báo giá: ngay bây giờ 50 USDT đổi được bao nhiêu GRAM?
Model gọi get_swap_quote với số tiền 50000000 (đúng cái đơn vị raw ở bước trước) và nhận về những con số cụ thể: đầu vào bao nhiêu, đầu ra bao nhiêu, đi theo tuyến nào, trượt giá bao nhiêu. Đây là điểm ra quyết định: nếu agent có điều kiện ("chỉ swap khi tỷ giá tốt hơn X"), nó so báo giá với ngưỡng rồi hoặc đi tiếp, hoặc chờ vòng lặp sau. Lưu ý: báo giá vẫn chưa phải giao dịch. Không đồng nào dịch chuyển, không có gì được ký. Đây thuần túy là đọc thị trường.
Bước 3: dựng lệnh swap chưa ký (build_swap_tx) và ký trong ví
Người dùng xem báo giá xong và nói "ok, swap đi". Agent gọi build_swap_tx và nhận về một giao dịch chưa ký cho lệnh swap, sẵn sàng đưa vào TonConnect.
Tôi muốn nhấn mạnh chữ "chưa ký". Server dựng ra một message hợp lệ — địa chỉ người nhận, payload, số tiền, tham số tuyến — rồi trả nguyên vẹn về. Sau đó message đi tiếp vào ví của người dùng (Tonkeeper, MyTonWallet, bất kỳ ví nào tương thích TonConnect), người dùng nhìn rõ mình đang ký cái gì và tự xác nhận. Chữ ký được tạo ra bằng private key của người dùng, thứ nằm trong ví của chính họ, chứ không phải trên server.
get_balance / get_jetton_balance → đọc xem đang có gì
↓
get_jetton_info → xác định decimals, tính lại
↓
get_swap_quote (Omniston) → báo giá chắc chắn
↓
build_swap_tx → giao dịch chưa ký
↓
ví của người dùng (TonConnect) → ký và gửi đi
Mỗi bước là một lời gọi công cụ tường minh, tách bạch. Agent không "tự tiện làm nốt" bất cứ điều gì với tiền: nó chuẩn bị, còn quyết định và chữ ký vẫn thuộc về con người. Kịch bản đầy đủ của một lệnh swap phi lưu ký, từ báo giá đến chữ ký, được mổ xẻ từng bước ở đây: /blog/agent-swap-ton-noncustodial.
Phi lưu ký: vì sao server không bao giờ giữ khóa của agent
Đây không phải câu chữ marketing, mà là một ranh giới kiến trúc. Ở TONNode, các công cụ swap, cross-chain và tạo ví là phi lưu ký một cách nghiêm ngặt:
- Server không bao giờ ký giao dịch.
- Server không bao giờ lưu private key và tiền.
- Tất cả những gì nó đưa ra ngoài chỉ là message TonConnect chưa ký.
Vì sao điều này lại quan trọng đúng với agent trading? Bởi vì theo định nghĩa, agent làm việc với tiền, và cũng theo định nghĩa, agent có thể sai — hiểu nhầm yêu cầu, nhầm số tiền, kẹt vòng lặp. Nếu khóa nằm trên server và server tự ký, thì một lỗi của agent đồng nghĩa với mất tiền mà bạn không hề hay biết. Trong mô hình phi lưu ký, phòng tuyến cuối cùng là bạn: không giao dịch nào rời đi trước khi ví của bạn xác nhận.
Hãy so sánh với @ton/mcp chính thức của TON Foundation — đó là một agent-wallet lưu ký: nó giữ operator-key và tự ký (sơ đồ split-key, trong đó operator-key nằm ở agent còn owner-key ở người dùng). Nó có thế mạnh riêng — chi tiêu tự động không cần con người tham gia, làm việc với NFT và DNS, vị thế chính thức của Foundation. Nhưng mô hình niềm tin thì khác: ở đó agent thực sự có thể dịch chuyển tiền. TONNode cố ý chọn ranh giới ngược lại: server không ký bất cứ thứ gì. So sánh chi tiết hai cách tiếp cận: /blog/custodial-vs-noncustodial-mcp.
Cách kết nối và bắt đầu trong 5 phút
Tin vui: để dựng pipeline trading, bạn không cần trả tiền. Nhưng đừng nhầm lẫn hai con đường miễn phí — bộ công cụ của chúng khác nhau.
Cấu hình public chạy local cho bạn trọn bộ công cụ đọc (8 công cụ: get_masterchain_info, get_balance, get_account_state, get_transactions, run_get_method, get_jetton_balance, parse_address, get_jetton_info). Cài qua npx, không cần key:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Package @tonnode/mcp là mã nguồn mở (MIT), nằm trên npm và GitHub (tonnode/mcp), chạy bằng giao thức ADNL native của TON, không chèn lớp HTTP nào giữa agent và mạng. Dán cấu hình vào Claude Desktop, Cursor hay bất kỳ MCP client nào — thế là agent đã biết đọc số dư và gọi get_jetton_info.
Còn bản thân phần báo giá — get_swap_quote và build_swap_tx — thuộc nhóm SWAP và đi qua endpoint hosted. Điểm mấu chốt: trên key miễn phí Hobby, bạn dùng được cả 16 công cụ, bao gồm cả báo giá lẫn dựng swap. Nghĩa là toàn bộ pipeline trading (đọc → báo giá → swap) có thể dựng miễn phí — nhưng là qua key hosted Hobby, chứ không phải qua cấu hình public chạy local. Cấu hình cho endpoint hosted:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
TONNode có đúng 16 công cụ, và mọi gói đều dùng được cả 16 — bạn chỉ trả tiền cho băng thông, không phải cho tính năng:
- Hobby — miễn phí vĩnh viễn, 60 request/phút, không cần thẻ.
- Pro — $29/tháng, 300 request/phút.
- Scale — $199/tháng, 1200 request/phút.
Để bắt đầu và chạy thử pipeline trading, key Hobby miễn phí là quá đủ: 60 request mỗi phút đủ cho rất nhiều lời gọi liên tiếp của agent. Không cần thẻ, key được cấp ngay sau khi đăng nhập.
Lấy key Hobby miễn phí (60 req/min, không cần thẻ): tonnode.io/dashboard?plan=hobby
Danh sách đầy đủ 16 công cụ: tonnode.io/mcp · Bảng giá: tonnode.io/pricing
Hãy dựng pipeline từ năm công cụ — get_balance, get_jetton_balance, get_jetton_info, get_swap_quote, build_swap_tx — giữ decimals trong tầm kiểm soát và giao chữ ký lại cho ví. Như vậy bạn sẽ có một agent trading đọc số dư một cách trung thực, lấy báo giá chắc chắn và chuẩn bị lệnh swap với số tiền thật, mà không một giây nào chạm được vào khóa của người khác. Agent trading trên TON đúng ra phải hoạt động như thế.
Cho agent của bạn quyền truy cập TON
16 công cụ MCP: đọc, swap phi lưu ký, cross-chain và ví. Gói miễn phí — 60 req/phút, không cần thẻ.