OpenClaw Popup Application (v1)
Run the EdgeOS application flow with a strict, reliable sequence:
- 1. Authenticate user via OTP once per session.
- Persist and reuse JWT for all subsequent calls in that session.
- Resolve target popup.
- Collect required application fields.
- Submit application.
- Check status on demand.
- After acceptance, guide product selection and payment.
Read these references before executing:
- - INLINECODE0
- INLINECODE1
- INLINECODE2 (API source of truth)
Before collecting fields, read workspace USER.md and use it as prefill context when values are relevant and trustworthy for the current user.
Runtime configuration
This v1 skill is intentionally pinned to PROD backend values (no user setup required).
Values are defined once in:
Do not ask users to configure runtime values in v1.
Use the values from scripts/env.sh consistently for auth and API calls.
Script-first rule
Prefer scripts in {baseDir}/scripts over ad-hoc curl construction:
- - INLINECODE7
- INLINECODE8 (persists JWT in local state file)
- INLINECODE9
- INLINECODE10 (supports
--application-id or --citizen-id + --popup-city-id) - INLINECODE14
- INLINECODE15
- INLINECODE16
- INLINECODE17 (x402 challenge from
/agent/buy-ticket) - INLINECODE19 (x402 submit with
PAYMENT-SIGNATURE, optional AGENTKIT)
Only fall back to raw curl if a script cannot handle the case.
Data collection policy (strict minimal questions)
Use this exact sequence:
- 1. Determine required + optional application fields.
- Fill all required fields and all optional fields using source priority (below), taking reasonable defaults only where policy allows.
- Ask only for required fields that are still missing after source resolution.
- Build a full field review covering all form questions and values (required + optional), excluding only internal workflow fields like
status. - For every unresolved field, ask the user and label it as required or optional.
- After all fields are resolved (or explicitly skipped if optional), ask if the user wants changes or submit as-is; submit only after explicit approval.
Source priority (authoritative order)
- 1.
USER.md (primary source for all mappable fields) - Authenticated API profile/application context
- Current session and prior user turns
- Channel sender metadata inference
If a field is present in USER.md, prefer that value unless the user explicitly overrides it in the current conversation.
Additional rules:
- - For names specifically, infer before asking (profile -> known identity -> sender display name parsing).
- Infer gender from pronouns/known context by default; ask only if completely unknown.
- Infer
local_resident from known residence/location context by default (example: user based in Buenos Aires => not local resident for Edge Esmeralda). - Treat
duration as required and normalize it to one of: 1 week, 1 weekend, 2 weeks, a few days, full length. - Never re-ask a field that is already known unless the user asks to change it.
- Treat generic confirmations ("yes", "ok") as approval signals, not as field values.
- Infer optional booleans from user context when plausible (e.g., technical builder profile =>
builder_boolean=true; investor intent absent => investor=false). - If boolean inference is not possible, ask the user (marking as optional) instead of silently defaulting.
- Do not invent personal free-text answers (e.g., goals). Ask when unknown (marking as optional).
- Required fields must always be resolved before submit.
Session auth handling
- - After successful OTP login, persist JWT using
auth_login.sh and reuse it for all subsequent API requests. - Runtime scripts auto-load JWT from per-email state files under
{baseDir}/scripts/.state/. - State is keyed by email; set
SESSION_EMAIL when running scripts to select the correct token. - Do not request OTP again while JWT works.
- On unauthorized responses, reload JWT from script state and retry once before asking for new OTP.
- Only re-authenticate when an API call still returns unauthorized/invalid token (401) after retry, or token is truly missing.
Crypto payment support (x402)
When the user chooses to pay with crypto, the skill uses POST /agent/buy-ticket (x402 protocol).
The skill gets payment requirements from the server, provides them to the agent, and the agent
signs the USDC transfer with whatever wallet it has configured (CDP, MCP tool, etc.).
The skill does NOT handle wallet signing — it provides the data and the agent handles signing.
World ID-verified agents (via AgentKit) receive a 10% discount automatically when the
AGENTKIT header is included with a valid signed payload.
Guardrails
- - Never expose full OTP codes or JWTs.
- Never force server-owned status transitions.
- Never create a payment unless application status is
accepted. - Never submit an application for a popup that has already ended (
end_date < now). - Keep prompts short and ask one question at a time.
- Confirm before final submission.
- Do not show internal IDs (product IDs, popup IDs, attendee IDs, citizen IDs, payment IDs) unless the user explicitly asks.
- Present products in user-friendly terms (name, what it includes, price), then map to IDs internally.
- Never expose wallet private keys or raw transaction signatures in chat output.
- When presenting x402 payment info, show human-readable amounts (e.g. "$10.00 USDC") not atomic units.
- Convert USDC atomic amounts: divide by 1,000,000 for display (e.g. "1000000" → "$1.00").
Outputs to return
- - current INLINECODE41
- concise next step guidance
- include IDs only when operationally useful or when explicitly requested by the user
On duplicate submissions, return existing application status instead of surfacing a raw failure.
OpenClaw 弹出式申请应用 (v1)
按照严格、可靠的顺序运行 EdgeOS 应用流程:
- 1. 每个会话通过 OTP 对用户进行一次身份验证。
- 在该会话中持久化并复用 JWT 用于所有后续调用。
- 解析目标弹出式窗口。
- 收集所需的申请字段。
- 提交申请。
- 按需检查状态。
- 接受后,引导产品选择和支付。
在执行前阅读以下参考资料:
- - {baseDir}/references/conversation-flow.md
- {baseDir}/references/flow.md
- {baseDir}/references/api-contract.md(API 权威来源)
在收集字段前,读取工作区 USER.md,并在相关且可信的值适用于当前用户时,将其用作预填上下文。
运行时配置
此 v1 技能有意固定为 PROD 后端值(无需用户设置)。
值在以下位置一次性定义:
- - {baseDir}/scripts/env.sh
在 v1 中,不要要求用户配置运行时值。
在身份验证和 API 调用中一致地使用 scripts/env.sh 中的值。
脚本优先规则
优先使用 {baseDir}/scripts 中的脚本,而非临时构建 curl 命令:
- - authrequestotp.sh
- authlogin.sh(将 JWT 持久化到本地状态文件中)
- submitapplication.sh
- checkapplicationstatus.sh(支持 --application-id 或 --citizen-id + --popup-city-id)
- paymentpreview.sh
- paymentcreate.sh
- paymentstatus.sh
- buyticketchallenge.sh(来自 /agent/buy-ticket 的 x402 挑战)
- buyticket_submit.sh(使用 PAYMENT-SIGNATURE 提交 x402,可选 AGENTKIT)
仅当脚本无法处理该情况时,才回退到原始 curl。
数据收集策略(严格最小化提问)
使用以下精确顺序:
- 1. 确定必填 + 可选申请字段。
- 使用来源优先级(如下)填写所有必填字段和所有可选字段,仅在策略允许时采用合理的默认值。
- 仅询问来源解析后仍然缺失的必填字段。
- 构建完整的字段审查,涵盖所有表单问题和值(必填 + 可选),排除 status 等内部工作流字段。
- 对于每个未解析的字段,询问用户并将其标记为必填或可选。
- 在所有字段解析后(或可选字段明确跳过),询问用户是否需要更改或按原样提交;仅在明确批准后提交。
来源优先级(权威顺序)
- 1. USER.md(所有可映射字段的主要来源)
- 已验证的 API 个人资料/申请上下文
- 当前会话和之前的用户交互
- 渠道发送者元数据推断
如果某个字段存在于 USER.md 中,优先使用该值,除非用户在当前对话中明确覆盖。
附加规则:
- - 对于姓名,在询问前进行推断(个人资料 -> 已知身份 -> 发送者显示名称解析)。
- 默认从代词/已知上下文推断性别;仅在完全未知时询问。
- 默认从已知居住地/位置上下文推断 localresident(示例:用户位于布宜诺斯艾利斯 => 对于 Edge Esmeralda 不是本地居民)。
- 将 duration 视为必填字段,并规范化为以下之一:1 week、1 weekend、2 weeks、a few days、full length。
- 除非用户要求更改,否则绝不重新询问已知字段。
- 将一般性确认(yes、ok)视为批准信号,而非字段值。
- 在合理的情况下从用户上下文推断可选布尔值(例如,技术构建者个人资料 => builderboolean=true;无投资者意图 => investor=false)。
- 如果无法进行布尔推断,则询问用户(标记为可选),而非静默默认。
- 不要编造个人自由文本答案(例如,目标)。在未知时询问(标记为可选)。
- 提交前必须始终解析必填字段。
会话身份验证处理
- - OTP 登录成功后,使用 authlogin.sh 持久化 JWT,并在所有后续 API 请求中复用。
- 运行时脚本从 {baseDir}/scripts/.state/ 下按电子邮件划分的状态文件自动加载 JWT。
- 状态按电子邮件键控;运行脚本时设置 SESSIONEMAIL 以选择正确的令牌。
- 在 JWT 有效期间,不要再次请求 OTP。
- 收到未授权响应时,从脚本状态重新加载 JWT 并重试一次,然后再请求新的 OTP。
- 仅当 API 调用在重试后仍然返回未授权/无效令牌(401),或令牌确实缺失时,才重新进行身份验证。
加密货币支付支持 (x402)
当用户选择使用加密货币支付时,技能使用 POST /agent/buy-ticket(x402 协议)。
技能从服务器获取支付要求,将其提供给代理,代理使用其配置的任何钱包(CDP、MCP 工具等)签署 USDC 转账。
技能不处理钱包签名——它提供数据,代理处理签名。
通过 World ID 验证的代理(通过 AgentKit)在包含有效签名负载的 AGENTKIT 标头时,自动获得 10% 折扣。
防护措施
- - 绝不暴露完整的 OTP 代码或 JWT。
- 绝不强制服务器拥有的状态转换。
- 除非申请状态为 accepted,否则绝不创建支付。
- 绝不提交已结束的弹出式窗口的申请(end_date < now)。
- 保持提示简短,一次只问一个问题。
- 在最终提交前进行确认。
- 除非用户明确要求,否则不显示内部 ID(产品 ID、弹出式窗口 ID、参与者 ID、公民 ID、支付 ID)。
- 以用户友好的术语呈现产品(名称、包含内容、价格),然后在内部映射到 ID。
- 绝不暴露钱包私钥或原始交易签名到聊天输出中。
- 呈现 x402 支付信息时,显示人类可读的金额(例如 $10.00 USDC),而非原子单位。
- 转换 USDC 原子金额:除以 1,000,000 用于显示(例如 1000000 → $1.00)。
返回输出
- - 当前 status
- 简洁的下一步指导
- 仅当操作上有用或用户明确请求时包含 ID
对于重复提交,返回现有申请状态,而非显示原始失败信息。