Skip to content

fix: separate Pocket API/RPC URLs, add 4-tier TX verification fallback#267

Merged
jorgecuesta merged 8 commits intostagingfrom
fix/separate-api-rpc-urls-tx-verification-266
Mar 31, 2026
Merged

fix: separate Pocket API/RPC URLs, add 4-tier TX verification fallback#267
jorgecuesta merged 8 commits intostagingfrom
fix/separate-api-rpc-urls-tx-verification-266

Conversation

@jorgecuesta
Copy link
Copy Markdown
Contributor

Summary

Closes #266

Production users reported stuck transactions (perpetual "Pending") and stale delivered keys after our latest release. Root cause: verifyTransaction depends on CometBFT RPC tx_index which doesn't serve historical TXs on our seed nodes, plus the DB stored API URLs in a column called rpcUrl.

Changes

  • DB schema: Rename rpcUrlpocketApiUrl, add pocketRpcUrl column
  • 4-tier TX verification in PocketBlockchain.getTransaction():
    1. RPC tx_index (StargateClient.getTx)
    2. REST API (/cosmos/tx/v1beta1/txs/{hash})
    3. Block scan (SHA256 raw TX bytes from block(height))
    4. Supplier existence check (circuit breaker)
  • TX expiration: Pending TXs older than 30 blocks marked as failed
  • Workflow workers: Read URLs from DB, seed from POKT_RPC_URL env on first boot
  • Setup forms: Dual inputs for Pocket API URL + RPC URL with presets
  • Provider key recovery: DeliveredKeyRecovery scheduled workflow for stale delivered keys (>24h)

Test plan

  • Docker build all 4 images
  • Unit tests pass (13/13)
  • Migration preserves existing data (RENAME COLUMN)
  • Setup form dual URL inputs + presets
  • ENV seeds DB on first boot
  • Stuck TX 57 (Ajes) resolves through fallback chain
  • Stale delivered key (JonatanM) recovers
  • See test-scenarios/ for 10 detailed QA checklists

#266)

- Rename DB column rpcUrl -> pocketApiUrl, add pocketRpcUrl column
- Add 4-tier TX lookup: RPC tx_index -> REST API -> block scan -> supplier check
- Workflows read URLs from DB, seed from POKT_RPC_URL env on first boot
- Setup forms now have dual inputs for API URL and RPC URL
- TX expiration: pending TXs older than 30 blocks marked as failed
- Provider key recovery: stale delivered keys (>24h) checked against chain state
- Add getTransaction tests with SHA256 block scan verification
- Add 10 test scenario checklists for manual QA
- getTransaction activity now returns executionHeight + unsignedPayload (was dead code)
- DAL update() methods scoped with WHERE clause by id (was updating all rows)
- updateKey() in recovery passes MAX_SAFE_INTEGER for lastUpdatedHeight (was silent no-op)
- Block scan guards results.results[i] against undefined
- Top-level imports for sha256/toHex instead of dynamic imports
- Remove stray console.log(applicationSettings) in Blockchain.ts
- Show pocketRpcUrl in provider overview and stepper summary
- Fix TS2345: guard txs[i] and log args against undefined
- Fix getTransaction activity: include executionHeight + unsignedPayload
- Fix DAL update() methods: scope with WHERE clause by id
- Fix remediateSupplier: return success instead of throwing when supplier not found
- Move delivered/missing_stake >24h recovery into SupplierStatus (remove separate workflow)
- Bootstrap seeds: backward compat with old rpcUrl field name
- Bootstrap example JSONs: use pocketApiUrl + pocketRpcUrl
- Settings forms: add RPC endpoint validation (/status), better error messages,
  disable Save during validation and when errors exist, add field descriptions,
  align help text with px-1
- Add ValidateRpcEndpoint server action for both apps
- Update test scenarios README with pass/fail status
…in all forms

