Repository navigation
docs: add recovery and protocol exit guides, an error reference and reader routing - #600
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Three documentation changes, one commit per issue.
guides/recovery(by account state: nothing done, partly closed, merged, funds sent to an exchange without credit) andapi-reference/errors(all 106 registered codes grouped by part of a close, with status, retry guidance, meaning and what to show the user).troubleshooting-and-faqgains a "What state is my account in" table.introductionlinks the new reference and fixes its 404 row. Both pages are appended to the navigation and nothing moves.contributing/add-a-protocol-exit, linked fromCONTRIBUTING.md, whose scope list now includesapiandweband saysxbullis not a scope.docs/index.mdx, a "Where to read next" table at the top of the README, and a Documentation table that now lists every top-level docs page, the guide sets, the SDK, the API reference andSECURITY.md. No README section or page path is removed or renamed.Why
A failure halfway through an irreversible close is the worst moment to have only FAQ entries. Integrators need retry and display guidance per code, contributors need the two-place rule with real file paths, and a first-time visitor needs a route by audience.
Drift prevention (#517)
scripts/check-error-reference.mjsfails when a code inapps/api/src/common/error-codes.tshas no row inerrors.mdx, when a row names an unknown or duplicated code, when a Retry value is outsideYes | After fix | Check first | No, or when a row's status or meaning differs from the generated registry table inintroduction.mdx(itself guarded by the existing OpenAPI drift test). Wiring reuses existing jobs, no new job: a step in thedocsjob (its change filter now also matches the script anderror-codes.ts), andbun test scripts/check-error-reference.test.tsin theauditjob next to the other script tests (7 tests).The two-place rule, stated precisely (#519)
apps/playground/lib/verify.tsdeliberately omitsinvokeHostFunction(its comment, lines 37-40): demo accounts never hold DeFi positions. The guide therefore says a Soroban exit needs the API adapter plusapps/web/lib/stellar/verify.ts(viaexit-expectations.tsand the webEXIT_FUNCTIONS), and a new classic operation also needs the playground allowlist.Stub-protocol check: on a scratch checkout of origin/main I added a stub name to
DefiProtocoland ran tsc. It fails in exactly four places, which the guide names: APIPROTOCOLS(lib/contract-registry/index.ts), APIPROTOCOL_LABEL(lib/defi-exits/plan-exits.ts), webEXIT_FUNCTIONS(lib/contract-registry/index.ts) and webdescribe-position.ts. The playground and SDK compile unchanged, andcheck-apireports the SDK API report changing (hence thesdk.api.mdand version-bump step). Places the compiler does not catch (catalog.ts,octopos-adapter.tsSUPPORTED_PROTOCOLS, the response DTO'sDEFI_PROTOCOLS,exit-payouts.tswhose default silently returns no tokens, the matrix script, tests) are listed explicitly. The scratch checkout was deleted.Verification
bun run format:check,node scripts/check-docs-nav.mjs,node scripts/check-error-reference.mjs .,bun test scripts/check-error-reference.test.tspass. Each of the three commits passes the nav and error-reference checks on its own.mint broken-linksandmint validate(mint 4.2.778 on Node 22) pass.lychee --offline README.md CONTRIBUTING.md: 0 errors.docs/page they target is indocs/docs.json.Testnet reproduction (testnet only)
An API instance run from this branch with a scratch environment only:
API_KEYS, the public testnet RPC and Horizon URLs, no mainnet variable, no mediator or sponsor secret, and the repo's.env.localnever read. Four throwaway accounts funded by friendbot. The script lived outside the repo and was deleted.merge_destination_unusablesuccess,remaining.requiresAnotherCall: true(txa6b3944365c952742b9fd991bb0adf8b842fbd9ce377e266d33594251bdaec07)success, same hashclose/transactionsagain (resume)remaining.steps: 0; submitting it finished the mergeaccount_not_foundfor bothsubmit_rejected,details.resultCode: tx_too_latesuccessinvalid_signatureCode-derived only (not reproduced):
confirmation_timeout(needs a ledger stall), the failed mediator co-sign and fee sponsorship paths (need server-side signing keys, which were not used), and the exchange-credit state (needs a real exchange). Each is described from the code below.Where each factual claim in the recovery guide comes from
confirmation_timeoutapps/api/src/config/constants.ts:7-8(30 polls at 3 s),apps/api/src/lib/stellar/submit.ts:93,apps/api/src/close/close.controller.ts:525apps/api/src/config/constants.ts:6,apps/api/src/lib/close-api/build-transactions.ts:219,657;tx_too_latemessage atapps/api/src/lib/utils/errors.ts:53; reproduced aboveapps/api/src/lib/stellar/submit.ts:53-56; reproduced abovesubmit_rejectedcarriesdetails.resultCodeapps/api/src/close/close.controller.ts:529-537; reproduced abovesubmit_failedis the catch-all, including congestion after 3 triesapps/api/src/close/close.controller.ts:542,apps/api/src/lib/stellar/submit.ts:17,73-79Retry-Afterdefault of 30 s on every 503apps/api/src/common/error-envelope.filter.ts:19,31-33; the 429 header atapps/api/src/auth/rate-limiter.ts:117submitdocs/sdk/errors.mdx:49-51apps/web/lib/session/store.ts:4-27,apps/web/lib/session/recovery.ts:5-12,apps/web/app/[network]/page.tsx:20,65apps/web/hooks/useCloseExecution.ts:251,275,304; the mediator route only returns the signed XDR,apps/api/src/mediator/mediator.controller.ts:135account_not_foundapps/api/src/lib/close-api/domain-errors.ts:37-41; reproduced abovesource_sequence_too_farcannot be retriedapps/api/src/lib/close-api/merge-preflight.ts:84-97apps/web/components/execution/ExecutionWizard.tsx:400apps/api/src/mediator/mediator.controller.ts:90-114,docs/architecture.mdsection 11Support channels in the guide are only the ones already in the README and the community page (community channels, GitHub issues,
SECURITY.mdfor vulnerabilities). It states no response time.Retry column: codes not marked Yes or No
Counts: Yes 15, No 16, After fix 71, Check first 4. Rules: Yes means the identical request can succeed later; After fix means the request, account, plan or a stated period must change first; Check first means the outcome may be unknown; No means retrying cannot help. Derived from the throw sites and the
ApiErrorResponsedeclarations in each controller.Check first
confirmation_timeout: the 90 s poll ended (submit.ts:93-111), the transaction may still land.submit_failed: unhandled failure after the send step (close.controller.ts:542), the outcome is unknown.merged_account_not_found: the account being merged is gone, possibly because the close already finished.tx_not_verified: the hash is not a confirmed merge on that network (stats.controller.ts:98-104), check hash and network.After fix, change the request or credentials:
bad_request,invalid_address,invalid_addresses,invalid_body,invalid_decisions,invalid_destination,invalid_memo,invalid_network,invalid_owner,invalid_rate_limit,invalid_request,invalid_signed_xdr,invalid_source,invalid_spender,invalid_token,invalid_tokens,invalid_transaction_xdr,invalid_tx_hash,missing_parameters,missing_transaction,not_found,payload_too_large,request_failed,too_many_addresses,unauthorized,unprocessable_entity,unsupported_media_type,invalid_challenge(request a new challenge),invalid_signature(sign again),api_key_not_found,key_limit_reached.After fix, plan again or answer a decision:
quote_drifted(route changed),defi_positions_stale(detection out of date),soroban_token_route_lost(route disappeared),needs_decisions,conversion_floor_missing,conversion_provider_unrecognized,transfer_destination_missing,transfer_destination_unusable,destination_not_acknowledged,merge_destination_unusable(fund or change the destination),memo_required,unsupported_memo_type,signer_normalization_unsafe,trustline_cannot_be_left.After fix, act on the account or the protocol first:
aquarius_trustline_missing,phoenix_trustline_missing,soroswap_trustline_missing,blend_emissions_trustline_missing,blend_repay_asset_missing,backstop_emissions_unclaimed,backstop_withdrawal_not_queued,backstop_withdrawal_cooling_down(wait out the cooldown),withdraw_before_repay,defi_exit_blocked,defi_exit_unsupported,defi_positions_blocked,soroban_token_conversion_failed,soroban_token_conversion_unavailable,soroban_token_conversion_unsafe,soroban_token_needs_restore,soroban_token_transfer_failed,soroban_token_transfer_unsafe(choose a different disposition),revoke_needs_restore,revoke_simulation_failed.After fix, rebuild or resign:
submit_rejected(depends ondetails.resultCode, for exampletx_too_lateneeds a fresh transaction),transaction_structure_not_allowed,forward_amount_exceeds_balance,inner_fee_not_zero,fee_bump_exceeds_cap,operation_not_sponsorable.Your spot-check items:
confirmation_timeoutCheck first;submit_rejectedAfter fix;quote_driftedAfter fix;source_sequence_too_farNo (merge-preflight.ts:84-97, "Retrying does not help");registry_expiredNo (close.controller.ts:332-340, the registry must be re-verified by an operator);mediator_not_configuredNo (mediator.controller.ts:67-72, a server setup issue). All three 503 rows still carryRetry-After, which the page says explicitly does not make them retryable.Review notes
Security-sensitive documentation: the protocol-exit guide describes
verify()and transaction construction and needs closer review. No source underapps/orpackages/is touched. The PR assignee was left unset.Closes #517
Closes #519
Closes #520