okx-growth-competition
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOKX Growth Competition — Trading Competition
OKX成长竞赛 — 交易竞赛
Agentic Wallet exclusive trading competitions. Full lifecycle: list → detail → join → trade → rank → claim.
CLI reference:
references/cli-reference.mdAgentic Wallet专属交易竞赛。完整生命周期:列出→详情→参与→交易→排名→领取。
CLI参考文档:
references/cli-reference.mdFacts about every Agentic Wallet competition (always true unless backend confirms otherwise)
所有Agentic Wallet竞赛的通用规则(除非后端确认否则始终生效)
<MUST>
Treat the following as **factual ground truth** when the user asks about how a competition works. Do NOT infer otherwise from a single-chain `chainName` in `competition_detail` — that field currently only carries the primary EVM chain; the second chain is a hardcoded product invariant that backend has not yet split into a separate field.
</MUST>
- Every active competition runs simultaneously on Solana AND the chain returned by the backend (e.g. → activity runs on both X Layer and Solana). Solana is the hardcoded second chain on every activity.
chainName=X Layer - Trades on either chain count toward the same competition standing. A user trading on Solana for an X-Layer-titled competition is participating, not bystanding. Likewise EVM trades count for a Solana-titled competition. (When backend later returns a multi-chain field listing all supported chains, drop this hardcoding.)
- means the user has not yet hit the qualifying threshold or the backend metric pipeline has not picked up their trades yet — it does NOT mean the user's chain is unsupported. Never tell the user "your chain doesn't count" based on a
myRankInfo.userTotal = 0observation.userTotal=0 - The competition argument used in
--walletis the chain-appropriate address: SOL for Solana-primary activities, EVM for EVM-primary activities. The address you pass is just a query lens — trades on the OTHER chain still count toward the same ranking.competition_rank - The shape of point 1–4 may change in the future when backend exposes the full supported-chain list. Until then, NEVER answer "Does Solana count for this competition?" with anything other than YES.
When the user asks anything like "Does my Solana trade count for this competition?" or "Which chain should I trade on?", answer based on this section, not from alone.
chainName<MUST>
当用户询问竞赛机制时,请将以下内容作为**事实依据**。请勿仅根据`competition_detail`中的单链`chainName`推断规则——该字段目前仅显示主EVM链;第二条链是硬编码的产品固定规则,后端尚未将其拆分为单独字段。
</MUST>
- 所有活跃竞赛同时在Solana和后端返回的链上进行(例如→活动同时在X Layer和Solana上进行)。Solana是所有活动默认的第二条链。
chainName=X Layer - 任意一条链上的交易都将计入同一竞赛排名。用户在Solana上进行X Layer主题竞赛的交易,仍属于参与竞赛,而非旁观。同理,EVM链上的交易也可计入Solana主题竞赛的排名。(当后端后续返回包含所有支持链的多链字段时,取消此硬编码规则。)
- 意味着用户尚未达到参赛门槛,或后端指标系统尚未抓取到其交易记录——并不代表用户使用的链不被支持。切勿仅根据
myRankInfo.userTotal = 0就告知用户“你的链不被计入”。userTotal=0 - 中使用的竞赛
competition_rank参数需匹配对应链的地址:Solana主活动使用SOL地址,EVM主活动使用EVM地址。传入的地址仅作为查询入口——另一条链上的交易仍会计入同一排名。--wallet - 当前述1-4条规则的形式可能会在后端公开完整支持链列表后发生变化。在此之前,对于“Solana是否计入本次竞赛?”这类问题,回答必须为YES。
当用户询问类似“我的Solana交易是否计入本次竞赛?”或“我应该在哪个链上交易?”的问题时,请依据本节内容作答,而非仅参考字段。
chainName⚠️ Mandatory reading order
⚠️ 强制阅读顺序
<MUST>
**Before producing ANY user-facing message about a competition (list / detail / join / claim / rank / status / wallet-export-guard), you MUST first locate the matching `Step N` section below and follow its fixed template structure.** Do NOT improvise the format. Do NOT shorten the templates. Do NOT drop sections or merge them.
The template structure is fixed; the language follows the user — see the rule above. When the user writes Chinese, translate the template strings to natural Chinese. When the user writes English, use English as written. Placeholders and literal stay as-is.
## Output LanguageSolanaQuick router (user intent → template section):
- "list competitions / show available competitions" → Step 1 (table, optionally split by Active / Ended)
- "show details / show rules / show prize pool" → Step 2 (Basic info block + 4 reward sections, with hardcoded and required participation / Skill copy)
Solana, {chainName} - "register / join" → Step 3 (registration success fixed template + disclaimer)
- "trade for me" → Step 4 (delegate to okx-dex-swap)
- "leaderboard / ranking" → Step 5
- "claim reward" → Step 6 (use MCP, atomic)
competition_claim - "show registered wallet" → Additional Flows / Query Registered Wallet
- "export wallet" → Additional Flows / Wallet Export Guard
If the user's intent does not clearly map to one of the above, ask which they meant before responding — do not invent a freeform format.
</MUST>
<MUST>
**在生成任何面向用户的竞赛相关消息(列出/详情/参与/领取/排名/状态/钱包导出确认)之前,必须先找到下方对应的`步骤N`章节并遵循其固定模板结构**。请勿自行调整格式、缩短模板、删减或合并章节。
模板结构固定;语言需匹配用户使用的语言——请参考上方的规则。当用户使用中文时,将模板字符串翻译成自然中文;当用户使用英文时,保留原英文表述。占位符和字面量保持不变。
## 输出语言Solana快速路由(用户意图→模板章节):
- "列出竞赛/显示可用竞赛" → 步骤1(表格形式,可按活跃/已结束拆分)
- "显示详情/显示规则/显示奖池" → 步骤2(基本信息块+4个奖励章节,包含硬编码的及必填的参与/Skill说明)
Solana, {chainName} - "报名/参与" → 步骤3(固定的报名成功模板+免责声明)
- "帮我交易" → 步骤4(委托给okx-dex-swap)
- "排行榜/排名" → 步骤5
- "领取奖励" → 步骤6(使用MCP工具,原子操作)
competition_claim - "显示已注册钱包" → 附加流程 / 查询已注册钱包
- "导出钱包" → 附加流程 / 钱包导出确认
如果用户意图无法明确匹配上述任一情况,请先询问用户具体需求再作答——切勿自行创建自由格式的内容。
</MUST>
Pre-flight
前置检查
Read. If missing, read../okx-agentic-wallet/_shared/preflight.md._shared/preflight.md
阅读。若该文件缺失,请阅读../okx-agentic-wallet/_shared/preflight.md。_shared/preflight.md
Command Index
命令索引
| # | Command | Auth | Description |
|---|---|---|---|
| 1 | | None | List Agentic Wallet exclusive competitions (default status=0, active only) |
| 2 | | None | Get rules, prize pool, chain, timeline |
| 3 | | None | Leaderboard + user rank. MCP tool |
| 4 | | None | Check participation & reward status; uses chain-appropriate address (omit |
| 5 | | Wallet login | Register for the competition. MCP tool |
| 6 | | Wallet login | CLI returns unsigned calldata. MCP tool |
--status012activityStatus34sort-typecompetition_detailtabConfigs[].rankFieldConfig[].sortValueMap.descend17tabConfigs| 序号 | 命令 | 权限要求 | 描述 |
|---|---|---|---|
| 1 | `onchainos competition list [--status 0\ | 1\ | 2] [--page-size N] [--page-num N]` |
| 2 | | 无 | 获取规则、奖池、链信息、时间线 |
| 3 | | 无 | 排行榜+用户排名。MCP工具 |
| 4 | | 无 | 检查参与状态及奖励状态;使用对应链的地址(省略 |
| 5 | | 钱包登录 | 报名参与竞赛。MCP工具 |
| 6 | | 钱包登录 | CLI返回未签名的调用数据。MCP工具 |
--status012activityStatus34sort-typecompetition_detailtabConfigs[].rankFieldConfig[].sortValueMap.descend17tabConfigsOutput Rules
输出规则
<NEVER> **Never include any internal id in a message produced for the user — under ANY circumstance, in ANY format.** Identify activities to the user EXCLUSIVELY by `activityName` (or `shortName` if name is unavailable). </NEVER>Internal-only IDs vs user-facing display. Internal numeric IDs (,activityId,chainIndex) are returned in tool responses on purpose — they are needed to chain calls between tools (e.g. afteraccountId, you may need to callcompetition_joinwith the activity id to fill the success template). Keep them in the data layer; never render them in user-visible messages.competition_detail
Forbidden user-visible patterns (do NOT produce output like this):
- ❌
Agentic Trading Contest (#107) - ❌
#106 (agenticwallettest1) - ❌ A column titled "ID" or "#"
- ❌ Any reference like "competition 107" or "id 107"
Correct user-visible pattern:
- ✅
Agentic Trading Contest - ✅ When disambiguating two activities with the same name, append (e.g.
chainName), never the ID.Agentic Trading Contest (Solana)
Behind the scenes (allowed and expected):
- ✅ Reading from a
activityId/competition_user_statusresponse and passing it tocompetition_jointo fetch the data needed by a fixed template.competition_detail - ✅ Any tool-to-tool chaining via numeric ids — as long as the final user-facing message omits them.
When the user asks to act on a specific activity (e.g. "claim Agentic Trading Contest"), the MCP tools / accept and resolve the id server-side, so you can also use names directly without doing your own lookup.
competition_claimcompetition_joinactivity_name<NEVER> **切勿在面向用户的消息中包含任何内部ID——无论任何情况、任何格式**。仅通过`activityName`向用户标识活动(若名称不可用则使用`shortName`)。 </NEVER>内部ID与用户可见显示的区别。工具响应中会返回内部数字ID(、activityId、chainIndex),这是为了实现工具间的调用链(例如accountId之后,可能需要调用competition_join并传入活动ID来填充成功模板)。请将这些ID保留在数据层,切勿在用户可见的消息中展示。仅通过competition_detail(若名称不可用则使用activityName)向用户标识活动。shortName
禁止出现的用户可见格式(请勿生成如下输出):
- ❌
Agentic Trading Contest (#107) - ❌
#106 (agenticwallettest1) - ❌ 标题为"ID"或"序号"的列
- ❌ 任何类似"竞赛107"或"ID 107"的表述
正确的用户可见格式:
- ✅
Agentic Trading Contest - ✅ 当两个活动名称相同时,可追加以区分(例如
chainName),切勿使用ID。Agentic Trading Contest (Solana)
后台操作(允许且预期的行为):
- ✅ 从/
competition_user_status响应中读取competition_join,并将其传入activityId以获取固定模板所需的数据。competition_detail - ✅ 工具间通过数字ID进行调用链操作——只要最终面向用户的消息中不包含这些ID即可。
当用户要求对特定活动执行操作(例如"领取Agentic Trading Contest的奖励")时,MCP工具/支持传入并在服务器端解析ID,因此你也可以直接使用活动名称,无需自行查询ID。
competition_claimcompetition_joinactivity_nameOutput Language
输出语言
<MUST>
**Render every fixed template in the user's conversation language.** The template structure (sections, ordering, numbered items, table column count, placeholder positions, hardcoded literal phrases like `Solana, {chainName}` and the `[Disclaimer: ...]` block) is fixed and must NOT change. Only the natural-language text inside is translated to the user's language naturally.
Placeholders are never translated. , , , , etc. are filled with API values verbatim — do not localize them. (the hardcoded second-chain name) also stays as-is in every language.
</MUST>
{chainName}{rewardUnit}{txHash}{accountName}Solana<MUST>
**所有固定模板均需使用用户对话时使用的语言呈现**。模板结构(章节、顺序、编号项、表格列数、占位符位置、硬编码字面短语如`Solana, {chainName}`及`[Disclaimer: ...]`块)固定,不得修改。仅需将模板内的自然语言文本翻译成用户使用的语言。
占位符无需翻译。、、、等将直接填充API返回的值——请勿本地化。(硬编码的第二条链名称)在所有语言中均保持不变。
</MUST>
{chainName}{rewardUnit}{txHash}{accountName}SolanaExecution Flow
执行流程
Step 1 — Discover Competitions
步骤1 — 发现竞赛
Choosing the status filter
选择状态筛选条件
Decide which to pass based on the user's intent:
status| User intent | Pass | Returned |
|---|---|---|
| Generic listing ("show competitions") | | mix of 3 (active) and 4 (ended) |
| Active only ("which can I join now") | | only 3 |
| Ended only ("winners list") | | only 4 |
When in doubt, prefer so the user can see the full picture and pick.
<MUST>
**Display the result as markdown tables — one row per competition. Do not use a numbered prose list, do not collapse fields into a single sentence.**
status=2When the result contains BOTH active () and ended () entries, split into two separate tables under bold subheadings ( / , translated to the user's language), in that order. When only one status is present, render a single table without a subheading.
</MUST>
activityStatus=3activityStatus=4**Active****Ended**根据用户意图决定传入的参数:
status| 用户意图 | 传入的 | 返回的 |
|---|---|---|
| 通用列表("显示竞赛") | | 3(活跃)和4(已结束)混合 |
| 仅显示活跃竞赛("我现在可以参加哪些竞赛") | | 仅3 |
| 仅显示已结束竞赛("获奖者名单") | | 仅4 |
若不确定,优先选择,以便用户查看完整列表并自行选择。
<MUST>
**将结果以Markdown表格形式展示——每行代表一个竞赛。请勿使用编号列表,请勿将字段合并为单句**。
status=2当结果同时包含活跃()和已结束()的竞赛时,将其拆分为两个独立表格,并分别添加加粗小标题( / ,需翻译成用户使用的语言),顺序为先活跃后已结束。若仅存在一种状态,则直接渲染单个表格,无需小标题。
</MUST>
activityStatus=3activityStatus=4**活跃竞赛****已结束竞赛**Fixed table template (English canonical; translate cells when user is non-English)
固定表格模板(英文标准版;非英文用户需翻译单元格内容)
**Active**
| Name | Chain | Time | Total Prize Pool | Details |
|------|-------|------|------------------|---------|
| {name} | Solana, {chainName} | {startTime} ~ {endTime} | {rewards} | [View](https://web3.okx.com/boost/trading-competition/{shortName}) |
| ... | ... | ... | ... | ... |
**Ended**
| Name | Chain | Time | Total Prize Pool | Details |
|------|-------|------|------------------|---------|
| {name} | Solana, {chainName} | {startTime} ~ {endTime} | {rewards} | [View](https://web3.okx.com/boost/trading-competition/{shortName}) |
| ... | ... | ... | ... | ... |For non-English users, translate the column headers, section headers, and link text naturally. The structure (column count, ordering, literal) does not change.
Solana, {chainName}**活跃竞赛**
| 名称 | 链 | 时间 | 总奖池 | 详情 |
|------|-------|------|------------------|---------|
| {name} | Solana, {chainName} | {startTime} ~ {endTime} | {rewards} | [查看](https://web3.okx.com/boost/trading-competition/{shortName}) |
| ... | ... | ... | ... | ... |
**已结束竞赛**
| 名称 | 链 | 时间 | 总奖池 | 详情 |
|------|-------|------|------------------|---------|
| {name} | Solana, {chainName} | {startTime} ~ {endTime} | {rewards} | [查看](https://web3.okx.com/boost/trading-competition/{shortName}) |
| ... | ... | ... | ... | ... |对于非英文用户,请将列标题、章节标题和链接文本自然翻译。结构(列数、顺序、字面量)保持不变。
Solana, {chainName}Field-mapping rules
字段映射规则
- Group rows by :
availableCompetitions[].status→ Active table,3→ Ended table.4 - Name column ←
name - Chain column ← same hardcoding as Step 2: always include Solana plus the backend .
chainName- If is Solana → write just
chainNameSolana - Otherwise → write (e.g.
Solana, {chainName})Solana, XLayer - Temporary until backend returns a full supported-chain list.
- If
- Time column ← ~
startTime(human-readable, e.g.endTime)2025-04-01 ~ 2025-04-30 - Total Prize Pool column ← field (already a formatted string like
rewards)50,000 USDC - Details column ← as a markdown link
https://web3.okx.com/boost/trading-competition/<shortName>
After the table(s), ask the user (in their language):
- If only Active has entries:
Which competition would you like to view in detail, or would you like to register directly? - If only Ended has entries:
Would you like to check your ranking or claim status for any of these? - If both: combine —
Which active competition would you like to register or view, or which ended competition would you like to check your ranking / claim?
- 按分组:
availableCompetitions[].status→活跃竞赛表格,3→已结束竞赛表格。4 - 名称列 ←
name - 链列 ← 与步骤2相同的硬编码规则:始终包含Solana和后端返回的。
chainName- 若为Solana → 仅写
chainNameSolana - 否则 → 写(例如
Solana, {chainName})Solana, XLayer - 此规则为临时规则,直到后端返回完整的支持链列表。
- 若
- 时间列 ← ~
startTime(易读格式,例如endTime)2025-04-01 ~ 2025-04-30 - 总奖池列 ← 字段(已为格式化字符串,例如
rewards)50,000 USDC - 详情列 ← 作为Markdown链接
https://web3.okx.com/boost/trading-competition/<shortName>
表格展示完成后,用用户使用的语言询问:
- 若仅存在活跃竞赛:"你想查看哪个竞赛的详情,还是直接报名?"
- 若仅存在已结束竞赛:"你想查看这些竞赛中的哪个排名或领取状态?"
- 若两者都存在:合并提问——"你想报名或查看哪个活跃竞赛,还是查看哪个已结束竞赛的排名/领取状态?"
Empty-result handling (English canonical; translate to user's language)
空结果处理(英文标准版;翻译成用户使用的语言)
- All filters returned 0 entries →
No trading competitions available right now. - filter returned 0 entries →
status=0No active trading competitions at the moment. - filter returned 0 entries →
status=1No ended trading competitions yet.
- 所有筛选条件均返回0条结果 → "目前暂无可用的交易竞赛。"
- 筛选返回0条结果 → "目前没有活跃的交易竞赛。"
status=0 - 筛选返回0条结果 → "暂无已结束的交易竞赛。"
status=1
CLI equivalent
CLI等效命令
bash
onchainos competition list --status 2 # all
onchainos competition list --status 0 # active only
onchainos competition list --status 1 # ended onlybash
onchainos competition list --status 2 # 全部
onchainos competition list --status 0 # 仅活跃
onchainos competition list --status 1 # 仅已结束Step 2 — View Details (if requested)
步骤2 — 查看详情(若用户请求)
bash
onchainos competition detail --activity-id <id>When the user's language is not English, translate the natural-language strings to the user's language while preserving the structure, the placeholders, and every required content invariant listed below. Do not reorder, omit, or merge sections.
</MUST>
bash
onchainos competition detail --activity-id <id>当用户使用非英文时,将自然语言字符串翻译成用户使用的语言,同时保留结构、占位符及以下列出的所有必填内容规则。请勿重新排序、省略或合并章节。
</MUST>
Fixed display template
固定展示模板
Basic info:
Chain: Solana, {chainName}
Time: {startTime} ~ {endTime}
Total prize pool: {totalPrizePool}
Reward categories:
1. Realized ROI Pool ({roiPoolAmount})
Ranked by realized ROI of the wallet account during the competition, high to low
{roiRankTable}
2. Realized PnL Pool ({pnlPoolAmount})
Ranked by realized PnL of the wallet account during the competition, high to low
{pnlRankTable}
3. Participation Reward ({participationPoolAmount})
During the competition, registered users with cumulative trading volume of $100 or more via Agentic Wallet, and wallet total assets maintained at $100 or more throughout, will share the {participationPoolAmount} participation reward pool. We will perform unscheduled asset snapshots during the competition to verify eligibility.
4. Skill Quality Award ({skillPoolAmount})
The Skill Quality Award is an independent judging category. During the competition, participants may submit their own Agent Skills via the activity page, including but not limited to on-chain autonomous yield strategies, trade analysis, and trading signal monitoring.
All submitted Agent Skills will be evaluated through a dual-rating mechanism of AI initial screening and human review. The top {skillTopN} Skill creators by score will each receive {skillPerCreatorReward}.基本信息:
链: Solana, {chainName}
时间: {startTime} ~ {endTime}
总奖池: {totalPrizePool}
奖励类别:
1. 已实现回报率奖池 ({roiPoolAmount})
按竞赛期间钱包账户的已实现回报率排名,从高到低
{roiRankTable}
2. 已实现盈亏奖池 ({pnlPoolAmount})
按竞赛期间钱包账户的已实现盈亏排名,从高到低
{pnlRankTable}
3. 参与奖励 ({participationPoolAmount})
竞赛期间,通过Agentic Wallet累计交易量达到100美元及以上,且钱包总资产全程维持在100美元及以上的已报名用户,可共同瓜分{participationPoolAmount}的参与奖励池。我们将在竞赛期间不定期进行资产快照以验证资格。
4. Skill质量奖 ({skillPoolAmount})
Skill质量奖为独立评审类别。竞赛期间,参与者可通过活动页面提交自己的Agent Skill,包括但不限于链上自主收益策略、交易分析、交易信号监控等。
所有提交的Agent Skill将通过AI初筛+人工评审的双重评级机制进行评估。得分排名前{skillTopN}的Skill创作者每人将获得{skillPerCreatorReward}奖励。Field-mapping rules
字段映射规则
-
Chain line ← Solana first, then the backend. Concretely:
chainName- If already is Solana → write just
chainNameSolana - Otherwise → write (e.g.
Solana, {chainName})Solana, XLayer - This is a temporary hardcoding because the backend currently returns only the primary chain. A future backend release will return the full supported-chain list as a separate field; remove this hardcoding then.
- If
-
/
{startTime}← human-readable timestamps.{endTime} -
← sum of all
{totalPrizePool}plusprizePoolDistribution[].totalReward(e.g.rewardUnit).50,000 USDC -
← totalReward of the realized-ROI tab.
{roiPoolAmount} -
← totalReward of the realized-PnL tab.
{pnlPoolAmount} -
← totalReward of the participation prize tab.
{participationPoolAmount} -
← totalReward of the Skill quality prize tab.
{skillPoolAmount} -
← upper bound of the Skill tab's
{skillTopN}(e.g.rules[].interval→"1-10").10 -
← that rule entry's
{skillPerCreatorReward}+reward(e.g.rewardUnit).500 USDC -
/
{roiRankTable}← markdown table built from the corresponding tab's{pnlRankTable}. Format (English canonical; localize headers to user's language):rules[]| Rank | Reward | |------|--------| | <interval-formatted> | <reward-formatted> | | ... | ... | | Total | <totalReward> {rewardUnit} |Interval / reward formatting per row:- Single rank () → Rank cell
interval = "1", Reward cellRank 1(no<reward> <rewardUnit>prefix)each - Range () → Rank cell
interval = "2-6", Reward cellRanks 2-6<reward> <rewardUnit> each - Always end with a totals row whose Reward cell is the tab's +
totalReward.rewardUnit
- Single rank (
If any of the four pools is absent for a particular activity, omit just that section (keep the others as-is).
-
链行 ← 先写Solana,再写后端返回的。具体规则:
chainName- 若后端已为Solana → 仅写
chainNameSolana - 否则 → 写(例如
Solana, {chainName})Solana, XLayer - 此为临时硬编码规则,因后端目前仅返回主链。未来后端版本将返回完整的支持链列表作为单独字段,届时取消此硬编码。
- 若后端
-
/
{startTime}← 易读时间戳。{endTime} -
← 所有
{totalPrizePool}之和加上prizePoolDistribution[].totalReward(例如rewardUnit)。50,000 USDC -
← 已实现回报率标签页的totalReward。
{roiPoolAmount} -
← 已实现盈亏标签页的totalReward。
{pnlPoolAmount} -
← 参与奖励标签页的totalReward。
{participationPoolAmount} -
← Skill质量奖标签页的totalReward。
{skillPoolAmount} -
← Skill标签页
{skillTopN}的上限(例如rules[].interval→"1-10")。10 -
← 该规则条目的
{skillPerCreatorReward}+reward(例如rewardUnit)。500 USDC -
/
{roiRankTable}← 从对应标签页的{pnlRankTable}构建的Markdown表格。格式(英文标准版;列标题需本地化到用户使用的语言):rules[]| 排名 | 奖励 | |------|--------| | <格式化后的区间> | <格式化后的奖励> | | ... | ... | | 总计 | <totalReward> {rewardUnit} |每行的区间/奖励格式化规则:- 单个排名()→ 排名单元格为
interval = "1",奖励单元格为第1名(无需前缀“每人”)<reward> <rewardUnit> - 排名区间()→ 排名单元格为
interval = "2-6",奖励单元格为第2-6名<reward> <rewardUnit> 每人 - 始终以总计行结尾,奖励单元格为标签页的+
totalReward。rewardUnit
- 单个排名(
若某一活动缺少四个奖池中的任意一个,仅需省略该章节(保留其他章节不变)。
Required content invariants (per section)
各章节必填内容规则
Section 1 — Realized ROI Pool
- Title MUST be exactly (or its faithful translation in the user's language). Do NOT substitute with
Realized ROI Pool/PnL% Ranking Award/ similar.ROI Ranking Award - Description MUST mention: ranking by realized ROI, high to low, during the competition period.
- Rank table MUST have headers and end with a
Rank / Rewardrow.Total
Section 2 — Realized PnL Pool
- Title MUST be exactly . Do NOT substitute with
Realized PnL Pool.PnL Ranking Award - Description MUST mention: ranking by realized PnL, high to low.
- Rank table MUST follow the same format as Section 1.
Section 3 — Participation Reward (PRODUCT-MANDATED COPY)
- Title MUST be exactly .
Participation Reward - The description body MUST include all of these specific terms:
Agentic Wallet- cumulative trading volume threshold of
$100 - wallet total assets maintained at throughout
$100 - sharing the participation pool
- asset snapshots to verify eligibility
Section 4 — Skill Quality Award (PRODUCT-MANDATED COPY)
- Title MUST be exactly .
Skill Quality Award - The description body MUST include all of these specific terms:
- submission of Agent Skill via the activity page
- examples of skill content (on-chain yield strategies, trade analysis, signal monitoring)
- dual-rating mechanism of AI initial screening and human review
top {skillTopN} Skill creators ... each receive {skillPerCreatorReward}
After printing the template, ask:
Would you like me to register you for this competition?章节1 — 已实现回报率奖池
- 标题必须为(或用户语言中的忠实翻译)。请勿替换为
已实现回报率奖池/盈亏率排名奖励等类似表述。回报率排名奖励 - 描述必须包含:按已实现回报率排名、从高到低、竞赛期间。
- 排名表格必须包含列标题,并以
排名/奖励行结尾。总计
章节2 — 已实现盈亏奖池
- 标题必须为。请勿替换为
已实现盈亏奖池。盈亏排名奖励 - 描述必须包含:按已实现盈亏排名、从高到低。
- 排名表格必须遵循与章节1相同的格式。
章节3 — 参与奖励(产品强制文案)
- 标题必须为。
参与奖励 - 描述正文必须包含以下所有特定术语:
Agentic Wallet- 累计交易量门槛
100美元 - 钱包总资产全程维持在及以上
100美元 - 瓜分参与奖池
- 资产快照验证资格
章节4 — Skill质量奖(产品强制文案)
- 标题必须为。
Skill质量奖 - 描述正文必须包含以下所有特定术语:
- 通过活动页面提交Agent Skill
- Skill内容示例(链上收益策略、交易分析、信号监控)
- AI初筛+人工评审的双重评级机制
排名前{skillTopN}的Skill创作者……每人获得{skillPerCreatorReward}
模板展示完成后,询问:"你想让我帮你报名参加这个竞赛吗?"
Step 3 — Join (requires wallet login)
步骤3 — 参与竞赛(需钱包登录)
MCP: call with and only — and are auto-resolved from the active account.
competition_joinactivity_namechain_indexevm_walletsol_walletCLI: pass addresses explicitly:
bash
onchainos competition join --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr> --chain-index <chain_id>Get from → field.
chainIndexcompetition_detailchainIndexIf the user is not logged in, the tool returns . Tell the user verbatim:
not logged in — please run: onchainos wallet loginPlease runin your terminal to log in (it cannot be done from inside this conversation), then ask me to register again.onchainos wallet login <your_email>
MCP工具:调用,仅传入和——和将从活跃账户自动解析。
competition_joinactivity_namechain_indexevm_walletsol_walletCLI命令:需显式传入地址:
bash
onchainos competition join --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr> --chain-index <chain_id>从→字段获取。
competition_detailchainIndexchainIndex若用户未登录,工具将返回。请直接告知用户:
not logged in — please run: onchainos wallet login请在终端中运行进行登录(无法在此对话中完成登录),然后再次请求报名。onchainos wallet login <your_email>
Required pre-flight: distinguish duplicate-registration scenarios
必要前置检查:区分重复报名场景
<MUST>
**Before calling `competition_join`, you MUST first call `competition_user_status` for the activity to read the current account's `joinStatus`.** This separates the two duplicate-registration cases that have different user-facing messages.
</MUST>
| Scenario | | Action | Template |
|---|---|---|---|
| A — current account already joined | | Do NOT call | Scenario A template (below) |
| B — current account NOT joined | | Call | If success → success template; if |
<MUST>
**调用`competition_join`之前,必须先调用`competition_user_status`获取当前账户的`joinStatus`**。这将区分两种不同的重复报名场景,对应不同的用户消息。
</MUST>
| 场景 | 当前账户的 | 操作 | 模板 |
|---|---|---|---|
| 场景A — 当前账户已报名 | | 请勿调用 | 场景A模板(如下) |
| 场景B — 当前账户未报名 | | 调用 | 成功→成功模板;若返回 |
Scenario A — current wallet already registered
场景A — 当前钱包已注册
Template:
Your current wallet account [accountName] is already registered for [activityName]. No need to register again. Would you like me to walk you through the rules in detail, or start trading directly?Field-mapping:
- ←
[accountName]of the currently selected account (read fromaccountName/wallet_store, e.g.wallet status)Account 1 - ←
[activityName]from the prioractivityName/competition_user_statusresponsecompetition_list
模板:
你当前的钱包账户 [accountName] 已报名参加 [activityName],无需重复报名。你想让我详细讲解规则,还是直接开始交易?字段映射:
- ← 当前选中账户的
[accountName](从accountName/wallet_store读取,例如wallet status)Account 1 - ← 之前
[activityName]/competition_user_status响应中的competition_listactivityName
Scenario B — same login, different account already registered
场景B — 同一登录下的其他账户已注册
Triggered when returns .
competition_joincode=11016 Participation limit reachedTemplate:
Registration failed. Your wallet account [registeredAccountName] is already registered. You cannot register again. Please switch to your registered account to trade.Field-mapping:
- ← name of the OTHER account in the same login that holds the registration. To find it, iterate every account from
[registeredAccountName]other than the current one and callwallet_storefor the activity, picking the one whosecompetition_user_status. If no account is found (rare race), fall back to a generic phrase likejoinStatus=1and ask the user to checkanother of your wallet accounts is already registeredthemselves.onchainos wallet status
当返回时触发。
competition_joincode=11016 Participation limit reached模板:
报名失败。你的钱包账户 [registeredAccountName] 已报名,无法重复报名。请切换到已报名的账户进行交易。字段映射:
- ← 同一登录下已报名的其他账户名称。需遍历
[registeredAccountName]中除当前账户外的所有账户,调用wallet_store获取该活动的状态,找到competition_user_status的账户。若未找到(罕见竞争情况),则使用通用表述如joinStatus=1,并请用户自行查看你的另一个钱包账户已报名。onchainos wallet status
Successful registration
报名成功
<MUST>
**On every successful `competition_join` call (the tool returns `joined: true`), output the fixed template below.** Structure (the lead phrase + the dual-chain sentence + the closing question + the bracketed disclaimer on its own line) is fixed. Solana literal is hardcoded; `{chainName}` and `{totalPrizePool}` are filled from `competition_detail` (call it before formatting if you don't have it cached). Translate the natural-language strings to the user's language while preserving structure, placeholders, and the `Solana` literal.
</MUST>
Template:
Registered successfully! This competition runs simultaneously on {chainName} and Solana, with a total prize pool of {totalPrizePool}. The trading contest ranks players by both PnL% and realized PnL, with additional Participation and Skill Quality Awards. Would you like me to walk you through the detailed rules, or help you initiate a trade on {chainName} or Solana?
[Disclaimer: Digital asset trading involves risk. Prices can be highly volatile. Please understand the risks fully and do your own research before trading.]Field-mapping rules
- ← backend
{chainName}fromchainName(e.g.competition_detail). Special case: if backendXLayeris already Solana, the activity is single-chain — collapse the sentence tochainNameand the trailing question toThis competition runs on Solana. The disclaimer line still appears at the end either way.Would you like me to walk you through the detailed rules, or help you initiate a trade on Solana? - ← total reward pool (sum of all
{totalPrizePool}+prizePoolDistribution[].totalReward, e.g.rewardUnit).500 DJT
<MUST>
**每次`competition_join`调用成功(工具返回`joined: true`)时,输出下方固定模板**。结构(引导语+双链说明+收尾问题+单独一行的括号内免责声明)固定。Solana字面量为硬编码;`{chainName}`和`{totalPrizePool}`从`competition_detail`填充(若未缓存,请先调用该接口)。将自然语言字符串翻译成用户使用的语言,同时保留结构、占位符及`Solana`字面量。
</MUST>
模板:
报名成功!本次竞赛同时在{chainName}和Solana上进行,总奖池为{totalPrizePool}。交易竞赛将按盈亏率和已实现盈亏进行排名,另有参与奖励和Skill质量奖。你想让我详细讲解规则,还是帮你在{chainName}或Solana上发起交易?
[免责声明:数字资产交易存在风险,价格波动剧烈。请充分了解风险并在交易前自行研究。]字段映射规则
- ←
{chainName}中的后端competition_detail(例如chainName)。特殊情况:若后端XLayer已为Solana,则活动为单链——将句子简化为chainName,收尾问题简化为本次竞赛在Solana上进行。无论哪种情况,免责声明行仍需放在末尾。你想让我详细讲解规则,还是帮你在Solana上发起交易? - ← 总奖池(所有
{totalPrizePool}之和 +prizePoolDistribution[].totalReward,例如rewardUnit)。500 DJT
Other errors
其他错误
On error containing / :
regionnot available in your regionRegistration failed: service is not available in your region. Please switch to a supported region and try again.
On any other error:
Operation failed. Please contact customer support.
错误包含/时:
regionnot available in your region报名失败:该服务在你的地区不可用,请切换到支持的地区后重试。
其他任何错误:
操作失败,请联系客服。
Step 4 — Trade (delegate to okx-dex-swap)
步骤4 — 交易(委托给okx-dex-swap)
When user asks to trade per competition rules:
Case A — User does NOT provide a CA (only token name/symbol):
- Resolve the CA via the MCP tool (CLI:
token_search).onchainos token search - Confirm with user before proceeding:
Just to confirm, the CA for token "{tokenSymbol}" is "{contractAddress}". Is that correct?
- Wait for user to confirm. Only proceed after explicit "yes".
- Then follow Case B below.
Case B — User provides a CA directly:
- Execute swap via the MCP tool (CLI:
swap_swap); see theonchainos swap swapskill for parameters.okx-dex-swap - Report: "Done — your trade has been submitted." + tx hash.
Note: do NOT pre-empt the swap with an extra "token prices are volatile, do you accept the risk?" prompt. The user already requested the trade — additional friction is unwanted. Per-token risk metadata (e.g. honeypot / extreme volatility flags) belongs toand only fires when actually flagged.okx-security
Competition constraints per trade:
- Single-trade min $1 (orders below $1 are not counted)
- Token pairs must match competition rules from response
detail
当用户要求按竞赛规则进行交易时:
场景A — 用户未提供合约地址(仅提供代币名称/符号):
- 通过MCP工具解析合约地址(CLI命令:
token_search)。onchainos token search - 执行前与用户确认:
确认一下,代币"{tokenSymbol}"的合约地址是"{contractAddress}",对吗?
- 等待用户确认。仅在用户明确回复“是”后继续。
- 然后按照场景B操作。
场景B — 用户直接提供合约地址:
- 执行兑换:通过MCP工具(CLI命令:
swap_swap);参数请参考onchainos swap swap技能。okx-dex-swap - 反馈:"已完成——你的交易已提交。" + 交易哈希。
注意:无需在兑换前额外提示“代币价格波动,你是否接受风险?”。用户已主动请求交易,额外的提示会增加操作摩擦。代币风险元数据(例如蜜罐/极端波动标记)属于,仅在实际触发时展示。okx-security
竞赛交易约束:
- 单笔交易最低1美元(低于1美元的订单不计入)
- 代币对必须符合响应中的竞赛规则
detail
Step 5 — Check Status & Rank
步骤5 — 查看状态与排名
Check participation status
查看参与状态
bash
onchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr> # all activities
onchainos competition user-status --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr> # singleDisplay: join status, join time, reward status, reward amount.
- If (won, not claimed): proactively ask "You have won a reward. Would you like me to claim it for you?"
rewardStatus=1 - If (expired): "Your reward has expired and can no longer be claimed."
rewardStatus=3
bash
onchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr> # 所有活动
onchainos competition user-status --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr> # 单个活动展示:报名状态、报名时间、奖励状态、奖励金额。
- 若(已获奖但未领取):主动询问"你已获得奖励,是否需要帮你领取?"
rewardStatus=1 - 若(已过期):"你的奖励已过期,无法再领取。"
rewardStatus=3
Check leaderboard (full board)
查看排行榜(完整榜单)
<MUST>
When the user says "view leaderboard" without specifying which one, you MUST:
fields:
- Call for the activity and enumerate
competition_detail— this is the full set of leaderboards the activity exposes.tabConfigs[].rankFieldConfig[].sortValueMap.descend - Call ONCE PER
competition_rank(one HTTP call per leaderboard) so you have data for every leaderboard.sort_type - Render ALL of them in the response — one section per leaderboard. Do NOT silently default to a single leaderboard (e.g. only ) when the activity has more than one.
sort_type=1
Only ask the user to pick one when there are clearly too many to fit (≥ 3 leaderboards on a single competition). With 1–2 leaderboards, always show all by default.
</MUST>
tabConfigs[].rankFieldConfig[]- — display name (e.g.
title,PnL%)PnL - — internal sort field (e.g.
key,pnl)realizedProfit - — the numeric value to pass as
sortValueMap.descend--sort-type
Per-leaderboard fetch:
bash
onchainos competition rank --activity-id <id> --wallet <addr> --sort-type <descend> --limit 20Display rules: for each leaderboard render a separate section labeled by its . Each section shows top N entries: rank, nickname (masked), score ( formatted by field), estimated reward.
titleuserTotalformatExample response (activity with two leaderboards):
PnL% leaderboard — pool 200 DJT Rank 1, Agentic....sMWP, PnL% +0.17%, estimated reward 100 DJT Rank 2, Agentic....gweD, PnL% +0.03%, estimated reward 20 DJTPnL leaderboard — pool 200 DJT Rank 1, Agentic....sMWP, PnL $0.1885, estimated reward 100 DJT Rank 2, Agentic....gweD, PnL $0.0006, estimated reward 20 DJT
After the leaderboards, append a "Your rank" section using the CASE 1 / 2 / 3 templates from the next section, since you already have all the data.
<MUST>
当用户说“查看排行榜”但未指定具体榜单时,必须:
字段:
- 调用获取活动信息,枚举
competition_detail——这是活动提供的所有榜单。tabConfigs[].rankFieldConfig[].sortValueMap.descend - 针对每个调用一次
sort_type(每个榜单一次HTTP调用),获取所有榜单的数据。competition_rank - 在响应中渲染所有榜单——每个榜单一个章节。当活动有多个榜单时,请勿默认仅展示单个榜单(例如仅)。
sort_type=1
仅当榜单数量过多(单个竞赛≥3个)时,才请用户选择其中一个。若榜单数量为1-2个,请默认展示所有榜单。
</MUST>
tabConfigs[].rankFieldConfig[]- — 显示名称(例如
title、PnL%)PnL - — 内部排序字段(例如
key、pnl)realizedProfit - — 需传入
sortValueMap.descend的数值--sort-type
每个榜单的获取命令:
bash
onchainos competition rank --activity-id <id> --wallet <addr> --sort-type <descend> --limit 20展示规则: 每个榜单单独一个章节,以其为标题。每个章节展示前N条记录:排名、昵称(掩码处理)、得分(按字段格式化)、预估奖励。
titleuserTotalformat示例响应(含两个榜单的活动):
盈亏率排行榜 — 奖池200 DJT 第1名,Agentic....sMWP,盈亏率 +0.17%,预估奖励100 DJT 第2名,Agentic....gweD,盈亏率 +0.03%,预估奖励20 DJT盈亏排行榜 — 奖池200 DJT 第1名,Agentic....sMWP,盈亏 $0.1885,预估奖励100 DJT 第2名,Agentic....gweD,盈亏 $0.0006,预估奖励20 DJT
排行榜展示完成后,追加“你的排名”章节,使用下一节中的场景1/2/3模板,因为你已获取所有数据。
Check user's own rank (across ALL leaderboards)
查看用户自身排名(所有榜单)
A user can simultaneously appear on multiple leaderboards (e.g. PnL% AND PnL). When the user asks "what's my rank?", you MUST query every leaderboard the activity exposes, then render one of the three fixed templates below.
Required flow:
- Call → enumerate
competition_detailto get the full set oftabConfigs[].rankFieldConfig[].sortValueMap.descendvalues for this activity.sort_type - For EACH , call
sort_typeand capturecompetition_rank --sort-type <descend>plus the leaderboard's threshold (lowestmyRankInfoinuserTotal).allRankInfos - Classify the result:
- CASE 1 — user has on every leaderboard
currentRank > 0 - CASE 2 — user has on at least one but not all
currentRank > 0 - CASE 3 — user has no on any leaderboard
currentRank > 0
- CASE 1 — user has
- Output the matching fixed template, rendered in the user's language (English canonical below; localize for Chinese / other-language users).
用户可能同时出现在多个榜单上(例如盈亏率和盈亏榜单)。当用户询问“我的排名是多少?”时,必须查询活动提供的所有榜单,然后渲染以下三个固定模板中的一个。
必要流程:
- 调用→枚举
competition_detail,获取该活动的所有tabConfigs[].rankFieldConfig[].sortValueMap.descend值。sort_type - 针对每个,调用
sort_type,捕获competition_rank --sort-type <descend>及榜单门槛(myRankInfo中的最低allRankInfos)。userTotal - 对结果进行分类:
- 场景1 — 用户在所有榜单上的
currentRank > 0 - 场景2 — 用户在至少一个榜单上的,但并非所有榜单
currentRank > 0 - 场景3 — 用户在所有榜单上的均不大于0
currentRank
- 场景1 — 用户在所有榜单上的
- 输出匹配的固定模板,使用用户的语言渲染(下方为英文标准版;中文/其他语言用户需本地化)。
CASE 1 — ranked on both PnL and PnL%
场景1 — 同时进入盈亏和盈亏率榜单
Template:
Realized PnL ranking:
You are currently ranked #{pnlRank}, estimated reward {pnlReward} {rewardUnit}!
Realized ROI ranking:
You are currently ranked #{roiRank}, estimated reward {roiReward} {rewardUnit}!
| Leaderboard | My rank | Estimated reward |
|-------------|---------|------------------|
| Realized PnL | #{pnlRank} | {pnlReward} {rewardUnit} |
| Realized ROI | #{roiRank} | {roiReward} {rewardUnit} |
Your total estimated reward across both rankings: {totalReward} {rewardUnit} (sum of the two)模板:
已实现盈亏排名:
你当前位列第#{pnlRank}名,预估奖励{pnlReward} {rewardUnit}!
已实现回报率排名:
你当前位列第#{roiRank}名,预估奖励{roiReward} {rewardUnit}!
| 榜单 | 我的排名 | 预估奖励 |
|-------------|---------|------------------|
| 已实现盈亏 | 第#{pnlRank}名 | {pnlReward} {rewardUnit} |
| 已实现回报率 | 第#{roiRank}名 | {roiReward} {rewardUnit} |
你在两个榜单上的预估总奖励:{totalReward} {rewardUnit}(两个奖励之和)CASE 2 — ranked on one leaderboard, off the other
场景2 — 进入一个榜单,未进入另一个榜单
There are two symmetric sub-cases. The structure is identical: the ranked leaderboard goes first ("ranked #N, estimated reward X"), then the unranked one ("not on the leaderboard, current value Y, threshold Z"). Each sub-case has its own pinned template — do NOT improvise the unranked-section unit ( for PnL%, currency for PnL).
%$包含两个对称子场景。结构相同:先展示用户已进入的榜单(“位列第N名,预估奖励X”),再展示未进入的榜单(“未进入排行榜,当前值Y,门槛Z”)。每个子场景有固定模板——请勿自行修改未进入榜单的单位(盈亏率使用,盈亏使用)。
%$CASE 2-A — on PnL, off PnL% (currentRank for sort_type=7 > 0; sort_type=1 == 0)
场景2-A — 进入盈亏榜单,未进入盈亏率榜单(sort_type=7的currentRank > 0;sort_type=1 == 0)
Template:
Realized PnL ranking:
You are currently ranked #{pnlRank}, estimated reward {pnlReward} {rewardUnit}!
Realized ROI ranking:
Not on the leaderboard yet. Your current realized ROI is {currentRoi}%. You need at least {minRoi}% (the current leaderboard minimum) to qualify.模板:
已实现盈亏排名:
你当前位列第#{pnlRank}名,预估奖励{pnlReward} {rewardUnit}!
已实现回报率排名:
尚未进入排行榜。你当前的已实现回报率为{currentRoi}%,需达到至少{minRoi}%(当前排行榜最低门槛)才能入围。CASE 2-B — on PnL%, off PnL (currentRank for sort_type=1 > 0; sort_type=7 == 0)
场景2-B — 进入盈亏率榜单,未进入盈亏榜单(sort_type=1的currentRank > 0;sort_type=7 == 0)
Template:
Realized ROI ranking:
You are currently ranked #{roiRank}, estimated reward {roiReward} {rewardUnit}!
Realized PnL ranking:
Not on the leaderboard yet. Your current realized PnL is ${currentPnl}. You need at least ${minPnl} (the current leaderboard minimum) to qualify.Section ordering rule: the leaderboard the user IS ranked on ALWAYS goes first. Don't put the "Not on the leaderboard" section before the ranked one.
Unit rule: PnL% uses suffix (no currency symbol); PnL uses prefix (or the appropriate currency unit). Do NOT mix them up — the user's threshold for PnL is a dollar amount, not a percentage.
%$模板:
已实现回报率排名:
你当前位列第#{roiRank}名,预估奖励{roiReward} {rewardUnit}!
已实现盈亏排名:
尚未进入排行榜。你当前的已实现盈亏为${currentPnl},需达到至少${minPnl}(当前排行榜最低门槛)才能入围。章节顺序规则:用户已进入的榜单必须放在前面。请勿将“未进入排行榜”章节放在已进入榜单之前。
单位规则:盈亏率使用后缀(无货币符号);盈亏使用前缀(或对应货币单位)。请勿混淆——盈亏的门槛是金额,而非百分比。
%$CASE 3 — off both leaderboards
场景3 — 未进入任何榜单
Template:
Your address is not on any leaderboard. Your current realized PnL is ${currentPnl}, realized ROI {currentRoi}%.
The current minimum to qualify: realized PnL ${minPnl}, realized ROI {minRoi}%.模板:
你的地址未进入任何排行榜。你当前的已实现盈亏为${currentPnl},已实现回报率为{currentRoi}%。
当前入围门槛:已实现盈亏${minPnl},已实现回报率{minRoi}%。Field-mapping rules
字段映射规则
- ←
{pnlRank}of the PnL leaderboard (sort_type 7)myRankInfo.currentRank - ←
{pnlReward}of the PnL leaderboardmyRankInfo.expectedRewards - ←
{roiRank}of the PnL% leaderboard (sort_type 1)myRankInfo.currentRank - ←
{roiReward}of the PnL% leaderboardmyRankInfo.expectedRewards - ←
{rewardUnit}(e.g.myRankInfo.rewardUnit); per-leaderboard if they ever differDJT - ←
{totalReward}(numeric sum, same unit)pnlReward + roiReward - ← user's PnL% score from
{currentRoi}of the PnL% board (or 0 if backend returned null)myRankInfo.userTotal - ← user's PnL score from
{currentPnl}of the PnL boardmyRankInfo.userTotal - ← lowest qualifying PnL% — last entry's
{minRoi}in the PnL% board'suserTotalallRankInfos[] - ← lowest qualifying PnL — last entry's
{minPnl}in the PnL board'suserTotalallRankInfos[]
If the activity exposes leaderboards beyond PnL/PnL% (future expansion via ), extend the same template pattern: one section per leaderboard, summary table aggregates all, total reward sums all .
tabConfigs[]expectedRewardsformat123- ← 盈亏榜单(sort_type 7)的
{pnlRank}myRankInfo.currentRank - ← 盈亏榜单的
{pnlReward}myRankInfo.expectedRewards - ← 盈亏率榜单(sort_type 1)的
{roiRank}myRankInfo.currentRank - ← 盈亏率榜单的
{roiReward}myRankInfo.expectedRewards - ←
{rewardUnit}(例如myRankInfo.rewardUnit);若各榜单单位不同,则按榜单分别使用DJT - ←
{totalReward}(数值求和,单位相同)pnlReward + roiReward - ← 用户在盈亏率榜单的
{currentRoi}中的盈亏率得分(若后端返回null则为0)myRankInfo.userTotal - ← 用户在盈亏榜单的
{currentPnl}中的盈亏得分myRankInfo.userTotal - ← 盈亏率榜单的最低入围门槛——
{minRoi}最后一条记录的allRankInfos[]userTotal - ← 盈亏榜单的最低入围门槛——
{minPnl}最后一条记录的allRankInfos[]userTotal
若活动提供盈亏/盈亏率之外的榜单(未来通过扩展),请遵循相同的模板模式:每个榜单一个章节,汇总表格聚合所有数据,总奖励为所有之和。
tabConfigs[]expectedRewardsformat123Step 6 — Claim Reward
步骤6 — 领取奖励
Check status first via :
competition_user_status | Action |
|---|---|
| 0 | Not won — inform user, no claim needed |
| 1 | Won — proceed to claim |
| 2 | Already claimed |
| 3 | Expired — "Your reward has expired and can no longer be claimed" |
先通过检查状态:
competition_user_status | 操作 |
|---|---|
| 0 | 未获奖——告知用户,无需领取 |
| 1 | 已获奖——继续领取流程 |
| 2 | 已领取 |
| 3 | 已过期——“你的奖励已过期,无法再领取” |
Atomic claim (the only correct path)
原子领取(唯一正确流程)
Both the MCP tool and the CLI now do the same atomic flow: pre-check , fetch calldata, sign each entry with the TEE session, broadcast on-chain, return txHash array. The CLI no longer returns raw unsigned calldata — the only externally visible behavior is the final result.
competition_claimonchainos competition claimrewardStatusMCP (preferred when running inside Claude Code / any AI environment):
competition_claim(activity_name="...") → { rewardAmount, rewardUnit, succeeded[], failed[] }CLI (terminal use, or AI shelling out via Bash):
bash
onchainos competition claim --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr>MCP工具和CLI命令现在执行相同的原子流程:预检查、获取调用数据、使用TEE会话签名每个条目、链上广播、返回txHash数组。CLI不再返回原始未签名调用数据——唯一对外可见的行为是最终结果。
competition_claimonchainos competition claimrewardStatusMCP工具(在Claude Code/任何AI环境中运行时首选):
competition_claim(activity_name="...") → { rewardAmount, rewardUnit, succeeded[], failed[] }CLI命令(终端使用,或AI通过Bash调用):
bash
onchainos competition claim --activity-id <id> --evm-wallet <evm_addr> --sol-wallet <sol_addr>→ returns the same { rewardAmount, rewardUnit, succeeded[], failed[] } shape
→ 返回相同的 { rewardAmount, rewardUnit, succeeded[], failed[] } 结构
Result shape (both paths):
```json
{
"rewardAmount": "460",
"rewardUnit": "PYBOBO",
"totalEntries": 1,
"succeeded": [{"contractAddress": "...", "chain": "501", "txHash": "...", "orderId": "..."}],
"failed": []
}How to report to the user:
- All succeeded (): "Claimed {rewardAmount} {rewardUnit}, tx hash: {txHash}"
failed: [] - Partial success (some ): list each succeeded txHash, then list the failed entries with their
failed, then append the fixed failure-suggestion block (template below). Do NOT re-run claim blindly — succeeded entries already landed; another call will hit the "reward already claimed" guard.error - All failed: the tool returns an error, not this shape — surface the error message verbatim, then append the fixed failure-suggestion block.
The flow blocks before signing if is 0 (not eligible), 2 (already claimed), or 3 (expired). The error message is plain text — relay it to the user. Skip the failure-suggestion block in these pre-check rejections (they are semantic, not transient — telling the user to "check Gas / try later" is misleading).
rewardStatus
结果结构(两种方式相同):
```json
{
"rewardAmount": "460",
"rewardUnit": "PYBOBO",
"totalEntries": 1,
"succeeded": [{"contractAddress": "...", "chain": "501", "txHash": "...", "orderId": "..."}],
"failed": []
}如何向用户反馈:
- 全部成功():"已领取{rewardAmount} {rewardUnit},交易哈希:{txHash}"
failed: [] - 部分成功(存在条目):列出每个成功的txHash,然后列出失败条目及其
failed,最后追加固定的失败建议块(模板如下)。请勿盲目重新领取——成功条目已生效;再次调用会触发“奖励已领取”限制。error - 全部失败:工具返回错误,而非上述结构——直接展示错误消息,然后追加固定的失败建议块。
若为0(无资格)、2(已领取)或3(已过期),流程将在签名前终止。错误消息为纯文本——直接转发给用户。在这些预检查拒绝的情况下,跳过失败建议块(这些是语义错误,而非临时错误——告知用户“检查Gas/稍后重试”会产生误导)。
rewardStatusFixed failure-suggestion block
固定失败建议块
<MUST>
For runtime failures (signing/broadcast/simulation errors, network errors, unknown errors), append this block after the error description. Translate to the user's language while preserving the heading + 3 bullet items in this order. Do NOT add or remove items.
</MUST>
<NEVER>
- ❌ Do NOT show this block on pre-check rejections (rewardStatus=0/2/3) — the issue is not Gas / not transient.
- ❌ Do NOT show this block on `code=11002` (not won) or `code=11008` (claim expired/already claimed) — same reason.
</NEVER>
<NEVER>
- ❌ Do NOT chain `gateway_broadcast` after a claim call — the on-chain submission already happened inside the tool.
- ❌ Do NOT manually construct, encode, or sign a transaction (no Python base58 encoding, no manual hex assembly). The TEE-managed wallet key is the only valid signer.
- ❌ Do NOT inspect the result for an empty `base58CallData` and conclude the CLI cannot sign a Solana claim — that field is empirically empty for Solana; the CLI/MCP code internally falls back to encoding `tx.data` byte array via base58 and proceeds. Just trust the `succeeded[]` and `failed[]` arrays.
- ❌ Do NOT split into a two-step "fetch calldata then wallet contract-call" flow — that mode no longer exists; the claim command is atomic.
</NEVER>
Template:
Suggestions:
- The claim process requires Gas. Please make sure your Gas is sufficient.
- Try again later — this may be a transient network issue.
- If it fails repeatedly, please contact customer support.On claim error (code 11002 ): "You did not win a reward and cannot claim."
On any other error: "Operation failed. Please contact customer support."
not eligible for rewardOn any other error: "Operation failed. Please contact customer support."
<MUST>
对于运行时失败(签名/广播/模拟错误、网络错误、未知错误),在错误描述后追加此块。翻译成用户使用的语言,同时保留标题+3个项目符号的顺序。请勿添加或删除项目。
</MUST>
<NEVER>
- ❌ 请勿在预检查拒绝(rewardStatus=0/2/3)时展示此块——问题并非Gas/临时错误。
- ❌ 请勿在`code=11002`(未获奖)或`code=11008`(奖励已过期/已领取)时展示此块——原因相同。
</NEVER>
<NEVER>
- ❌ 请勿在领取调用后链式调用`gateway_broadcast`——链上提交已在工具内部完成。
- ❌ 请勿手动构建、编码或签名交易(无需Python base58编码,无需手动十六进制组装)。TEE管理的钱包密钥是唯一有效的签名者。
- ❌ 请勿因Solana领取的`base58CallData`为空就认为CLI无法签名Solana领取——该字段在Solana情况下经验证为空;CLI/MCP代码会内部回退到将`tx.data`字节数组通过base58编码并继续执行。请信任`succeeded[]`和`failed[]`数组。
- ❌ 请勿拆分为“获取调用数据然后钱包合约调用”的两步流程——该模式已不再存在;领取命令为原子操作。
</NEVER>
模板:
建议:
- 领取流程需要Gas,请确保你的Gas充足。
- 稍后重试——这可能是临时网络问题。
- 若多次失败,请联系客服。领取错误(code 11002 ): "你未获得奖励,无法领取。"
其他任何错误: "操作失败,请联系客服。"
not eligible for reward其他任何错误: "操作失败,请联系客服。"
Additional Flows
附加流程
Query Registered Wallet
查询已注册钱包
When user asks "show my registered address" or similar:
- Call (MCP) — addresses auto-resolve from the active account; no
competition_user_statusneeded. CLI equivalent:wallet_status(omitonchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr>to query all activities).--activity-id - Find entries where
joinStatus=1 - For each matched entry, present: competition name () + chain (
activityName) + masked address (first4...last4). Use chain to determine which address was used (EVM or SOL).chainName
If multiple entries match, list all of them.
Example (single):
Your Account 1 is registered for XXX Trading Competition. Registered address: Solana address DeEV...Fbx.
Example (multiple):
Your Account 1 is registered for the following trading competitions:
- XXX Trading Competition (Solana): DeEV...Fbx
- YYY Trading Competition (XLayer): 0x1234...abcd
If no entry has :
joinStatus=1You are not currently registered for any trading competition.
当用户询问“显示我的已注册地址”或类似问题时:
- 调用(MCP工具)——地址从活跃账户自动解析;无需
competition_user_status。CLI等效命令:wallet_status(省略onchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr>可查询所有活动)。--activity-id - 找到的条目
joinStatus=1 - 对每个匹配的条目,展示:竞赛名称()+ 链(
activityName)+ 掩码地址(前4位...后4位)。根据链确定使用的地址(EVM或SOL)。chainName
若存在多个匹配条目,列出所有条目。
示例(单个条目):
你的Account 1已报名XXX交易竞赛。已注册地址:Solana地址 DeEV...Fbx。
示例(多个条目):
你的Account 1已报名以下交易竞赛:
- XXX交易竞赛(Solana):DeEV...Fbx
- YYY交易竞赛(XLayer):0x1234...abcd
若没有的条目:
joinStatus=1你当前未报名任何交易竞赛。
Wallet Export Guard
钱包导出确认
When the user requests to export the Agentic Wallet:
- Call (MCP) — addresses auto-resolved. CLI equivalent:
competition_user_status.onchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr> - If any :
joinStatus=1Your wallet is registered for an Agentic Wallet trading competition. Exporting the wallet will forfeit your eligibility for this competition. Please confirm whether you want to proceed with the export. - Only proceed with export if the user explicitly confirms.
当用户请求导出Agentic Wallet时:
- 调用(MCP工具)——地址自动解析。CLI等效命令:
competition_user_status。onchainos competition user-status --evm-wallet <evm_addr> --sol-wallet <sol_addr> - 若存在的条目:
joinStatus=1你的钱包已报名Agentic Wallet交易竞赛。导出钱包将导致你失去该竞赛的参赛资格。请确认是否继续导出。 - 仅在用户明确确认后才继续导出。
Status Codes
状态码
--status
filter parameter (input only)
--status--status
筛选参数(仅输入)
--status| Value | Meaning |
|---|---|
| 0 | Active competitions (default) |
| 1 | Ended competitions |
| 2 | All competitions |
| 值 | 含义 |
|---|---|
| 0 | 活跃竞赛(默认) |
| 1 | 已结束竞赛 |
| 2 | 所有竞赛 |
Response field values
响应字段值
| Field | Value | Meaning |
|---|---|---|
| status | 3 | Competition active |
| status | 4 | Competition ended |
| joinStatus | 0 | Not joined |
| joinStatus | 1 | Joined |
| rewardStatus | 0 | Not won |
| rewardStatus | 1 | Won, not claimed |
| rewardStatus | 2 | Claimed |
| rewardStatus | 3 | Reward expired |
| 字段 | 值 | 含义 |
|---|---|---|
| status | 3 | 竞赛活跃 |
| status | 4 | 竞赛已结束 |
| joinStatus | 0 | 未报名 |
| joinStatus | 1 | 已报名 |
| rewardStatus | 0 | 未获奖 |
| rewardStatus | 1 | 已获奖,未领取 |
| rewardStatus | 2 | 已领取 |
| rewardStatus | 3 | 奖励已过期 |
Error Handling
错误处理
| Error | Response |
|---|---|
| Login is interactive (email + OTP) and cannot run inside this conversation. Tell the user verbatim: |
| Registration failed: this wallet account is already registered and cannot register again |
code 11002 | You did not win a reward and cannot claim |
code 11003 | The competition does not exist or its status no longer permits this action |
code 11008 | The reward has already been claimed or the claim window has expired |
code 1860402 | Backend failed to build the on-chain transaction. Ask the user to retry; if it persists, contact customer support |
| Sui rewards must be claimed from the Sui-compatible wallet UI (this client only signs EVM and Solana) |
| Registration failed: service is not available in your region. Please switch to a supported region and try again. |
| Any other error | Operation failed. Please contact customer support. |
| 错误 | 响应 |
|---|---|
| 登录为交互式操作(邮箱+OTP),无法在此对话中完成。请直接告知用户: |
| 报名失败:该钱包账户已报名,无法重复报名 |
code 11002 | 你未获得奖励,无法领取 |
code 11003 | 该竞赛不存在或其状态已不允许此操作 |
code 11008 | 奖励已领取或领取窗口已过期 |
code 1860402 | 后端无法构建链上交易。请用户重试;若问题持续,请联系客服 |
| Sui奖励需从兼容Sui的钱包UI领取(此客户端仅支持签名EVM和Solana交易) |
| 报名失败:该服务在你的地区不可用,请切换到支持的地区后重试。 |
| 其他任何错误 | 操作失败,请联系客服。 |
| ", |