fix(cli): resolve viem chain from chain_id during prepare/commit#250
Open
fix(cli): resolve viem chain from chain_id during prepare/commit#250
Conversation
…field The CLI read `kms_info.chain` (a viem Chain object) in three places: - `phala instances add` two-phase prepare/commit - `phala cvms replicate` two-phase prepare/commit - `phala deploy` on-chain registration during update Two problems with that: 1. `instances add` extracts `kms_info` from raw HTTP 465 error.structuredDetails, bypassing the SDK's KmsInfoSchema zod transform. The transform is the only place that injects `.chain`, so this path always threw "App KMS info is missing chain configuration" for on-chain KMS apps that needed prepare/commit. 2. The transform only injects `.chain` when chain_id is in SUPPORTED_CHAINS (mainnet / base / anvil). For unsupported chains, `replicate` and `deploy` would throw the same "missing chain configuration" message even though chain_id was present. Resolve from `chain_id` directly via SUPPORTED_CHAINS at the call site, and emit a clearer error when the chain is genuinely unsupported.
The CLI interface-compat tests spawn `bun cli/dist/index.js --help` for each command, so they hard-require the build to have run. Previously the prek config skipped build and went straight from type-check to test, causing 34 silent failures (empty stdout from missing dist) any time you came back to a fresh checkout. Same risk for js: cli consumes @phala/cloud through the workspace link to js/dist, so a stale js/dist makes cli tests run against outdated code. Mirror release-npm.yml's order (lint → type-check → build → test).
formatStructuredError used template-literal interpolation on detail.value, which produced "[object Object]" whenever the backend emitted dict or array values inside a structured error (e.g. HashRegistrationRequired carries kms_info and onchain_status as objects). The contract says these should be primitives, but the SDK shouldn't be the layer that crashes when reality drifts from contract. - Add formatStructuredErrorDetailValue: a pure helper that coerces any detail value to a renderable string (string passthrough, number/boolean via String(), null/undefined → "", everything else via JSON.stringify with String() fallback). - formatStructuredError uses the helper for the details section. - Export the helper so consumers (frontend dialog, etc.) can normalize using the same rule instead of duplicating it. The public type StructuredErrorDetail.value stays `unknown` so consumers that need the raw structure (e.g. CLI `instances add` extracting commit_token + kms_info from prepare payload) keep working unchanged.
Contributor
📋 Check Results✨ JS SDK - Code FormattingShow format check results🔍 JS SDK - TypeScript Type CheckShow type check output🧪 JS SDK - Test ResultsShow test output📝 JS SDK - Lint CheckShow lint results🌐 JS SDK - Browser CompatibilityShow browser test results🌐 Browser Compatibility ReportBrowser compatibility tests completed across:
The SDK has been verified to work in modern browser environments. Check run: https://github.com/Phala-Network/phala-cloud/actions/runs/25430405693 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three changes:
CLI chain resolution — `phala instances add`, `phala cvms replicate`, and `phala deploy` all read `kms_info.chain` (a viem `Chain` object), but that field is only populated by the JS SDK's `KmsInfoSchema` zod transform. `instances add` extracts `kms_info` from the raw HTTP 465 `error.structuredDetails` and bypasses the transform entirely, so the path always threw `App KMS info is missing chain configuration` for on-chain KMS apps that needed prepare/commit. The transform also only injects `.chain` when `chain_id` is in `SUPPORTED_CHAINS` (mainnet/base/anvil), so unsupported chains hit the same dead-end on `replicate` and `deploy`. Resolve from `chain_id` directly via `SUPPORTED_CHAINS` at the call sites and emit a clearer error when the chain id genuinely is not supported.
prek build step — CLI interface-compat tests spawn `bun cli/dist/index.js --help` for each command, so they hard-require the build to have run. Previously prek went lint → type-check → test, and a fresh checkout (no `dist/`) silently failed 34 tests with empty-stdout assertions. Mirror `release-npm.yml` order: lint → type-check → build → test, for both `js` and `cli` (cli consumes `@phala/cloud` through the workspace link to `js/dist`).
JS SDK detail-value rendering — `formatStructuredError` used `${d.value}` interpolation, producing `[object Object]` for dict / array values (e.g. `HashRegistrationRequired` carries `kms_info` and `onchain_status` as dicts). Add `formatStructuredErrorDetailValue` helper (string passthrough / `String()` for primitives / `JSON.stringify` for objects / `""` for nullish) and use it in the details section. The helper is exported so frontend consumers can apply the same normalization rule. `StructuredErrorDetail.value` keeps its `unknown` type so CLI consumers that need raw structure (e.g. `instances add` extracting `commit_token` from the prepare payload) keep working.
Repro for #1
User-reported: ScaleDialog on `cloud.phala.com` adding a replica to a node whose `device_id` isn't in the on-chain allowlist returned 465 with `kms_info` and `onchain_status` as dict values, which crashed the React error dialog. Frontend hotfix is in https://github.com/Phala-Network/phala-cloud-monorepo/pull/1304. The CLI side of the same flow is what this PR fixes.
```bash
cd cli && bun run build
./dist/index.js instances add \
--app-id 48da3ef94f5c5409c2c6df70f95474f41eb763a5 \
--node-id 1 \
--prepare-only
```
Before: throws `App KMS info is missing chain configuration`.
After: prints `App instance prepared successfully (pending on-chain approval)` with compose hash, app id, device id, commit token, commit URL.
Test plan