Skip to content

fix(cli): reconcile existing Grid CLI commands with the current API - #702

Closed
ls-bolt[bot] wants to merge 2 commits into
mainfrom
07-18-grid-cli-drift-fixes
Closed

fix(cli): reconcile existing Grid CLI commands with the current API#702
ls-bolt[bot] wants to merge 2 commits into
mainfrom
07-18-grid-cli-drift-fixes

Conversation

@ls-bolt

@ls-bolt ls-bolt Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

This PR has been claimed. The active PR is now #709.

Summary

Reconciles every command the Grid CLI (cli/) already implements against the current 2025-10-13 OpenAPI surface. Focuses on correctness of existing commands — net-new endpoints/domains (agents, cards, sca, auth, tokens, …) are out of scope and tracked as follow-ups.

Bugs fixed (commands that built invalid requests)

  • customers update — now sends the required customerType discriminator and routes individual/business fields under the correct variant (previously every update was rejected).
  • customers create (business) — sends the required incorporatedOn; also validates the required legalName/taxId/incorporatedOn up front.
  • quotes createpurposeOfPayment moved to the top-level field (was buried in senderCustomerInfo and silently ignored).
  • sandbox receive — uses receivingCurrencyAmount/receivingCurrencyCode (were amount/currency, which don't exist), requires senderUmaAddress, and adds --customer-id.
  • accounts external create — uses the currency-suffixed *_ACCOUNT discriminators (USD_ACCOUNT, MXN_ACCOUNT, BRL_ACCOUNT, EUR_ACCOUNT, INR_ACCOUNT, …); drops the non-existent NGN purposeOfPayment and US accountCategory; requires a beneficiary (with a name) for fiat accounts.

Field / param drift added

  • quotes create: remittanceInformation, paymentRail, cryptoNetwork (stablecoin realtime funding), FBO customerId, scaFactor; quotes execute: scaFactor.
  • transfers out: remittanceInformation, destination paymentRail.
  • customers: KYB fields (NAICS, structured source-of-funds, expected-activity, counterparty countries, entity/business type, …), contact fields, nationality, id fields, and new list filters.
  • config update: supportedCurrencies, embeddedWalletConfig.
  • accounts: internal list --type, platform-endpoint param trimming, external-create swiftCode/ifsc/rail, platformAccountId, defaultUmaDepositAccount.
  • transactions list --account-identifier; approve receiverCustomerInfo.
  • receiver lookup-account: sender-uma / customer-id query params.

Other

  • Relaxed the client-side currency allowlist to a format check (it was rejecting ~24 currencies the API now supports).
  • error.details now maps the schema's inner details object instead of the whole error body.
  • Refreshed stale response TypeScript interfaces.
  • Added a vitest boundary-test harness (30 tests) — the CLI had none. Tests drive each command through argv parsing with fetch stubbed and assert the constructed request; every bug fix and guard is covered.

Breaking change

accounts external create --account-type values changed from the legacy rail names (US_ACCOUNT, CLABE, PIX, IBAN, UPI) to the API discriminators (USD_ACCOUNT, MXN_ACCOUNT, BRL_ACCOUNT, EUR_ACCOUNT, INR_ACCOUNT). The old values were already rejected by the API, so this is a fix rather than a regression. README updated; CLI version bumped 1.0.0 → 1.1.0.

Test plan

  • cd cli && npm install && npm run build — clean strict-mode compile.
  • npm test — 30 passing boundary tests.

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jul 19, 2026 1:36am
grid-wallet-demo Ignored Ignored Preview Jul 19, 2026 1:36am

Request Review

@ls-bolt ls-bolt Bot added the bolt label Jul 18, 2026
@ls-bolt ls-bolt Bot changed the title plan: fix drift on existing Grid CLI commands fix(cli): reconcile existing Grid CLI commands with the current API Jul 18, 2026
@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reconciles the Grid CLI's existing commands against the 2025-10-13 OpenAPI surface, fixing several commands that were building invalid requests and refreshing stale TypeScript interfaces. It also introduces a 30-test boundary harness using vitest that stubs fetch and asserts on emitted HTTP requests.

  • Bug fixes: customers update now sends the required customerType discriminator; sandbox receive corrects field names to receivingCurrencyAmount/receivingCurrencyCode and makes senderUma required; accounts external create uses currency-suffixed *_ACCOUNT discriminators and enforces a beneficiary for all fiat account types; quotes create moves purposeOfPayment to a top-level field.
  • Field/param additions: new filter params for customers list, transactions list, and accounts internal list; remittanceInformation, paymentRail, scaFactor, cryptoNetwork, and FBO customerId added across quotes, transfers, and accounts; config update gains supportedCurrencies and embeddedWalletConfig.
  • Test harness: test/helpers.ts properly resets process.exitCode between runs to prevent worker-exit false failures; the 30 tests cover every bug fix and guard introduced.

Confidence Score: 5/5

Safe to merge; the changes correct genuinely broken API requests across multiple commands and are well-covered by a new boundary test harness.

Every bug fix is substantiated by a failing-before/passing-after test. The process.exitCode reset in helpers.ts prevents cross-test contamination. The only open item is a UX gap where conflicting --source-account + --source-customer flags are silently resolved rather than rejected, which is not a correctness problem for the emitted request.

No files require special attention; cli/src/commands/quotes.ts has a minor ambiguous-flag UX gap worth addressing before the next release, but nothing that breaks current usage.

Important Files Changed

Filename Overview
cli/src/commands/accounts.ts Switches to currency-suffixed *_ACCOUNT discriminators, adds buildBeneficiary/validateBeneficiaryInput/isFiatAccountType helpers, enforces a beneficiary for all fiat account types, and adds platformAccountId, defaultUmaDepositAccount, and several new fields.
cli/src/commands/customers.ts Adds customerType discriminator to create/update, validates required business fields, adds KYB fields, contact fields, nationality/id fields, and new list filters; refactored into helpers for clarity.
cli/src/commands/quotes.ts Moves purposeOfPayment to a top-level field; adds remittanceInformation, paymentRail, cryptoNetwork, fboCustomer, scaFactor; updates Quote interface to match current schema.
cli/src/commands/sandbox.ts Fixes sandbox receive to use correct field names (receivingCurrencyAmount/receivingCurrencyCode), makes --sender-uma required, and adds --customer-id as an alternative receiver identifier.
cli/src/validation.ts Replaces the hardcoded currency allowlist with a format-only regex ^[A-Z0-9]{2,10}$; the uppercase-only pattern means lowercase inputs still produce a clear client-side error.
cli/test/helpers.ts New test harness using vitest; stubs fetch at the network boundary and correctly resets process.exitCode in the finally block to prevent cross-test leakage.
cli/test/accounts.test.ts Comprehensive boundary tests for external account creation, beneficiary validation, currency allowlist relaxation, and internal account list filtering.
cli/src/commands/transactions.ts Adds --account-identifier filter and --receiver-customer-info JSON option for approve; updates Transaction interface to current schema.
cli/src/commands/transfers.ts Adds --payment-rail and --remittance-information to transfers out; correctly nests paymentRail inside the destination object.
cli/src/index.ts Extracts program construction into buildProgram() so tests can call it without triggering process.argv parsing; guards main() with require.main === module.
cli/src/commands/config.ts Adds --supported-currencies and --embedded-wallet-config options with JSON parsing and proper error handling; updates PlatformConfig interface.
cli/src/commands/receiver.ts Adds --sender-uma and --customer-id query params to lookup-account; updates ReceiverLookup interface to current schema.
cli/src/parse.ts New utility that splits a comma-separated CLI flag into a trimmed, non-empty string array; handles empty/whitespace-only input gracefully.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["quotes create"] --> B{{"--source-account set?"}}
    B -- Yes --> C["sourceType: ACCOUNT\naccountId: sourceAccount\n[+ customerId if --fbo-customer]"]
    B -- No --> D{{"--source-customer OR\n--source-currency set?"}}
    D -- Yes --> E["sourceType: REALTIME_FUNDING\ncurrency: sourceCurrency\n[+ customerId if --source-customer]\n[+ cryptoNetwork if --crypto-network]"]
    D -- No --> F["No source in body"]
    G["Destination?"] --> H{{"--dest-account set?"}}
    H -- Yes --> I["destinationType: ACCOUNT\naccountId: destAccount\n[+ paymentRail if --payment-rail]"]
    H -- No --> J{{"--dest-uma set?"}}
    J -- Yes --> K["destinationType: UMA_ADDRESS\numaAddress: destUma\ncurrency: destCurrency"]
    J -- No --> L["No destination in body"]
    C --> G
    E --> G
    F --> G
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["quotes create"] --> B{{"--source-account set?"}}
    B -- Yes --> C["sourceType: ACCOUNT\naccountId: sourceAccount\n[+ customerId if --fbo-customer]"]
    B -- No --> D{{"--source-customer OR\n--source-currency set?"}}
    D -- Yes --> E["sourceType: REALTIME_FUNDING\ncurrency: sourceCurrency\n[+ customerId if --source-customer]\n[+ cryptoNetwork if --crypto-network]"]
    D -- No --> F["No source in body"]
    G["Destination?"] --> H{{"--dest-account set?"}}
    H -- Yes --> I["destinationType: ACCOUNT\naccountId: destAccount\n[+ paymentRail if --payment-rail]"]
    H -- No --> J{{"--dest-uma set?"}}
    J -- Yes --> K["destinationType: UMA_ADDRESS\numaAddress: destUma\ncurrency: destCurrency"]
    J -- No --> L["No destination in body"]
    C --> G
    E --> G
    F --> G
Loading

Reviews (4): Last reviewed commit: "feat(cli): fix drift on existing Grid CL..." | Re-trigger Greptile

Comment thread cli/src/validation.ts
Comment thread cli/src/commands/accounts.ts
Comment thread cli/src/commands/accounts.ts
Comment thread cli/test/quotes.test.ts Outdated
@ls-bolt
ls-bolt Bot force-pushed the 07-18-grid-cli-drift-fixes branch from 60355e8 to d829484 Compare July 19, 2026 01:01
@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Revision — addressed Greptile + Faraday review

Applied all findings from both reviews:

  • Currency validation (Greptile): tightened validateCurrency to ^[A-Z0-9]{2,10}$ so lowercase codes fail client-side with a clear error instead of being sent verbatim.
  • isFiatAccountType (Greptile): removed the redundant || === "SWIFT_ACCOUNT" clause (already covered by endsWith("_ACCOUNT")).
  • Beneficiary name/type (Greptile): added the reverse guard — --beneficiary-name without --beneficiary-type now errors.
  • Transaction --type help (Faraday): dropped CARD (the TransactionType enum is INCOMING/OUTGOING).
  • sandbox receive (Faraday): added a mutual-exclusivity guard for --uma-address / --customer-id.
  • Test coverage (Faraday): added cases for a wallet account type skipping the beneficiary requirement, a BUSINESS beneficiary, and a partial beneficiary address; moved the transfers out tests into test/transfers.test.ts (Greptile).

Declined (with reasoning): the --supported-currencies int64/JSON precision note (Faraday) — this is the general JS-number limitation for every int64 amount the CLI sends; realistic per-currency limits sit far below 2^53. Happy to add a systemic safe-integer guard across all amount inputs if preferred.

npm run build + npm test green.

@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread cli/test/helpers.ts
Reconcile every implemented command against the current 2025-10-13 schema.

Bug fixes (commands that built invalid requests):
- customers update: send required customerType discriminator; route
  individual/business fields under the correct variant
- customers create (business): send required incorporatedOn
- quotes create: move purposeOfPayment to the top-level field (was buried
  in senderCustomerInfo and ignored)
- sandbox receive: use receivingCurrencyAmount/receivingCurrencyCode and
  require senderUmaAddress; add --customer-id
- accounts external create: use currency-suffixed *_ACCOUNT discriminators,
  drop nonexistent NGN purposeOfPayment / US accountCategory, require
  beneficiary for fiat accounts

Field/param drift added:
- quotes create: remittanceInformation, paymentRail, cryptoNetwork, FBO
  customerId, scaFactor; quotes execute: scaFactor
- transfers out: remittanceInformation, destination paymentRail
- customers: KYB fields, contact fields, nationality, id fields, list filters
- config update: supportedCurrencies, embeddedWalletConfig
- accounts: internal list --type, platform-endpoint param trimming, external
  create swift/ifsc/rail, platformAccountId, defaultUmaDepositAccount
- transactions list --account-identifier; approve receiverCustomerInfo
- receiver lookup-account sender-uma/customer-id

Also: relax client-side currency allowlist to a format check, map error.details
to the schema's inner details object, refresh stale response interfaces, and add
a vitest boundary-test harness (25 tests) covering the fixes.
@ls-bolt
ls-bolt Bot force-pushed the 07-18-grid-cli-drift-fixes branch from 90b36db to 0364499 Compare July 19, 2026 01:36
@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@jklein24 jklein24 closed this Jul 19, 2026
jklein24 added a commit that referenced this pull request Jul 20, 2026
…709)

