Ủy quyền Agent
Hỗ trợ ký nhiều khóa cho nhà tạo lập thị trường.
Tổng quan
Ủy quyền agent cho phép một khóa ký chuyên dụng (agent) đặt và hủy lệnh thay mặt cho một ví giao dịch. Điều này hữu ích cho:
- Bảo mật: Giữ khóa ví giao dịch trong kho lạnh, sử dụng khóa nóng để ký
- Vận hành: Nhiều thành viên trong nhóm có thể ký bằng các khóa khác nhau
- Tự động hóa: Các hệ thống tự động có thể ký bằng khóa chuyên dụng
Hai mô hình ủy quyền
Hypercall có hai hệ thống ủy quyền riêng biệt tùy theo sản phẩm:
| Sản phẩm | Loại ủy quyền | Lưu trữ | Cách thiết lập |
|---|---|---|---|
| Quyền chọn (REST API) | Ủy quyền agent | Off-chain (cơ sở dữ liệu) | POST /approve-agent |
| Perps (chỉ thị on-chain) | Ví API | On-chain (hợp đồng Exchange) | Chỉ thị hc_update_api_wallet |
Đây là các hệ thống độc lập. Việc phê duyệt một agent cho giao dịch quyền chọn không ủy quyền cho agent đó giao dịch perps, và ngược lại.
Quyền chọn: Ủy quyền Agent (Off-Chain)
Agent ký các thông điệp EIP-712 PlaceOrder và CancelOrder thay mặt cho ví giao dịch. Máy chủ API xác minh ủy quyền dựa trên cơ sở dữ liệu của mình trước khi chuyển tiếp đến engine.
Perps: Ví API (On-Chain)
Ví API ký các chỉ thị perp bằng domain EIP-712 HypercallAgentSign. Hợp đồng Exchange xác minh ủy quyền on-chain thông qua isApiWalletActive(). Xem EIP-712 Signing để có tài liệu tham khảo đầy đủ về việc ký chỉ thị.
Để thêm hoặc xóa ví API, hãy gửi chỉ thị hc_update_api_wallet được ký bởi ví quản lý của tài khoản.
Điều này phản ánh mô hình ví API của Hyperliquid. Hyperliquid gọi đây là ví API, còn được gọi là ví agent, trong tài liệu Nonces and API wallets, và mô tả approveAgent trong Exchange endpoint.
Bảo vệ chống Replay Nonce
Theo dõi nonce tuân theo mô hình nonce của Hyperliquid. Tất cả các hành động đã ký (lệnh, phê duyệt/thu hồi agent, bắt tay QP) chia sẻ một không gian nonce theo từng người ký. Engine lưu trữ 100 nonce cao nhất cho mỗi địa chỉ người ký. Một nonce mới được chấp nhận nếu:
nonce > min(stored_set)-- phải lớn hơn nonce nhỏ nhất được lưu trữ!stored_set.contains(nonce)-- không được trùng lặpnoncenằm trong khoảng (T - 2 ngày, T + 1 ngày) so với dấu thời gian của máy chủ
Nonce không theo thứ tự vẫn được chấp nhận (ví dụ: nonce 105 rồi 102 đều hoạt động nếu cả hai đều lớn hơn giá trị nhỏ nhất trong tập hợp). Tập hợp bị giới hạn ở 100 mục, vì vậy các mục cũ nhất sẽ bị loại bỏ khi các mục mới được thêm vào. Điều này ngăn tài khoản bị khóa do một nonce quá lớn.
Người ký nonce là địa chỉ đã ký thông điệp EIP-712: ví API đối với lệnh, người ký được khôi phục đối với ủy quyền agent, ví QP đối với bắt tay. Client nên sử dụng Date.now() (epoch mili giây) làm giá trị khởi tạo nonce và tăng đơn điệu.
Ủy quyền Agent cho Quyền chọn
Ký trực tiếp
Nếu signer == wallet, lệnh luôn được ủy quyền (tự ký).
Ký bằng Agent
Nếu signer != wallet, người ký phải là một agent đã được ủy quyền:
- Agent phải có mặt trong trạng thái ủy quyền do engine sở hữu
- Ủy quyền không được hết hạn
- Snapshot của engine và nhật ký (journal) của engine là các nguồn khôi phục bền vững khi khởi động lại
Phê duyệt Agent
Endpoint: POST /approve-agent
Yêu cầu: ApproveAgentRequest
{
"agent": "0x...",
"nonce": 1,
"signature": "0x..."
}
Ký:
- Chủ sở hữu ví ký thông điệp
ApproveAgent - Ví được suy ra từ chữ ký được khôi phục
- Agent là trường
agenttrong yêu cầu
Cấu trúc EIP-712:
struct ApproveAgent {
address agent;
uint64 nonce;
}
Phản hồi: ApproveAgentResponse
{
"success": true,
"error": null
}
Ghi chú:
- Ủy quyền agent là bền vững (được lưu trong DB)
- Ủy quyền không hết hạn trừ khi
expires_atđược thiết lập (chưa được triển khai)
Thu hồi Agent
Endpoint: DELETE /revoke-agent
Yêu cầu: RevokeAgentRequest
{
"agent": "0x...",
"nonce": 2,
"signature": "0x..."
}
Ký:
- Chủ sở hữu ví ký thông điệp
RevokeAgent - Ví được suy ra từ chữ ký được khôi phục
Cấu trúc EIP-712:
struct RevokeAgent {
address agent;
uint64 nonce;
}
Phản hồi: RevokeAgentResponse
Ghi chú:
- Áp dụng lệnh
RevokeAgentđược ghi vào nhật ký lên trạng thái ủy quyền do engine sở hữu - Các kiểm tra ủy quyền của API giao dịch đọc trạng thái backend và thực thi việc thu hồi đối với các yêu cầu giao dịch. Việc đăng bài trên Trollbox có thể lưu cache ủy quyền agent tích cực lâu hơn, vì vậy một agent vừa bị thu hồi vẫn có thể đăng bài cho đến khi cache đó hết hạn hoặc việc vô hiệu hóa theo cơ chế best-effort đến được vị trí edge liên quan. Cache này không ủy quyền cho các thao tác thay đổi trên API giao dịch.
- Agent không thể ký cho ví sau khi bị thu hồi
Lấy danh sách Agent đã được ủy quyền
Endpoint: GET /authorized-agents?wallet=...
Tham số truy vấn:
wallet(bắt buộc)
Phản hồi:
{
"agents": [
"0x...",
"0x..."
]
}
Ghi chú:
- Chỉ trả về các agent đang hoạt động, chưa hết hạn
- Sắp xếp theo
created_at DESC
Sử dụng Agent
Ký lệnh bằng Agent
Sau khi agent được phê duyệt:
- Ký lệnh bằng ví agent: Sử dụng ví agent để ký các thông điệp
PlaceOrder/CancelOrder - Thiết lập trường wallet: Đặt trường
walletlà địa chỉ ví giao dịch (không phải địa chỉ agent) - Xác minh bởi middleware: Middleware xác minh agent đã được ủy quyền cho ví đó
Ví dụ:
// Agent wallet signs the order
const agentSigner = new ethers.Wallet(agentPrivateKey);
const message = {
wallet: "0x...", // Trading wallet (not agent)
symbol: "BTC-20250131-100000-C",
side: "Buy",
size: "0.1",
price: "100.0",
tif: "gtc",
clientId: "mm-1",
nonce: 1
};
// Sign with agent wallet
const signature = await agentSigner._signTypedData(domain, types, message);
// Send request
const response = await fetch('/order', {
method: 'POST',
body: JSON.stringify({
...message,
signature
})
});
Lệnh hàng loạt với Agent
Các endpoint hàng loạt xác minh ủy quyền agent theo từng mục:
- Mỗi lệnh trong
POST /bulk_ordercó thể được ký bởi một agent khác nhau - Ủy quyền agent được kiểm tra theo từng mục
- Nếu bất kỳ mục nào không vượt qua xác thực agent, mục đó sẽ trả về lỗi trong
BulkOrderResult
Các kiểm tra ủy quyền
Middleware (Lệnh đơn)
Endpoint:
POST /orderDELETE /orderDELETE /order_cloid
Kiểm tra: signature_and_agent_middleware xác minh:
- Khôi phục chữ ký thành công
- Người ký được ủy quyền (signer == wallet HOẶC agent đã được ủy quyền)
Handler (Lệnh hàng loạt)
Endpoint:
POST /bulk_orderDELETE /bulk_orderDELETE /bulk_order_cloid
Kiểm tra: Xác minh theo từng mục trong handler:
- Khôi phục chữ ký theo từng mục
- Kiểm tra ủy quyền agent theo từng mục
Lưu trữ ủy quyền
Ủy quyền agent là trạng thái do engine sở hữu. Các lệnh ApproveAgent và RevokeAgent được ghi vào nhật ký, được khôi phục thông qua cơ chế replay của engine, và được cung cấp qua snapshot đọc để phục vụ các kiểm tra của API.
Logic ủy quyền
Ủy quyền người ký là logic OR rõ ràng:
- Ký trực tiếp:
signer == wallet. - Ký bằng agent: snapshot của engine chứa một bản ghi ủy quyền cho
wallet_address == <wallet>vàagent_address == <signer>, vàexpires_atkhông tồn tại hoặc nằm trong tương lai.
Hết hạn
expires_at được thực thi bởi các kiểm tra ủy quyền của snapshot engine. Các agent có
expires_at < NOW() được coi là chưa được ủy quyền.
Cân nhắc về bảo mật
- Bảo mật khóa agent: Bảo vệ khóa riêng tư của agent (sử dụng ví phần cứng hoặc hệ thống quản lý khóa an toàn)
- Kiểm tra định kỳ: Xem xét các agent đã được ủy quyền thông qua
GET /authorized-agentsmột cách thường xuyên - Thu hồi các agent không sử dụng: Thu hồi các agent không còn cần thiết
- Hết hạn: Sử dụng
expires_atcho các ủy quyền agent tạm thời khi luồng phê duyệt cung cấp thời hạn hết hạn không mặc định
Thực hành tốt nhất
- Sử dụng agent cho tự động hóa: Giữ khóa ví giao dịch trong kho lạnh, sử dụng agent cho các hệ thống tự động
- Giới hạn phạm vi của agent: Chỉ phê duyệt các agent cần quyền truy cập
- Giám sát việc sử dụng agent: Theo dõi agent nào đang đặt lệnh
- Thu hồi kịp thời: Thu hồi agent ngay lập tức khi không còn cần thiết
Các vấn đề thường gặp
"Unauthorized: signer not authorized for wallet"
Nguyên nhân: Agent chưa được phê duyệt hoặc ủy quyền đã hết hạn/bị thu hồi.
Giải pháp: Phê duyệt agent qua POST /approve-agent hoặc ký trực tiếp bằng ví.
Ủy quyền Agent không hoạt động
Nguyên nhân:
- Agent không có mặt trong trạng thái ủy quyền do engine sở hữu
- Ủy quyền đã bị thu hồi
- Ủy quyền đã hết hạn
Giải pháp: Kiểm tra trạng thái agent qua GET /authorized-agents?wallet=....