- Setup + settings forms: validate RPC URL via /status endpoint with debounce
- Cross-validate API and RPC chain IDs match in all 4 forms
- Replace raw "fetch failed" errors with descriptive messages
- Disable Next/Save buttons during validation and when errors exist
- Fix middleman setup page top padding (pt-14)
- Reorganize middleman setup form layout (App Identity full width, API+RPC side by side)
@jorgecuesta jorgecuesta force-pushed the fix/separate-api-rpc-urls-tx-verification-266 branch from f799daa to 29deeb7 Compare March 31, 2026 01:51
@jorgecuesta jorgecuesta added the release Trigger staging deploy on merge to staging label Mar 31, 2026
@jorgecuesta jorgecuesta merged commit a676150 into staging Mar 31, 2026
6 checks passed
@jorgecuesta jorgecuesta deleted the fix/separate-api-rpc-urls-tx-verification-266 branch March 31, 2026 02:00
jorgecuesta added a commit that referenced this pull request Mar 31, 2026
* fix: separate Pocket API/RPC URLs, add 4-tier TX verification fallback (#267)

* fix: separate Pocket API/RPC URLs, add 4-tier TX verification fallback (#266)

- Rename DB column rpcUrl -> pocketApiUrl, add pocketRpcUrl column
- Add 4-tier TX lookup: RPC tx_index -> REST API -> block scan -> supplier check
- Workflows read URLs from DB, seed from POKT_RPC_URL env on first boot
- Setup forms now have dual inputs for API URL and RPC URL
- TX expiration: pending TXs older than 30 blocks marked as failed
- Provider key recovery: stale delivered keys (>24h) checked against chain state
- Add getTransaction tests with SHA256 block scan verification
- Add 10 test scenario checklists for manual QA

* fix: address review findings — critical bugs and quality issues

- getTransaction activity now returns executionHeight + unsignedPayload (was dead code)
- DAL update() methods scoped with WHERE clause by id (was updating all rows)
- updateKey() in recovery passes MAX_SAFE_INTEGER for lastUpdatedHeight (was silent no-op)
- Block scan guards results.results[i] against undefined
- Top-level imports for sha256/toHex instead of dynamic imports
- Remove stray console.log(applicationSettings) in Blockchain.ts
- Show pocketRpcUrl in provider overview and stepper summary

* chore: update pnpm-lock.yaml for @cosmjs/tendermint-rpc dependency

* fix: review fixes, UX improvements, remove DeliveredKeyRecovery workflow

- Fix TS2345: guard txs[i] and log args against undefined
- Fix getTransaction activity: include executionHeight + unsignedPayload
- Fix DAL update() methods: scope with WHERE clause by id
- Fix remediateSupplier: return success instead of throwing when supplier not found
- Move delivered/missing_stake >24h recovery into SupplierStatus (remove separate workflow)
- Bootstrap seeds: backward compat with old rpcUrl field name
- Bootstrap example JSONs: use pocketApiUrl + pocketRpcUrl
- Settings forms: add RPC endpoint validation (/status), better error messages,
  disable Save during validation and when errors exist, add field descriptions,
  align help text with px-1
- Add ValidateRpcEndpoint server action for both apps
- Update test scenarios README with pass/fail status

* chore: remove test-scenarios from PR (local QA tracking only)

* docs: update READMEs and bootstrap guide for dual API/RPC URL fields

* docs: document LOCALNET_ENABLED env var in DEVELOP.md

* fix(ui): RPC validation, chain ID cross-check, better error messages in all forms

- Setup + settings forms: validate RPC URL via /status endpoint with debounce
- Cross-validate API and RPC chain IDs match in all 4 forms
- Replace raw "fetch failed" errors with descriptive messages
- Disable Next/Save buttons during validation and when errors exist
- Fix middleman setup page top padding (pt-14)
- Reorganize middleman setup form layout (App Identity full width, API+RPC side by side)

* chore(deploy): update staging image to a676150

* chore(release): prepare v0.9.0 mainnet overlays [skip ci]

---------

Co-authored-by: Jorge S. Cuesta <jorge.s.cuesta@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Trigger staging deploy on merge to staging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant