haedal-hawal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHaedal haWAL
Haedal haWAL
Haedal Protocol is a DeFi ecosystem on the SUI blockchain. haWAL is its liquid staking token (LST) for WAL: stake WAL to receive haWAL, earn staking rewards, and optionally choose validators. This skill calls the Haedal Skills API to perform stake, withdraw, instant withdraw, and claim operations via curl — no custom scripts required.
Call the haWAL HTTP APIs directly with curl.
All numeric parameters are human‑readable amounts: pass and similar quantity fields as human‑readable values, without multiplying by decimals. For example, to stake 20 tokens, simply send .
amount"amount":"20"Haedal Protocol是SUI区块链上的DeFi生态系统。haWAL是其针对WAL的流动性质押代币(LST):质押WAL即可获得haWAL,赚取质押奖励,还可选择验证节点。本技能通过curl调用Haedal Skills API来执行质押、提取、即时提取和领取奖励操作——无需自定义脚本。
直接使用curl调用haWAL HTTP接口。
所有数值参数均为人类可读金额:将及类似数量字段以人类可读值传入,无需乘以小数位数。例如,要质押20个代币,只需传入。
amount"amount":"20"Validator when staking
质押时的验证节点设置
Only the stake method requires a (validator node ):
validatornode_id- Passing means "use the default validator".
0x0 - If the user does not provide a validator: show a reference list of validators and let the user choose. The user can respond with index 1–10 or the validator name. Map this to the corresponding from the table and include it in the request.
node_id - The reference list is defined in (mapping between name and node_id, indexed 1–10).
references/validators.md
Typical flow: the user says "stake hawal" without specifying a validator → present 10 reference validators (index + name) → the user replies with "1" or "Nansen", etc. → use the corresponding to call stake.
node_id只有stake方法需要传入(验证节点的):
validatornode_id- 传入****表示“使用默认验证节点”。
0x0 - 如果用户未提供验证节点:展示验证节点参考列表供用户选择。用户可回复1-10的索引或验证节点名称。将其与表格中对应的映射后加入请求。
node_id - 参考列表定义在中(名称与node_id的映射,索引1-10)。
references/validators.md
典型流程:用户说“stake hawal”但未指定验证节点 → 展示10个参考验证节点(索引+名称) → 用户回复“1”或“Nansen”等 → 使用对应的调用质押接口。
node_idClaiming rewards and NFTObj
领取奖励与NFTObj
The claim endpoint requires address and NFTObj (the NFT object ID that holds the rewards). When the user says "claim hawal rewards":
- Ask the user whether they want help finding the object id (if the user already knows the NFTObj, you can send it directly).
- If discovery is needed: call get_unstake_tickets_list with the user . On HTTP 200 the response body is:
addressjson{ "list": [ { "objectId": "0x...", "type": "0x...::walstaking::UnstakeTicket", "version": "...", "fields": { "claim_epoch": 27, "claim_timestamp_ms": "1774364404744", "hawal_amount": "700000000000", "id": { "id": "0x..." }, "unstake_timestamp_ms": "1772871784320", "wal_amount": "700635659164" } } ] } - Present the list to the user in a readable format — show key fields such as ,
objectId,hawal_amount,wal_amount,claim_epochfor each entry.claim_timestamp_ms - If there are multiple entries in the list: let the user choose which one to claim (or take the first entry if only one exists) and use that entry's as NFTObj.
objectId - Then call claim: with body
POST /api/v1/hawal/claim.{"address":"0x...","NFTObj":"<objectId from previous step>"}
Flow summary: the user says "claim hawal rewards" → ask whether to discover the object id → if yes, call get_unstake_tickets_list(address) → present the list with key details → user selects one → take the chosen as NFTObj → call claim(address, NFTObj).
objectIdclaim接口需要address和NFTObj(存储奖励的NFT对象ID)。当用户说“claim hawal rewards”时:
- 询问用户是否需要帮助查找对象ID(如果用户已知NFTObj,可直接传入)。
- 若需要查找:调用get_unstake_tickets_list接口并传入用户。HTTP 200响应体如下:
addressjson{ "list": [ { "objectId": "0x...", "type": "0x...::walstaking::UnstakeTicket", "version": "...", "fields": { "claim_epoch": 27, "claim_timestamp_ms": "1774364404744", "hawal_amount": "700000000000", "id": { "id": "0x..." }, "unstake_timestamp_ms": "1772871784320", "wal_amount": "700635659164" } } ] } - 以可读格式向用户展示列表——显示每个条目的关键字段,如、
objectId、hawal_amount、wal_amount、claim_epoch。claim_timestamp_ms - 若列表中有多个条目:让用户选择要领取的条目(若只有一个条目则直接使用),并将该条目的作为NFTObj。
objectId - 然后调用claim接口:,请求体为
POST /api/v1/hawal/claim。{"address":"0x...","NFTObj":"<上一步获取的objectId>"}
流程总结:用户说“claim hawal rewards” → 询问是否需要查找对象ID → 若是则调用get_unstake_tickets_list(address) → 展示带关键信息的列表 → 用户选择条目 → 取选中条目的作为NFTObj → 调用claim(address, NFTObj)。
objectIdBase URL
基础URL
https://skillsapi.haedal.xyz/api/v1/hawalhttps://skillsapi.haedal.xyz/api/v1/hawalRequest body
请求体
| Method | Required fields | Notes |
|---|---|---|
| stake | address, amount, validator | No object field |
| withdraw | address, amount | No object field |
| withdraw_instant | address, amount | No object field |
| claim | address, NFTObj | Requires NFT object ID, see the "Claiming rewards" flow above |
| get_unstake_tickets_list | address | Query the UnstakeTicket list for this address to obtain NFTObj |
| 方法 | 必填字段 | 说明 |
|---|---|---|
| stake | address, amount, validator | 无object字段 |
| withdraw | address, amount | 无object字段 |
| withdraw_instant | address, amount | 无object字段 |
| claim | address, NFTObj | 需要NFT对象ID,详见上方“领取奖励”流程 |
| get_unstake_tickets_list | address | 查询该地址的UnstakeTicket列表以获取NFTObj |
curl examples
curl示例
stake
Pass as to use the default validator, or use a node_id from (user can choose by index 1–10 or by name).
validator0x0references/validators.mdbash
undefined质押
传入为即可使用默认验证节点,也可使用中的node_id(用户可通过1-10的索引或名称选择)。
validator0x0references/validators.mdbash
undefinedUse the default validator
使用默认验证节点
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
Or specify an explicit validator node_id (for example Nansen)
或指定明确的验证节点node_id(例如Nansen)
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x7b3ba6de2ae58283f60d5b8dc04bb9e90e4796b3b2e0dea75569f491275242e7"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x7b3ba6de2ae58283f60d5b8dc04bb9e90e4796b3b2e0dea75569f491275242e7"}'
**withdraw**
```bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/withdraw" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'withdraw_instant
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/withdraw_instant" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'get_unstake_tickets_list (query the UnstakeTicket list that can be claimed, used to obtain NFTObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/get_unstake_tickets_list" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS"}'When the response status is 200, the body contains . Present key fields (, , , , ) to the user, then use the selected as the NFTObj for the claim call.
{"list":[{"objectId":"...","type":"...","version":"...","fields":{...}}, ...]}objectIdhawal_amountwal_amountclaim_epochclaim_timestamp_mslist[].objectIdclaim (requires NFTObj, which can be obtained from get_unstake_tickets_list → list[].objectId)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/claim" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","NFTObj":"0xOBJECT_ID_FROM_LIST"}'curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x7b3ba6de2ae58283f60d5b8dc04bb9e90e4796b3b2e0dea75569f491275242e7"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x7b3ba6de2ae58283f60d5b8dc04bb9e90e4796b3b2e0dea75569f491275242e7"}'
**提取**
```bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/withdraw" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'即时提取
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/withdraw_instant" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'get_unstake_tickets_list(查询可领取的UnstakeTicket列表,用于获取NFTObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/get_unstake_tickets_list" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS"}'响应状态为200时,响应体包含;使用获取列表。每个条目的包含、、、、。将选中条目的作为claim接口的NFTObj。
{"list":[{"objectId":"...","type":"...","version":"...","fields":{...}}, ...]}jq -r '.list'fieldshawal_amountwal_amountclaim_epochclaim_timestamp_msunstake_timestamp_msobjectIdclaim(需要NFTObj,可从get_unstake_tickets_list的list[].objectId获取)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hawal/claim" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","NFTObj":"0xOBJECT_ID_FROM_LIST"}'Response
响应
- stake / withdraw / withdraw_instant / claim: on HTTP 200, the body is ; use
{"txBytes":"<base64>"}to extract it. On non‑200, usejq -r '.txBytes'to return the error reason to the user.jq -r '.msg' - get_unstake_tickets_list: on HTTP 200, the body is ; use
{"list":[{"objectId","type","version","fields":{...}}, ...]}to obtain the list. Each entry'sjq -r '.list'containsfields,hawal_amount,wal_amount,claim_epoch,claim_timestamp_ms. Take the desired entry'sunstake_timestamp_msas the NFTObj for claim.objectId
- stake / withdraw / withdraw_instant / claim:HTTP 200响应体为;使用
{"txBytes":"<base64>"}提取。非200响应时,使用jq -r '.txBytes'将错误原因返回给用户。jq -r '.msg' - get_unstake_tickets_list:HTTP 200响应体为;使用
{"list":[{"objectId","type","version","fields":{...}}, ...]}获取列表。每个条目的jq -r '.list'包含fields、hawal_amount、wal_amount、claim_epoch、claim_timestamp_ms。将目标条目的unstake_timestamp_ms作为claim接口的NFTObj。objectId
MoveAbort error codes
MoveAbort错误码
When a dry-run or build call fails with , use the following mapping:
MoveAbort(..., <code>)| Code | Constant Name | Description |
|---|---|---|
| 1 | | Data version does not match the current program version |
| 2 | | Stake amount is below the minimum staking threshold (1 WAL) |
| 3 | | Calculated haWAL mint amount is zero |
| 4 | | Unstake ticket is still locked (claim epoch/time not reached) |
| 5 | | Unstake WAL amount exceeds total available WAL |
| 6 | | Unstake input haWAL amount must not be zero |
| 7 | | Staking is currently paused |
| 8 | | Unstaking is currently paused |
| 9 | | Unstake process failed: remaining |
| 10 | | Claim is currently paused |
| 11 | | Provided validator count does not match existing validator count |
| 12 | | Validator not found in the validator list |
| 13 | | No active validators found for staking |
| 14 | | Unstake timestamp is out of the valid epoch time range |
| 15 | | Active validators list is empty |
| 16 | | Unstake WAL amount is below the minimum staking threshold |
当预执行或构建调用返回时,使用以下映射关系:
MoveAbort(..., <code>)| 错误码 | 常量名称 | 描述 |
|---|---|---|
| 1 | | 数据版本与当前程序版本不匹配 |
| 2 | | 质押金额低于最低质押阈值(1 WAL) |
| 3 | | 计算出的haWAL铸造量为零 |
| 4 | | 提取票据仍处于锁定状态(未到领取周期/时间) |
| 5 | | 提取WAL金额超过可用WAL总额 |
| 6 | | 提取输入的haWAL金额不能为零 |
| 7 | | 当前质押功能已暂停 |
| 8 | | 当前提取功能已暂停 |
| 9 | | 提取流程失败:剩余 |
| 10 | | 当前领取奖励功能已暂停 |
| 11 | | 提供的验证节点数量与现有验证节点数量不匹配 |
| 12 | | 在验证节点列表中未找到指定节点 |
| 13 | | 未找到可用于质押的活跃验证节点 |
| 14 | | 提取时间戳超出有效周期时间范围 |
| 15 | | 活跃验证节点列表为空 |
| 16 | | 提取WAL金额低于最低提取阈值 |