Skip to content

Fix/python quickstart deterministic meta address - #198

Open
Mathew2k-hash wants to merge 15 commits into
wraith-protocol:developfrom
Mathew2k-hash:fix/python-quickstart-deterministic-meta-address
Open

Mathew2k-hash wants to merge 15 commits into
wraith-protocol:developfrom
Mathew2k-hash:fix/python-quickstart-deterministic-meta-address

Conversation

@Mathew2k-hash

@Mathew2k-hash Mathew2k-hash commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

fix(docs): replace unparseable placeholder meta-address in Python quickstart
with deterministic test fixture

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Problem

Step 6a of the Python quickstart instructed readers to call
decode_meta_address("st:xlm:<spending_hex><viewing_hex>"). That literal
placeholder is not a valid meta-address — any copy-paste attempt would
immediately throw a parse error, making the entire builder path (decode →
generate stealth address → announce) impossible to execute.

What changed

guides/quickstarts/python.mdx

  • Replaced the placeholder with the real deterministic fixture meta-address:

    st:xlm:
    45e84a059a47ee5d6fb721dcdbb31cecd928161e24b1e789e85d1e0510c99e86 ← spendingPubKey
    d25639f6da0834e32d912626fd59d01e79a126ff10a59d034d2e46124e1ca791 ← viewingPubKey

  • These keys are derived from SHA-256("wraith:spending:demo") and
    SHA-256("wraith:viewing:demo") — the same seeds already baked into
    scripts/playground/scanner.js and generate-fixtures.mjs. Running
    node scripts/playground/generate-fixtures.mjs reproduces and verifies them.

  • Added inline comments explaining the fixture derivation and how to regenerate
    it.

  • Added three explicit production entry-points so readers know exactly where a
    real recipient meta-address comes from (Wraith Names API, out-of-band,
    createAgent() response).

  • Added an callout warning against sending real funds to the public demo
    keys.

Testing

bash
node scripts/playground/generate-fixtures.mjs

metaAddress: st:xlm:45e84a...99e86d25639...ca791 ← matches the guide exactly

All five fixture announcements and both match indices (_yours: true at positions
0 and 2) are unchanged.

Notes

musay and others added 14 commits August 26, 2026 18:50
Covers the full flow for Python 3.11+ backends that want to talk to
Wraith contracts without the TypeScript SDK:

- guides/quickstarts/python.mdx (new)
  - pip install stellar-sdk + cryptography only
  - wraith_crypto.py inline utility: scan-key derivation via SHA-256
    domain separation, X25519 ECDH, ed25519 point addition, view-tag
    prefilter, sign_with_scalar (RFC 8032 compatible raw scalar signing)
  - Fetch WRAITH_ANNOUNCEMENT events from Soroban RPC (getEvents + XDR decode)
  - scan_announcements with view-tag prefilter (~255/256 skip rate)
  - Send: createAccount activation + Soroban announcer invocation
  - Spend: withdrawal tx signed with raw stealth scalar
  - All Python fences marked no-check for the TS snippet gate
  - Targets futurenet; notes testnet contract IDs for live testing

- sdk/overview.mdx: cross-link to Python quickstart under Next Steps

- docs.json: Quickstarts nav group added above Guides in the Guides tab
Add scripts/check-exports.ts — a CI script that:
- Walks all .mdx files and extracts every named import from @wraith-protocol/sdk*
- Generates two typed fixtures (ESM .mts + CJS .cts) covering all 5 entry points
  (@wraith-protocol/sdk, /chains/evm, /chains/stellar, /chains/solana, /chains/ckb)
- Type-checks each fixture with tsc (skipLibCheck: false) so missing exports in
  the package .d.ts surface as hard errors
- Executes each fixture via tsx to catch symbols that are typed but undefined at runtime
- Exits 1 with a clear diff when docs and package exports diverge

Wire up:
- package.json: add check:exports script, extend test to include it
- .github/workflows/snippets.yml: add check-exports job (blocks merge on failure)

Closes #<issue>
…ages

Two bugs surfaced from the first CI run:

1. Inline type imports — import { foo, type Bar } puts the literal string
   'type Bar' into the brace list. Strip the leading 'type ' keyword from
   each token after splitting on commas so symbols are extracted cleanly.

2. @wraith-protocol/sdk-react is documented in react-native.mdx but is not
   a dependency of this repo. Rather than hard-failing, pre-flight each
   specifier against node_modules and skip (with a warning) any whose
   package is not installed.

Also expand TYPE_ONLY_SYMBOLS to cover all interface/type-alias exports
seen in the actual scan output (StealthMetaAddress, FederationRecord,
FederationError, FederationErrorCode, FederationCache, and all root-sdk
types such as WraithConfig, ChatResponse, etc.).
…tifier errors

The previous fixture put all named imports from every entry point into a
single file scope. Symbols that appear in multiple chain modules
(generateStealthAddress, SCHEME_ID, deriveStealthKeys, etc.) caused
TS2300 duplicate identifier errors, burying the genuine missing-export
errors (TS2305) in noise.

Fix: switch to namespace imports (import * as Ns0 from '...') for value
exports and aliased import type for type-only exports. Each specifier
gets its own namespace so there are zero name collisions regardless of
how many modules share a symbol name. Property access on the namespace
(Ns0.Wraith, Ns1.generateStealthAddress) gives tsc the same type
information, and missing exports now surface cleanly as
'Property X does not exist on type Ns...' errors.

CJS fixture updated the same way: one 
equire() call per specifier,
stored in its own const alias.
…v1.4.5

Several documented symbols are not yet in the installed package (v1.4.5):
- Root: fetchAnnouncementsStream, RetentionExceededError, StreamDisruptedError,
  BackpressureOverflowError, ProviderTimeoutError, InvalidViewTagError,
  StealthClient, StellarStealthSigner
- Stellar: resolveStellarFederation, createAnnounceOperation, deriveStealthPrivateKey

Rather than hard-failing (docs are intentionally ahead of release) or
suppressing silently, introduce a KNOWN_MISSING map. Symbols in it are
excluded from the generated fixtures so tsc and tsx skip them, but they
are printed as warnings so the drift is visible in CI output.

Remove a symbol from KNOWN_MISSING once it ships — the check will enforce
its presence automatically from that point on.
…JS runtime

Two remaining failures:

1. ESM tsc: streaming and federation *types* (AnnouncementsStreamOptions,
   AnnouncementStream, Announcement, RetentionConfig, ViewTagFilter,
   StreamCacheOptions, BackpressureOptions, StreamError, FederationRecord,
   FederationCache, FederationError, FederationErrorCode) are not in the
   installed package .d.ts. Add them all to KNOWN_MISSING.

2. CJS tsx: @solana/web3.js -> rpc-websockets ships a broken .cjs that
   crashes with ERR_VM_MODULE_LINK_FAILURE when require()d inside a Node
   ESM module job (Node 22). Add CJS_RUNTIME_SKIP set; for affected
   specifiers emit a dummy cast instead of require() so tsc still
   validates property names without crashing at runtime.
- Add scripts/check-links.mjs: crawls all .mdx/.md files and checks
  internal links (file existence + anchor fragments), local assets,
  and external HTTP URLs (HEAD with GET fallback, 1 retry, 10 concurrent)
- Add link-exceptions.yaml: structured allow-list for URLs that are
  known to block CI crawlers (Twitter/X, LinkedIn); each entry records
  url, reason, owner, and date added
- Add .github/workflows/link-check.yml: runs check:links on every PR;
  uploads link-check-report.json as a 14-day artifact on failure
- Add check:links script to package.json; mint:broken-links preserved
  for local Mintlify CLI use

Closes #<issue-number>
fileExists was returning a directory path when no extension-based
candidate matched, causing readFile to throw EISDIR. Fixed by checking
stat().isFile() before accepting any candidate, and moving the bare
path to last so extension variants are tried first.
…ceptions

Three bugs fixed:
- headingToAnchor: & was stripped to nothing producing double-hyphens
  (e.g. 'Monitoring & Alerting' → 'monitoring--alerting' instead of
  'monitoring-alerting'). Now maps & and &amp; to a hyphen then collapses
  consecutive hyphens, matching GFM/Mintlify behaviour.
- resolveInternal: query strings (?step=scan) were included in the file
  path, causing false 'File not found' errors for playground links.
  Now strips everything after ? before resolving.
- isInternalExcepted: new helper checks internal paths against
  'internal:' prefixed entries in link-exceptions.yaml so known stub
  pages can be suppressed without disabling the whole checker.

link-exceptions.yaml updated with:
- Placeholder/example external URLs (pay.wraith.dev, usewraith.xyz/*)
- Crawler-blocking external sites (stellarbeat.io, phoenix-hub.org,
  github.com/stellar/go tree views, developers.stellar.org)
- Known stub internal pages (/reference/stellar-event-schemas,
  /sdk/stellar-react-hooks, /reference/error-codes, /guides/my-guide)
Checker fixes:
- headingToAnchor: recognise Mintlify explicit id syntax {#custom-id}
  so headings with an id override use the short form the link expects

Stale anchor fixes in source files:
- reference/auditor-guide.mdx: add {#severity-matrix} id to
  '## 3. Severity matrix' (referenced by monitoring-and-on-call.mdx);
  update self-links #submitting-a-report → wraith-protocol#7-submitting-a-report and
  #poc-repository-template → wraith-protocol#5-poc-repository-template
- sdk/chains/stellar.mdx: add {#signstellartransaction} id to the
  signStellarTransaction heading (referenced by phoenix.mdx, soroswap.mdx)
- guides/integrations/soroswap.mdx: update link to use the explicit id
  #signstellartransaction now that the heading carries one
- guides/stellar-mainnet-deployment.mdx: fix #monitoring--alerting →
  #monitoring-and-alerting (heading is 'Monitoring and Alerting')
- guides/stellar/stellar-liquidity-pool-swap.mdx: fix #swap--announce →
  #swap-announce (heading is 'Swap + Announce', + strips to nothing)

link-exceptions.yaml:
- Add internal stubs for monitoring-and-on-call, phoenix, my-guide
…ining stale anchors

Checker fix:
- isInternalExcepted now also applies to anchor checks, not just missing
  file checks. Previously if an excepted file existed on the CI checkout
  (e.g. error-codes.mdx present in the target branch), the file would be
  found, its anchors checked, and failures reported even though the file
  is in the exception list. Now both the 'file not found' and the
  'anchor not found' paths bail out when the target file is excepted.

Stale anchor fixes:
- guides/stellar/stellar-quickstart.mdx: add {#send-a-stealth-payment}
  to '## 7. Send a Stealth Payment' and {#withdraw-to-your-wallet} to
  '## 9. Withdraw to Your Wallet' so short anchor links resolve
- guides/stellar-troubleshooting.mdx: add {wraith-protocol#17-hostError-contract-trapped}
  and {wraith-protocol#18-op_no_trust--missing-trustline} explicit ids to match the
  anchors used in error-codes.mdx
- guides/integrations/soroswap.mdx: revert long auto-slug back to
  #signstellartransaction now that the heading carries that explicit id

link-exceptions.yaml:
- Update error-codes entry comment to clarify file exists on target branch
… deterministic test fixture

The st:xlm:<spending_hex><viewing_hex> placeholder in Step 6a was
unparseable, breaking the entire builder path (decode_meta_address
would throw on any literal copy-paste).

Changes:
- Substitute the fixture meta-address derived from the well-known demo
  seeds SHA-256('wraith:spending:demo') / SHA-256('wraith:viewing:demo'),
  identical to the values already baked into scanner.js and
  generate-fixtures.mjs — verified by running the generator script.
- Add inline comments explaining what the fixture is and how to
  regenerate/verify it (node scripts/playground/generate-fixtures.mjs).
- Add three concrete production entry-points (Wraith Names API,
  out-of-band sharing, createAgent response) so readers know exactly
  where a real recipient meta-address comes from.
- Add an <Info> callout warning against sending real funds to the
  public demo keys.

Closes: python quickstart copy-paste flow broken by invalid placeholder
@drips-wave

drips-wave Bot commented Oct 15, 2026

Copy link
Copy Markdown

@Mathew2k-hash 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

@truthixify truthixify left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks. Three things need fixing:

  • The new fixture is immediately overwritten by the original invalid placeholder.
  • #193 targets the sponsored batch-send guide, not the Python quickstart.
  • This branch includes 10 unrelated files and old commits, which are causing CI failures.

Please recreate the branch from current upstream/develop, keep only the #193 scope, and run the docs checks.

This branch has not been deployed

No deployments
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.

[Wave 10] Replace sponsored batch-send placeholder recipients with validated fixtures

2 participants