Repository navigation
0.10.0
Stellar is the second chain. An order can be quoted in XLM, USDC or EURC, paid by memo id, text memo or muxed destination, synced from Horizon and settled under the same rule as on the XRPL — the payment record, the settlement policy and the five payment states are unchanged and shared.
Added
Core\Stellar\… and Port\StellarPaymentRepositoryInterface. A sibling of the XRPL stack, not a generalized multi-chain port: HorizonClient behind the internal PaymentSourceInterface (fixed SDF endpoints, 429 with Retry-After surfaced as HorizonException), SyncService (cursor per account and network, dedup by (hash, op_index), testnet-reset detection from the cursor's ledger bits with RESET_LEDGER_MARGIN, findFulfillmentFor() under the sum rule), StellarPayment, StellarAmount, Fulfillment, MemoIdService on the shared Identity\SequencePermutation, PaymentIntentService (stellar-xlm-payment, stellar-usdc-payment, stellar-eurc-payment), Schema (ledger_direct_stellar_payment, ledger_direct_stellar_memo) and the composition root LedgerDirectStellar::create(). PaymentIntent::NATIVE_ASSET_BY_CHAIN knows STELLAR => XLM.
Identifiers as decimal strings. The memo id, a muxed destination's id and a canonical MEMO_TEXT all name the same order; a foreign identifier may use the full uint64, so the repository port and the stored column carry strings and BIGINT UNSIGNED. INVARIANTS.md, "Stellar", has the precedence and the canonical-form rule.
Stellar\StablecoinRegistry with Circle's USDC and EURC issuers for mainnet and testnet, copied from Circle's documentation and confirmed against Horizon; the excerpt and Horizon's answers are checked in under tests/Stellar/fixtures/registry/ and the test compares the constants with both. Stellar\AccountInspector with Trustline and IssuerFlags answers the preconditions an adapter checks before quoting an issued asset (account exists, trust line with headroom, issuer flags), cached over PSR-16. Stellar\PaymentUri builds the SEP-0007 request the QR code encodes, memo always included — not yet verified by a wallet scan; the first adapter does that.
Prices. Price\XlmPriceProvider (Binance, Coingecko, Kraken, divergence filter), Price\EurcPriceProvider (Coingecko, EUR peg — the first non-USD peg), Price\AmountQuote and PriceService::quoteAmount() as the chain-neutral half of the quote; getCryptoPriceForOrder() delegates and keeps refusing non-XRPL assets.
Core\ChainCatalog, ChainDescriptor, AssetDescriptor. The chains and their assets as data for the adapters' configuration screens (label, native asset, networks, identifier label, account-format check; per asset the intent type, decimals, peg, issuer per network, trust-line requirement), derived from the intent services and registries and pinned by tests. forType() finds chain and asset from an intent's type. Additively extensible; the NFT strand will add capabilities here.
Sync\LedgerSyncInterface. Both syncs implement it; SyncThrottle::syncIfDue() accepts it (parameter type widened, nothing else changed).
Testing kit. Testing\InMemoryStellarPaymentRepository and StellarPaymentRepositoryContractTestCase for adapters, recorded Horizon answers from the testnet under tests/Stellar/fixtures/ (public data only, and only what a test reads), and the opt-in tests/Integration/Stellar/HorizonIntegrationTest.
Changed
INVARIANTS.mdgains the "Stellar" section (names in the record, identifiers, payment source, tables, testnet reset, oracles and pegs, preconditions, registry, known gaps) anddocs/testing.mdthe Stellar rows.- The 0.8.1 rule holds on Stellar as it does on the XRPL: a payment in the other asset class — XLM on a USDC order, an issued asset on an XLM order — is a foreign candidate,
wrong_assetwith the delivered amount when nothing in the quoted asset has arrived, put aside and logged once something has. An earlier state of the branch skipped it. - The schema test for the Stellar tables holds the 0.9.0 rule that no column may take a PostgreSQL system column name.
Fixed
- A payment from another network never counts, on either chain. The same key pair is an account on testnet and mainnet, the tag and memo counters are per account, and a refreshed quote keeps account and identifier. A merchant who switched the network could see a stored testnet payment settle a mainnet order, or show as
wrong_asset. Both syncs now skip a candidate whosenetworkdiffers from the intent's, with a warning, before any other check;INVARIANTS.md, "Settlement", states the rule. The XRPL sync had this gap since 0.1. Found by CodeRabbit. Stellar\PaymentUrinames the testnet passphrase (network_passphrase) on testnet requests; SEP-0007 assumes the public network without it.StellarPayment::isCanonicalIdentifier()and the account patterns inChainCatalogreject a trailing newline.PriceService::getCryptoPriceForOrder()refuses a non-XRPL asset before any oracle work.
Not in this release
RPC as a second payment source (CAP-67 transfer and mint events, to_muxed_id as a string for text memos) and Soroban/SAC transfers arriving as invoke_host_function. Both documented under "Stellar", Known gaps.
Upgrading
Nothing changes for XRPL code; no existing public symbol changed. An adapter that adds Stellar creates the two tables from Stellar\Schema::tables() or Stellar\Schema::mysql(), implements StellarPaymentRepositoryInterface (and runs the contract test case against it), configures the receiving account per chain through ConfigProviderInterface and composes with LedgerDirectStellar::create(). The configuration screens come from ChainCatalog; the cross-adapter handover "Chain-Auswahl in der Konfiguration" describes the layout.
Full Changelog: 0.9.0...0.10.0