feat(#416 ②): create-with-tier-profile — pick a profile, bake ETH + USDC/USDT limits at birth#420
Conversation
…s at birth
Onboarding one-shot: the user picks a spending profile (Web3 Beginner / Trader / Conservative)
at account creation and their ETH + stablecoin tier limits are baked into the account at birth,
instead of the aPNTs-gated post-create tier-setup.
- lib/tier-profiles.ts: business config — 3 profiles × {ETH (SDK REFERENCE_ETH_PROFILES),
USDC, USDT} ceilings (user-confirmed defaults; movable to the config center later).
- CreateAccountDialog: replaces the raw daily-ETH input with a profile picker →
resolveTierProfile() (@aastar/sdk/kms 0.35.0) → passes { dailyLimit, initialTokens,
initialTokenConfigs } to prepare-create-with-passkey. Bigints serialized to base-unit strings.
- backend: prepare-create DTO accepts initialTokens/initialTokenConfigs (TokenTierConfigDto),
service converts strings→bigint and threads them into prepareCreateAccountWithPasskey.
ETH tier1/tier2 (r.ethTierLimits) still applies post-deploy via tier-setup self-pay (#418) —
folds into birth once airaccount-contract#161 lands; resolveTierProfile API unchanged. See
memory create-with-tier-profile / docs/CREATE_FLOW_BETA_BUG.md. backend+frontend tsc+lint green.
NOTE: like #417, needs a live cos72 validation of the full create-with-profile ceremony.
|
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: #420 — feat(#416 ②): create-with-tier-profile
#416 fix plan #2:创建时一次性烘焙 ETH + 稳定币 tier 上限,替代 aPNTs 门控的 post-create tier-setup。
核心链路
resolveTierProfile(TIER_PROFILES[selectedProfile].profile) → r.dailyLimit/initialTokens/initialTokenConfigs
formatEther(r.dailyLimit) → ETH 字符串送后端 ✓
c.tier1Limit.toString() 将 bigint 序列化为十进制字符串,后端 BigInt(c.tier1Limit) 逆向还原 ✓
条件 spread ...(initialTokens && initialTokens.length > 0 ? { initialTokens, initialTokenConfigs } : {}) — 无 token 时不污染请求 ✓
USD 显示 Number(p.profile.tokens[0].dailyLimit) / 1e6:trader $5000 USDC = 5_000_000_000n,远低于 Number.MAX_SAFE_INTEGER,无精度损失 ✓
DTO: @IsEthereumAddress({ each: true }) 校验每个 token 地址;@ValidateNested + @Type(() => TokenTierConfigDto) 嵌套校验 ✓
[M] 后端 BigInt() 无格式校验
TokenTierConfigDto 仅有 @IsString(),接受任意字符串。BigInt("1.5")、BigInt("")、BigInt("abc") 在运行时抛异常而非返回 400(导致 500)。攻击面:已认证用户可触发。建议在 TokenTierConfigDto 三个字段加:
@Matches(/^\d+$/, { message: "must be a non-negative base-10 integer string" })[L] Sepolia USDT 地址待核对
0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0 — Tether 无官方 Sepolia 部署,请与项目 token registry 确认此地址为已注册的测试代币。
总结
架构完整(lib/tier-profiles → dialog → api.ts → DTO → service),与 sdk#267 (resolveTierProfile) 和 #417 (deploy-at-birth) 形成完整 onboarding 修复链。ETH tier1/tier2 post-deploy via tier-setup (#418) 路径文档清晰,contract#161 落地后 API 无变化。
NOTE(与 #417 相同):需要 cos72 live 验证 create-with-profile 完整仪式。
APPROVE
| 轮次 | 执行者 | 裁决 |
|---|---|---|
| R1 | Sonnet 4.6 | APPROVE(M 需加 @Matches(/^\d+$/) 防 BigInt 运行时崩溃;L USDT Sepolia 地址待核对) |
Completes ② (aastar-sdk#266 / create-with-tier-profile). Onboarding one-shot: the user picks a spending profile (Web3 Beginner / Trader / Conservative) at account creation and their ETH + USDC/USDT tier limits are baked into the account at birth — instead of the aPNTs-gated post-create tier-setup.
lib/tier-profiles.ts— business config: 3 profiles × { ETH (SDKREFERENCE_ETH_PROFILES), USDC, USDT } ceilings (user-confirmed defaults, movable to the config center later).resolveTierProfile()(@aastar/sdk/kms0.35.0) → passes{ dailyLimit, initialTokens, initialTokenConfigs }toprepare-create-with-passkey(bigints → base-unit strings).initialTokens/initialTokenConfigs(TokenTierConfigDto); service converts strings→bigint intoprepareCreateAccountWithPasskey.ETH tier1/tier2 still finalize post-deploy via tier-setup self-pay (#418) — folds into birth once airaccount-contract#161 lands,
resolveTierProfileAPI unchanged. backend+frontend tsc+lint+build green.ethTierLimitsto tier-setup after deploy so ETH tier1/tier2 is one guided tap.