Skip to content

feat(cli): add exchange-rates, crypto, discoveries, uma-providers, tokens, and internal-account update/export#712

Open
jklein24 wants to merge 1 commit into
07-19-grid-cli-cards-auth-planfrom
07-19-grid-cli-quick-wins
Open

feat(cli): add exchange-rates, crypto, discoveries, uma-providers, tokens, and internal-account update/export#712
jklein24 wants to merge 1 commit into
07-19-grid-cli-cards-auth-planfrom
07-19-grid-cli-quick-wins

Conversation

@jklein24

Copy link
Copy Markdown
Contributor

Summary

Rounds out the Grid CLI with the high-value "quick win" endpoints from the audit. Stacked on #704.

New commands

  • grid exchange-ratesGET /exchange-rates (--source-currency, repeatable --destination-currency, --sending-amount)
  • grid crypto estimate-feePOST /crypto/estimate-withdrawal-fee
  • grid discoveriesGET /discoveries (receiving-institution lookup)
  • grid uma-providersGET /uma-providers (counterparty providers, paginated)
  • grid tokens list|get|create|revoke — API token management (create returns the clientSecret once — noted in help/output)
  • grid internal-accounts update|export — the two signed internal-account operations, reusing the --wallet-signature / --request-id header support (they surface the 202 challenge like the other signed ops; the CLI does not compute the stamp, generate keys, or decrypt)

Supporting change

  • buildUrl now sends array query params as repeated keys (for exchange-rates --destination-currency).

Test plan

  • cd cli && npm run build — clean compile.
  • npm test — 9 new boundary tests (67 total with the rest of the stack), asserting each command's method/path/query/body/headers.

Follow-up (noted, not in this PR)

customers update can hit a signed-retry (202) when changing email/phone for Embedded-Wallet customers; it doesn't yet accept --wallet-signature/--request-id. Worth wiring up in a follow-up (needs the signed helper positioned in the stack).

Original PR: #705

@vercel

vercel Bot commented Jul 19, 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 20, 2026 10:16pm
grid-wallet-demo Ignored Ignored Preview Jul 20, 2026 10:16pm

Request Review

akanter commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@greptileai review

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

   \m/ GRID CLI SHREDS ON \m/
 __|_____|_____|_____|_____|__
|  RIFF · RIFF · RIFF · RIFF  |
|_____________________________|
  "Compile or Die Trying"

Rounds out the Grid CLI with six new command groups — exchange-rates, crypto estimate-fee, discoveries, uma-providers, tokens, and internal-accounts update/export — plus a targeted buildUrl enhancement that serializes array-valued query params as repeated keys.

  • buildUrl now correctly emits ?destinationCurrency=EUR&destinationCurrency=MXN for string[] params; the QueryParams type is updated to advertise this capability, and the change is covered by an integration test.
  • All new commands follow the established CLI pattern: getClient guard, input validation with process.exitCode = 1 on bad input, and outputResponse for API results; the two signed internal-accounts operations correctly reuse addSignedOptions / validateSignedOptions / signedHeaders from signed.ts.

Confidence Score: 5/5

Safe to merge — all new commands are additive, follow established patterns, and are covered by integration tests.

Every new command is a thin wrapper over existing client infrastructure; input validation is consistent with the rest of the CLI (strict integer guards where required, NaN guard on pagination limits); the buildUrl array change is correct and tested; signed-retry wiring correctly delegates to the shared signed.ts helpers.

No files require special attention.

Important Files Changed

Filename Overview
cli/src/client.ts Added QueryParams export type and array-aware buildUrl logic; arrays emit repeated query-param keys via searchParams.append. Clean, backward-compatible change.
cli/src/commands/exchange-rates.ts New exchange-rates command with repeatable --destination-currency (via collect coercer) and strict /^\d+$/ + isSafeInteger validation on --sending-amount.
cli/src/commands/crypto.ts New crypto estimate-fee subcommand; uses the same strict integer guard (/^\d+$/ + isSafeInteger) as described in the PR notes.
cli/src/commands/discoveries.ts Minimal discoveries GET command; passes optional country/currency filters directly — no validation needed for opaque ISO codes.
cli/src/commands/uma-providers.ts New uma-providers list command; --has-blocked-providers boolean flag correctly mapped to `true
cli/src/commands/tokens.ts Full token CRUD (list/get/create/revoke); create notes one-time clientSecret in description; revoke gates deletion behind --yes or an interactive confirmation.
cli/src/commands/internal-accounts.ts Signed update/export subcommands; correctly chains addSignedOptions → validateSignedOptions → signedHeaders and validates --private-enabled as strict `true
cli/test/quick-wins.test.ts 9 new boundary tests covering method, path, query/body params, headers, and rejection of invalid inputs for every new command.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant CLI
    participant GridClient
    participant API

    Note over CLI: exchange-rates / discoveries / uma-providers / tokens list|get
    User->>CLI: grid exchange-rates --destination-currency EUR --destination-currency MXN
    CLI->>GridClient: "get("/exchange-rates", {destinationCurrency: ["EUR","MXN"]})"
    GridClient->>API: "GET /exchange-rates?destinationCurrency=EUR&destinationCurrency=MXN"
    API-->>CLI: "{ data: [...] }"

    Note over CLI: tokens create / crypto estimate-fee / tokens revoke
    User->>CLI: grid tokens create --name "CI" --permissions VIEW,TRANSACT
    CLI->>GridClient: "post("/tokens", { name, permissions })"
    GridClient->>API: POST /tokens
    API-->>CLI: "{ id, clientSecret (once) }"

    Note over CLI: internal-accounts update|export (signed-retry flow)
    User->>CLI: grid internal-accounts update id --private-enabled true
    CLI->>GridClient: "patch("/internal-accounts/id", { privateEnabled: true })"
    GridClient->>API: PATCH /internal-accounts/id
    API-->>CLI: "202 { requestId, challenge }"
    User->>CLI: re-run + --wallet-signature stamp --request-id id
    CLI->>GridClient: patch(..., headers: Grid-Wallet-Signature + Request-Id)
    GridClient->>API: PATCH /internal-accounts/id (signed)
    API-->>CLI: 200 OK
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"}}}%%
sequenceDiagram
    participant User
    participant CLI
    participant GridClient
    participant API

    Note over CLI: exchange-rates / discoveries / uma-providers / tokens list|get
    User->>CLI: grid exchange-rates --destination-currency EUR --destination-currency MXN
    CLI->>GridClient: "get("/exchange-rates", {destinationCurrency: ["EUR","MXN"]})"
    GridClient->>API: "GET /exchange-rates?destinationCurrency=EUR&destinationCurrency=MXN"
    API-->>CLI: "{ data: [...] }"

    Note over CLI: tokens create / crypto estimate-fee / tokens revoke
    User->>CLI: grid tokens create --name "CI" --permissions VIEW,TRANSACT
    CLI->>GridClient: "post("/tokens", { name, permissions })"
    GridClient->>API: POST /tokens
    API-->>CLI: "{ id, clientSecret (once) }"

    Note over CLI: internal-accounts update|export (signed-retry flow)
    User->>CLI: grid internal-accounts update id --private-enabled true
    CLI->>GridClient: "patch("/internal-accounts/id", { privateEnabled: true })"
    GridClient->>API: PATCH /internal-accounts/id
    API-->>CLI: "202 { requestId, challenge }"
    User->>CLI: re-run + --wallet-signature stamp --request-id id
    CLI->>GridClient: patch(..., headers: Grid-Wallet-Signature + Request-Id)
    GridClient->>API: PATCH /internal-accounts/id (signed)
    API-->>CLI: 200 OK
Loading

Reviews (3): Last reviewed commit: "feat(cli): add exchange-rates, crypto, d..." | Re-trigger Greptile

Comment thread cli/src/commands/exchange-rates.ts
Comment thread cli/src/commands/tokens.ts
@ls-bolt
ls-bolt Bot force-pushed the 07-19-grid-cli-cards-auth-plan branch from b0aab72 to ff7cc64 Compare July 19, 2026 18:46
@ls-bolt
ls-bolt Bot force-pushed the 07-19-grid-cli-quick-wins branch from cf31175 to b14f21d Compare July 19, 2026 18:46
@ls-bolt

ls-bolt Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@greptileai review

@jklein24
jklein24 force-pushed the 07-19-grid-cli-cards-auth-plan branch from ff7cc64 to 893e326 Compare July 20, 2026 22:16
…kens, internal-account update/export

Read/lookup commands (exchange-rates, crypto estimate-fee, discoveries,
uma-providers), API token CRUD (tokens list/get/create/revoke), and the two
signed internal-account operations (update, export) reusing the
--wallet-signature/--request-id header support. Extends buildUrl to send array
query params (exchange-rates --destination-currency). vitest boundary tests
cover each.
@jklein24
jklein24 force-pushed the 07-19-grid-cli-quick-wins branch from b14f21d to 5120c4b Compare July 20, 2026 22:16
@jklein24
jklein24 marked this pull request as ready for review July 21, 2026 06:02
@jklein24
jklein24 requested a review from pengying July 21, 2026 23:50
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