Skip to content

feat(sdp-web): move token/RPC actions off the playground proxy - #1064

Merged
multipletwigs merged 3 commits into
mainfrom
feat/move-issuance-off-playground
Aug 4, 2026
Merged

feat(sdp-web): move token/RPC actions off the playground proxy#1064
multipletwigs merged 3 commits into
mainfrom
feat/move-issuance-off-playground

Conversation

@multipletwigs

Copy link
Copy Markdown
Collaborator

Route mint/burn/seize/freeze/pause/authority/allowlist/RPC-test calls through dedicated dashboard API wrapper routes instead of the generic /api/playground/execute proxy, so that route's only remaining consumer is the API playground shell. Reuses the shared dashboardFetch helper (extended with status/body) instead of hand-rolled fetch parsing.

Route mint/burn/seize/freeze/pause/authority/allowlist/RPC-test calls
through dedicated dashboard API wrapper routes instead of the generic
/api/playground/execute proxy, so that route's only remaining consumer
is the API playground shell. Reuses the shared dashboardFetch helper
(extended with status/body) instead of hand-rolled fetch parsing.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
sdp-docs Ready Ready Preview Aug 4, 2026 7:18am
sdp-web Ready Ready Preview Aug 4, 2026 7:18am

Request Review

@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves token mutations and RPC testing from the generic playground executor to dedicated authenticated dashboard routes.

  • Adds constrained proxy routes for issuance actions, metadata updates, allowlist mutations, and RPC tests.
  • Extends dashboardFetch to preserve HTTP status and error bodies.
  • Updates issuance and settings clients and their end-to-end coverage for the new routes.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sdp-web/src/lib/dashboard-fetch.ts Extends dashboard request results with HTTP status and parsed error-body details.
apps/sdp-web/src/app/api/dashboard/issuance/tokens/[tokenId]/[action]/route.ts Adds an allowlisted token-action proxy with encoded token identifiers.
apps/sdp-web/src/app/dashboard/issuance/[tokenId]/token-management-workspace.utils.ts Replaces playground execution envelopes with direct dashboard-route requests.
apps/sdp-web/src/app/dashboard/settings/organization-rpc-settings-form.tsx Routes RPC tests through the dedicated dashboard proxy while preserving the API success envelope.
apps/sdp-web/src/app/api/dashboard/issuance/tokens/[tokenId]/allowlist/[entryId]/route.ts Adds a dedicated encoded route for removing token allowlist entries.

Sequence Diagram

sequenceDiagram
  participant UI as Dashboard UI
  participant Route as Dedicated /api/dashboard route
  participant Proxy as proxyToSdpApi
  participant API as sdp-api
  UI->>Route: Mutation or RPC-test request
  Route->>Proxy: Fixed upstream path
  Proxy->>API: Project-scoped authenticated request
  API-->>Proxy: Status and response body
  Proxy-->>Route: Pass-through response
  Route-->>UI: Status and response body
Loading

Reviews (3): Last reviewed commit: "Merge branch 'main' into feat/move-issua..." | Re-trigger Greptile

@resourcefulmind resourcefulmind left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have looked through all 16 files. I think the direction here is right and the security shape is a real improvement: fixing
the upstream path server-side instead of accepting it from the request body is the actual win, and
proxyToSdpApi adding a required project scope makes these routes tighter than the playground path they
replace. Object.hasOwn for the action guard rather than in is the right call too.

Holding on the two red checks, because one of them is caused by this change.

1. The E2E helper still targets /api/playground/execute. issuance.e2e.spec.ts:153 matches on response.url().endsWith(“/api/playground/execute”) plus the old {“method”:…} envelope in the post body, then asserts payload.ok === true. This PR moves those actions off that URL and removes that envelope, so the predicate can never match and it times out at 180s — that’s the failing
“7. user can update an authority” shard.

Worth flagging that the helper is stale in three ways, not one: the URL, the postData.includes on the sdp-api path (which is no longer in the body), and the payload.ok assertion. So it needs updating to the new contract rather than a matcher tweak.

Also worth knowing the red test understates it. e2e-issuance.sh runs the shards sequentially under set -euo pipefail, so when authority and supply fails, freeze controls, pause controls and allowlist never run at all. Test 6 (allowlist) uses the same helper at :467 and :486, so it’s broken by this change too and is currently masked. Three shards of coverage are silently skipped.

Until that’s fixed, authority/mint/burn/seize/freeze/allowlist have no end-to-end cover: the new unit test mocks proxyToSdpApi entirely, so it proves the action→path map and the 404 guard and nothing about whether a request actually reaches sdp-api authenticated.

2. Translation Catalog Policy. check-catalog-change-policy.mjs rejects any PR touching both messages/en/** and a localized catalog, so the four en + fr edits trip it. Dropping the two fr files clears it.

Also, the policy’s rationale is that the translation agent adds missing keys on the release PR. These are deletions. If the automation doesn’t prune removed keys, dropping the fr edits leaves five orphaned French keys behind. @GuiBibeau owns #1022, you might want to confirm which way that cuts.

3. Non-blocking, on the new unit test. It covers the 404 path with “not-a-real-action”. The reason the route uses Object.hasOwn rather than in is #926 , with in, __proto__, constructor and toString all match and would proxy through. Worth adding those three to the 404 case so the guard is pinned and a later refactor back to in fails the test instead of quietly reopening it.

4. Non-blocking. In organization-rpc-settings-form.tsx the old code checked !envelope.body?.data before destructuring; the new one checks only !result.ok then reads result.data.data. A 200 with a malformed body now throws instead of returning the friendly message. It’s inside the existing try/catch so it degrades to a generic error, just noting it since rpcTestFailedStatus went away with it.

Happy to re-review as soon as the E2E is pointed at the new routes.

@multipletwigs
multipletwigs enabled auto-merge (squash) August 4, 2026 00:36
Rewrite waitForActionResponse for the new contract: match the dashboard
route URL + real HTTP method instead of the retired /api/playground/execute
envelope, and assert on the passed-through upstream status rather than the
playground's ok flag. Covers the allowlist shard (test 6) as well as the
authority shard that surfaced the failure.

Drop the fr catalog edits per the catalog change policy (translation
automation owns localized files), and pin the Object.hasOwn action guard
with __proto__/constructor/toString 404 cases.
@multipletwigs

multipletwigs commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed in 7954ba0:

1. E2E helperwaitForActionResponse now matches the new contract: dashboard route URL (/api/dashboard/issuance/tokens/…) + the real HTTP method, and asserts on the passed-through upstream status instead of the playground ok envelope.

2. Translation Catalog Policy — dropped the two fr catalog edits; the diff is now en-only, which the policy script accepts as source-only.

3. Action guard test — added __proto__, constructor, and toString to the 404 cases so a refactor back to in fails the suite.

4. Agreed it degrades to the generic catch message on a malformed 200; leaving as is since the route now passes through the upstream status, so a non-2xx upstream surfaces its real error via dashboardFetch.

@tobySolutions tobySolutions left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path fixed server side instead of read off the body is the real win here, and the project scope check makes these tighter than the playground route they replace.

Two things for follow up: result.data.data in the rpc form can still throw on a malformed 200, and there are 7 orphaned fr keys to prune not 5 (the two rpcTestFailed ones in dashboard-custody).

@multipletwigs
multipletwigs merged commit ce25f00 into main Aug 4, 2026
34 checks passed
@multipletwigs
multipletwigs deleted the feat/move-issuance-off-playground branch August 4, 2026 07:28
enochakinbode pushed a commit to enochakinbode/solana-developer-platform that referenced this pull request Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants