Description
Anchor-issued assets used in StellarSplit invoices must have a valid stellar.toml file published at the asset issuer's home domain, but the SDK does not validate this before accepting custom assets. This issue adds a StellarTomlParser that fetches and parses stellar.toml files according to SEP-1, and an AnchorVerifier that cross-references the TOML metadata with on-chain account data to confirm the issuer account's home_domain points back to the TOML file (bidirectional verification).
Technical Context
- New file:
src/anchors/StellarTomlParser.ts and src/anchors/AnchorVerifier.ts; parsed result type: TomlMetadata mirrors the SEP-1 top-level fields
StellarTomlParser.fetch(domain: string): Promise<TomlMetadata> uses fetch() to retrieve https://{domain}/.well-known/stellar.toml and parses it with a lightweight TOML parser (@iarna/toml or equivalent)
AnchorVerifier.verify(assetIssuer: string, assetCode: string): Promise<VerificationResult> performs: (1) load issuer account from Horizon to get home_domain, (2) fetch TOML from home_domain, (3) assert TOML CURRENCIES array contains an entry matching assetCode and issuer
VerificationResult: { verified: boolean; tomlUrl: string; currencyEntry?: TomlCurrency; issues: string[] }
- TOML responses are cached for
tomlCacheTtlMs (default 3 600 000 ms) per domain
Acceptance Criteria
Description
Anchor-issued assets used in StellarSplit invoices must have a valid
stellar.tomlfile published at the asset issuer's home domain, but the SDK does not validate this before accepting custom assets. This issue adds aStellarTomlParserthat fetches and parsesstellar.tomlfiles according to SEP-1, and anAnchorVerifierthat cross-references the TOML metadata with on-chain account data to confirm the issuer account'shome_domainpoints back to the TOML file (bidirectional verification).Technical Context
src/anchors/StellarTomlParser.tsandsrc/anchors/AnchorVerifier.ts; parsed result type:TomlMetadatamirrors the SEP-1 top-level fieldsStellarTomlParser.fetch(domain: string): Promise<TomlMetadata>usesfetch()to retrievehttps://{domain}/.well-known/stellar.tomland parses it with a lightweight TOML parser (@iarna/tomlor equivalent)AnchorVerifier.verify(assetIssuer: string, assetCode: string): Promise<VerificationResult>performs: (1) load issuer account from Horizon to gethome_domain, (2) fetch TOML fromhome_domain, (3) assert TOMLCURRENCIESarray contains an entry matchingassetCodeandissuerVerificationResult:{ verified: boolean; tomlUrl: string; currencyEntry?: TomlCurrency; issues: string[] }tomlCacheTtlMs(default 3 600 000 ms) per domainAcceptance Criteria
fetch('example.com')retrieves and correctly parses all SEP-1 TOML sections (ACCOUNTS,CURRENCIES,VALIDATORS,DOCUMENTATION)verify('GABC...', 'USDC')returns{ verified: true }when the issuer'shome_domainTOML contains a matchingCURRENCIESentryverify()returns{ verified: false, issues: ['no_home_domain'] }when the issuer account has nohome_domainsetverify()returns{ verified: false, issues: ['currency_not_found'] }when the TOML exists but lacks theassetCodeentryfetch()call within TTL; after TTL, a fresh HTTP request is made