## Summary

Reconciles every command the Grid CLI (`cli/`) already implements against the current `2025-10-13` OpenAPI surface. Focuses on correctness of existing commands — net-new endpoints/domains (agents, cards, sca, auth, tokens, …) are out of scope and tracked as follow-ups.

### Bugs fixed (commands that built invalid requests)

- **`customers update`** — now sends the required `customerType` discriminator and routes individual/business fields under the correct variant (previously every update was rejected).
- **`customers create` (business)** — sends the required `incorporatedOn`; also validates the required `legalName`/`taxId`/`incorporatedOn` up front.
- **`quotes create`** — `purposeOfPayment` moved to the top-level field (was buried in `senderCustomerInfo` and silently ignored).
- **`sandbox receive`** — uses `receivingCurrencyAmount`/`receivingCurrencyCode` (were `amount`/`currency`, which don't exist), requires `senderUmaAddress`, and adds `--customer-id`.
- **`accounts external create`** — uses the currency-suffixed `*_ACCOUNT` discriminators (`USD_ACCOUNT`, `MXN_ACCOUNT`, `BRL_ACCOUNT`, `EUR_ACCOUNT`, `INR_ACCOUNT`, …); drops the non-existent NGN `purposeOfPayment` and US `accountCategory`; requires a `beneficiary` (with a name) for fiat accounts.

### Field / param drift added

- `quotes create`: `remittanceInformation`, `paymentRail`, `cryptoNetwork` (stablecoin realtime funding), FBO `customerId`, `scaFactor`; `quotes execute`: `scaFactor`.
- `transfers out`: `remittanceInformation`, destination `paymentRail`.
- `customers`: KYB fields (NAICS, structured source-of-funds, expected-activity, counterparty countries, entity/business type, …), contact fields, nationality, id fields, and new `list` filters.
- `config update`: `supportedCurrencies`, `embeddedWalletConfig`.
- `accounts`: internal `list --type`, platform-endpoint param trimming, external-create `swiftCode`/`ifsc`/`rail`, `platformAccountId`, `defaultUmaDepositAccount`.
- `transactions list --account-identifier`; `approve` `receiverCustomerInfo`.
- `receiver lookup-account`: `sender-uma` / `customer-id` query params.

### Other

- Relaxed the client-side currency allowlist to a format check (it was rejecting ~24 currencies the API now supports).
- `error.details` now maps the schema's inner `details` object instead of the whole error body.
- Refreshed stale response TypeScript interfaces.
- **Added a `vitest` boundary-test harness (30 tests)** — the CLI had none. Tests drive each command through argv parsing with `fetch` stubbed and assert the constructed request; every bug fix and guard is covered.

## Breaking change

`accounts external create --account-type` values changed from the legacy rail names (`US_ACCOUNT`, `CLABE`, `PIX`, `IBAN`, `UPI`) to the API discriminators (`USD_ACCOUNT`, `MXN_ACCOUNT`, `BRL_ACCOUNT`, `EUR_ACCOUNT`, `INR_ACCOUNT`). The old values were already rejected by the API, so this is a fix rather than a regression. README updated; CLI version bumped 1.0.0 → 1.1.0.

## Test plan

- `cd cli && npm install && npm run build` — clean strict-mode compile.
- `npm test` — 30 passing boundary tests.


Original PR: #702
jklein24 added a commit that referenced this pull request Jul 27, 2026
…#711)

## Summary

Adds the **cards** and **auth** domains to the Grid CLI, plus **signed-request header support** so the signed-retry flows are usable. Stacked on #702/#703.

### cards (`grid cards …`)
`list`, `get`, `create`, `update` (freeze/unfreeze/replace-sources/close), `reveal` (prints the short-lived `panEmbedUrl`). No `delete` — closing is `update --state CLOSED`.

### auth (`grid auth …`)
- `credentials` — `list`, `create`, `challenge` (OTP resend / passkey re-challenge), `verify`, `revoke`
- `delegated-keys` — `list`, `get`, `create` (with repeatable `--spending-limit CUR:amount`), `revoke`
- `sessions` — `list`, `refresh`, `revoke`

### Signed-request support
Many auth operations and `cards update` use Grid's signed-retry flow (first call returns `202` + `payloadToSign`; the retry carries a `Grid-Wallet-Signature` + `Request-Id`). This PR:
- extends `GridClient` so `get/post/patch/delete` accept optional headers;
- exposes `--wallet-signature` / `--request-id` on the signed operations.

**The CLI forwards a caller-supplied stamp — it does not compute the Turnkey/HPKE signature itself** (compute it with `scripts/embedded-wallet-sign.js` or your own tooling). Passkey create/verify likewise accept the WebAuthn `--attestation` / `--assertion` as JSON you produce client-side.

## Note on structure
The plan proposed cards and auth as two separate stacked PRs. They share the new `client.ts` header plumbing (and `auth` depends on it) and both touch `index.ts`, so I've kept them in one PR to avoid a fragile cross-branch split. Say the word if you'd prefer them separated.

## Test plan

- `cd cli && npm run build` — clean strict compile.
- `npm test` — 53 boundary tests (19 new for cards + auth), asserting each command's method/path/query/body/headers.

## Known follow-up

- Sensitive values (OIDC tokens, wallet signatures) are passed as flags today. Supporting file/stdin/env input for secrets is a sensible cross-cutting follow-up (also applies to the existing `configure --client-secret`) — not done here.


Original PR: #704
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants