> ## Documentation Index
> Fetch the complete documentation index at: https://docs.istravex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# wallet-backend pilot

> Running stellar/wallet-backend's own ingestion over the corpus, unmodified, and scoring what it produces.

Toy indexers prove the corpus discriminates. A real indexer proves it's useful. The pilot runs [stellar/wallet-backend](https://github.com/stellar/wallet-backend), SDF's backend for wallets, over every fixture and scores the result.

## How it works

Nothing in wallet-backend is changed or mocked except the network:

**1. Pinned checkout**

wallet-backend is cloned into `.cache/wallet-backend` at commit [`3e22515`](https://github.com/stellar/wallet-backend/commit/3e22515a44979fdc3a558fda3991ca2b48e38cef) (main, 12 November 2026).

**2. Adapter**

A small Go file, `kit/pilot/wallet-backend/adapter.go`, is copied in behind a build tag. It needs the module's internal packages, which is why it lives inside the checkout.

**3. Mock RPC**

The [mock RPC](https://docs.istravex.com/tools/mock-rpc.md) serves the corpus's canonical ledgers, one server per network.

**4. wallet-backend's own pipeline**

For each fixture, the adapter builds wallet-backend's own RPC ledger backend (`ingest.NewLedgerBackend`), fetches the fixture's ledger through `getLedgers`, and runs `indexer.ProcessLedger`, the same per-ledger function live ingestion calls. It prints what the indexer produced for the fixture's transaction. Nothing is written to a database; the output is exactly what ingestion would hand to persistence.

**5. Score**

`kit/pilot/score.mjs` compares that output with each fixture's expectations, field by field.

**6. Lint**

`istravex-lint` runs over the same checkout, and each finding is matched against a reviewed triage in `kit/pilot/wallet-backend/triage.json`. An untriaged finding fails CI.

```bash theme={null}
npm run pilot:wallet-backend   # → corpus/results/pilot-wallet-backend.json
```

## Results

| Fixture | Verdict | Checks |
| - | - | - |
| `cap15-fee-bump-pubnet-0001` | correct | ✓ fee\_charged ✓ fee debited from ✓ fee debit amount |
| `cap27-muxed-payment-pubnet-0001` | correct | ✓ recipient credited ✓ to\_muxed\_id |
| `cap40-signed-payload-signer-local-0001` | correct | ✓ signer ✓ weight |
| `cap40-signed-payload-signer-testnet-0001` | correct | ✓ signer ✓ weight |
| `cap73-sac-trust-local-0001` | correct | ✓ trustline operation ✓ asset ✓ limit ✓ TRUSTLINE state change |
| `cap73-sac-trust-testnet-0001` | correct | ✓ trustline operation ✓ asset ✓ limit ✓ TRUSTLINE state change |

**6 of 6 correct.** wallet-backend charges fee-bump fees to the right account at the charged amount, keeps the muxed ID exact (it stores `to_muxed_id` as text), records the full `P…` signer, and indexes the SAC trustline from metadata. On every pattern in the corpus, it already does what the [hardening guide](https://docs.istravex.com/guide/overview.md) asks.

## Lint

One finding, triaged **latent**:

```go internal/utils/ingestion_utils.go theme={null}
switch memoType {
case xdr.MemoTypeMemoNone:
    return nil, memoType.String()
case xdr.MemoTypeMemoText:
    if text, ok := memo.GetText(); ok {   // IX001
        return &text, memoType.String()
    }
case xdr.MemoTypeMemoId:
```

`utils.Memo` returns memo text as a Go string without UTF-8 validation. Nothing outside tests calls it at this commit and no migration has a memo column, so it isn't reachable today. It's worth a guard before memos are stored. Because it isn't a live bug, no upstream issue was filed.

## What the pilot taught us about our own code

The first version of the pilot driver passed wallet-backend's JSON output through `JSON.parse` and reported muxed IDs off by a few hundred. wallet-backend was right. The driver was rounding them, the exact bug the corpus exists to catch. The adapter now emits every 64-bit integer as a string.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.