fix(#416 P0): account creation uses v0.23 passkey-at-birth (deploy-at-birth)#417
Conversation
…-at-birth) The dashboard's account-creation dialog — the real onboarding path for a fresh user — called the legacy single-shot createWithP256Guardians, which leaves the account UNDEPLOYED. Its first gasless transfer then reverts at prepare time (v0.22 factory can't deploy-in-initCode), and the user is pushed into the aPNTs-gated tier-setup to pre-deploy. Beta blocker (docs/CREATE_FLOW_BETA_BUG.md #1). Switch to the v0.23 passkey-at-birth flow the backend already exposes (and the live DEMO used): prepare-create-with-passkey → owner device-passkey ceremony (startAuthentication) → submit-create-with-passkey (relayer deploys). The account is DEPLOYED + wired (owner passkey + validator) at birth, so the first transfer works with no separate pre-deploy step. + api.ts wrappers for the two phases. tsc + lint green. NOTE: needs a dialog-flow validation (test stack / cos72: register → create account → confirm deployed → transfer) before merge — critical onboarding path. Follow-ups: #2 bake default tiers via initialTokenConfigs, #3 tier-setup self-pay fallback.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
clestons
left a comment
There was a problem hiding this comment.
Review: #417 — fix(#416 P0): passkey-at-birth
#416 beta blocker 的直接修复。CreateAccountDialog 切换到两阶段 v0.23 deploy-at-birth 流程。
challengeId 分析
transfer 的 submit 携带 challengeId,此处 submitCreateWithPasskey 只传 { createId, credential } — 正确:account creation 走 device-passkey 路径(startAuthentication,非 KMS ceremony),WebAuthn challenge 已内嵌于 publicKeyOptions.challenge 并通过 clientDataJSON 回传,后端用 createId 关联验证。SubmitCreateWithPasskeyDto.challengeId 是 optional,SDK 走 device-passkey 验证路径 ✓
其余检查
startAuthentication({ optionsJSON: prep.data.publicKeyOptions as any }) — as any 已注释,与 transfer 同模式 ✓
credential as unknown as Record<string, unknown> — 同 #399 已审通过的双重 cast ✓
用户取消 biometric → startAuthentication 抛 NotAllowedError → 外层 try/catch,不进入 submit ✓
api.ts 两个 wrapper 类型签名与后端 DTO 匹配(challengeId 不在 submit DTO 里)✓
[M] dialog-flow 验证待完成(作者已标注)
PR 自注:"needs a dialog-flow validation (test stack / cos72: register → create account → confirm deployed → transfer) before merge — critical onboarding path"
这是唯一实质风险:prepareCreateWithPasskey 响应的 publicKeyOptions 形状未类型化,端到端流程需真实跑通。tsc/lint 不覆盖运行时序列。建议完成 cos72 验证后合并。
总结
代码结构正确,逻辑无误,修复方向准确。P0 blocker 已解除,跟进 #2(默认 tiers)和 #3(tier-setup 自付 fallback)。
APPROVE(待 dialog-flow 验证后合并)
| 轮次 | 执行者 | 裁决 |
|---|---|---|
| R1 | Sonnet 4.6 | APPROVE(M 待 cos72 端到端验证,代码逻辑正确) |
Beta blocker fix (docs/CREATE_FLOW_BETA_BUG.md #1).
The dashboard's CreateAccountDialog — the real onboarding path for a fresh user (dashboard → 'Create Account') — called the legacy single-shot
createWithP256Guardians, which leaves the account undeployed. The first gasless transfer then reverts at prepare time (v0.22 factory can't deploy-in-initCode) and the user is pushed into the aPNTs-gatedtier-setupto pre-deploy.Switch to the v0.23 passkey-at-birth flow the backend already exposes (and the live DEMO used):
prepare-create-with-passkey→ owner device-passkey ceremony (startAuthentication) →submit-create-with-passkey(relayer deploys). The account is deployed + wired at birth → first transfer works, no pre-deploy step. Adds the twoapi.tswrappers.tsc + lint + build green. Fix is on the confirmed onboarding path (dashboard renders this dialog).
/account/createshortcut which bypasses this dialog, so it doesn't cover the change.Follow-ups (same beta-bug doc): #2 bake default tiers via
initialTokenConfigs; #3 tier-setup self-pay (ETH) fallback.