Skip to content

[435] [High] Token Registry Admin API with On-Chain Metadata Verification - #549

Merged
james2177 merged 2 commits into
stellar-vortex-protocol:mainfrom
Goodnessukaigwe:fix/435-high-token-registry-admin-api-with-on-chain-metadata-verification
Sep 30, 2026
Merged

james2177 merged 2 commits into
stellar-vortex-protocol:mainfrom
Goodnessukaigwe:fix/435-high-token-registry-admin-api-with-on-chain-metadata-verification

Conversation

@Goodnessukaigwe

Copy link
Copy Markdown

Summary

  • Adds POST, PATCH, and DELETE /api/v1/admin/tokens behind the existing admin key and audit log.
  • Verifies ERC-20 (eth_getCode, decimals, symbol, name, including bytes32 symbols) and Stellar classic assets / SAC metadata before any write. A mismatch or missing contract persists nothing.
  • Soft-delist keeps the row (active / paused / delisted) so existing intents still resolve, hides delisted tokens from discovery, and emits token_list_updated.

Closes #435

Problem

Token registry changes were not an admin API and were not checked against on-chain metadata, so a bad symbol or decimals could be stored and used for new intents.

Solution

Identity is chain + address in the body. Status-only updates and delist do not call RPC, so an operator can pause a token during an outage. Cache invalidation is the in-memory snapshot reload (cacheGeneration). No automated token-list ingestion.

Config: EVM_RPC_URLS (JSON map of chain to JSON-RPC URL), SOROBAN_RPC_URL, and SHADOW_SOURCE_ACCOUNT for read-only SAC simulation.

Migration 20260929000000_token_registry_status adds status and asset_kind. Rollback drops those columns and the token_status enum. Intents do not foreign-key the token table.

Test plan

  • POST /api/v1/admin/tokens with a matching symbol and decimals returns 201 and lists the token
  • A decimals or symbol mismatch returns 400 METADATA_MISMATCH and does not persist
  • A missing contract returns 400 TOKEN_NOT_FOUND and does not persist
  • PATCH status to paused keeps the token listed but rejects new intent creates; DELETE hides it from discovery while resolve still returns it
  • Missing or wrong x-admin-key returns 401
  • A successful write emits token_list_updated

Made with Cursor

Admin create and update check ERC-20 and Stellar metadata and soft-delist tokens so existing intents keep resolving.

Co-authored-by: Cursor <cursoragent@cursor.com>
@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@Goodnessukaigwe Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…registry-admin-api-with-on-chain-metadata-verification

# Conflicts:
#	.env.example
#	.env.mainnet.example
#	.env.staging.example
#	.env.testnet.example
#	CHANGELOG.md
#	docs/runbooks/on-call.md
#	jest.config.js
#	package-lock.json
#	package.json
#	src/app.module.ts
#	src/common/stellar-signature.ts
#	src/config/configuration.ts
#	src/config/env.validation.ts
#	src/governance/governance.module.ts
#	src/intents/intents.gateway.spec.ts
#	src/intents/intents.gateway.ts
#	src/intents/intents.module.ts
#	src/intents/intents.service.shadow.spec.ts
#	src/intents/intents.service.spec.ts
#	src/intents/solver-intent-matcher.ts
#	src/intents/ws/connection-state.ts
#	src/solvers/solvers.controller.ts
#	src/soroban/event-ingestion.service.ts
#	src/soroban/signer.service.spec.ts
#	src/soroban/solver-registry.service.spec.ts
#	src/soroban/soroban.controller.spec.ts
#	src/soroban/soroban.module.ts
#	src/soroban/soroban.service.ts
#	src/soroban/stellar-tx.service.spec.ts
#	src/soroban/stellar-tx.service.ts
#	src/soroban/tx-confirmation.service.ts
#	src/tokens/in-memory-tokens.repository.ts
#	src/tokens/tokens.service.ts
#	src/treasury/treasury.service.spec.ts
#	src/treasury/treasury.service.ts
#	test/jest-e2e.json
@james2177
james2177 merged commit 9c897b0 into stellar-vortex-protocol:main Sep 30, 2026
const existing = this.require(chain, dto.address);
const metadataChange = dto.symbol !== undefined || dto.decimals !== undefined || dto.name !== undefined;
let next: TokenRecord = { ...existing, status: dto.status ?? existing.status ?? "active" };
if (metadataChange) {
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.

[High] Token Registry Admin API with On-Chain Metadata Verification

3 participants