web/public-storefront/src/types.ts — Service carries price, network, no token field; whatever string the backend ships is rendered verbatim.
PaymentFlow.tsx — describes the x402 protocol generically (ERC-3009, X-PAYMENT). No USDC string anywhere.
ServiceCard.tsx — renders service.price/service.network as plain strings.
page.tsx — fetches /api/services.json (served by the controller's skill-catalog ConfigMap), no client-side currency assumptions.
internal/serviceoffercontroller/render.go::describeOfferPrice (pre-existing in main, not introduced by this PR) hardcodes "USDC/request", "USDC/MTok", "USDC/hour" regardless of offer.Spec.Payment.Asset.Symbol. Since First commit towards a demo sell command #355 now consumes this via buildServiceCatalogJSON and pipes the string straight to the storefront, an OBOL-Permit2-priced ServiceOffer would render as e.g. "0.001 USDC/request" on the public storefront even when the asset symbol is OBOL.
obol sell demo writes a ServiceOffer without the new payment.asset block (no Address/Symbol/TransferMethod/EIP712Name). It only sets scheme: exact, network, payTo, price.perRequest. Demos therefore default to whatever the controller treats as the unspecified-asset baseline (USDC). That's fine for the proof-of-payment use case but means the demo command doesn't exercise the OBOL Permit2 path.
Update describeOfferPrice to use offer.Spec.Payment.Asset.Symbol when set, falling back to "USDC".
Remaining insufficency identified in: #355 (comment)