0.28.20
New `AssetStore` lookups: `getByTokenId(String)` and `existsByTokenId(String)`.
Adapters honouring `AssetBind` during `TokenService.createAsset` can now confirm the bound asset is actually registered locally rather than silently echoing the supplied tokenId back into a fresh `SuccessfulAssetCreation`. Previously the contract only exposed lookup by FinP2P `assetId` — every adapter that wanted bind-validation had to copy `DbAssetStore` or trust the router blindly.
`DbAssetStore` impl uses jOOQ; `token_id` isn't `UNIQUE` at the DB layer so the lookup degrades gracefully when the same on-chain token was bound to multiple FinP2P assetIds — picks the first match, warn-logs, never throws.
Migration `V1004__index_assets_token_id.sql` adds a partial index on `assets.token_id` (`WHERE token_id <> ''`) so the lookup hits an index, and so the empty-string backfill rows V1002 left in 0.27.x → 0.28 upgrades don't surface from tokenId queries.
Not changed in this release: `VanillaServiceImpl.createAsset` still echoes the supplied tokenId back (today's behaviour). Wiring it to use the new lookup would convert silent-echo into fail-closed-reject — a behaviour change adapters should opt into deliberately rather than land in a patch.
Reported by SWIFT payment-rails. PR: #63