## Summary
Adds first-class support for
ETH Swarm
hashes in the token metadata pipeline, mirroring the existing Arweave integration.
The implementation works with
any content stored on Swarm
, not just
/bzz
uploads — because the entry point is the 64-character keccak-256
hash
(content address), which is shared by:
  • /bzz/<hash>
    — regular chunk uploads
  • SOC (Single Owner Chunks) references
  • Feed manifests (which resolve to a content-address under the hood)
A 200 response from the Swarm gateway is therefore sufficient proof that the content exists, regardless of how it was originally uploaded.
---
## Changes
###
apps/explorer/lib/explorer/token/metadata_retriever.ex
| Addition | Purpose |
|---|---|
|
@invalid_swarm_path
| Error constant (mirrors
@invalid_ipfs_path
) |
|
swarm_link/1
| Builds
<gateway>/bzz/<hash>/
; defaults to
https://gateway.ethswarm.org
; overridable via
config :indexer, :swarm, gateway_url:
|
|
swarm_headers/0
| Returns
Authorization: Bearer <token>
when
config :indexer, :swarm, bearer_token:
is set — supports private / paid gateway nodes |
|
valid_swarm_hash?/1
| Validates 64-char lowercase hex Swarm hash |
|
bzz://
clause in
fetch_from_ipfs_or_ar?/5
| Routes
bzz://<hash>[/path]
URIs |
|
/bzz/<hash>
clause in
fetch_from_ipfs_or_ar?/5
| Routes plain HTTPS Swarm gateway URLs |
|
fetch_from_swarm/2
+
fetch_from_swarm_if_valid_hash/2
| Fetcher (mirrors
fetch_from_arweave/2
) |
|
swarm?/1
predicate | Threaded through host-filtering bypass, header selection, and
process_result/3
|
###
apps/explorer/test/explorer/token/metadata_retriever_test.exs
New describe blocks:
  • swarm_link/1
    — default gateway, custom gateway, trailing-slash stripping
  • swarm_headers/0
    — no token, bearer token configured
  • valid_swarm_hash?/1
    — valid, embedded path, uppercase, too short/long, empty, non-binary
  • ETH Swarm URI routing —
    bzz://
    scheme, plain HTTPS
    /bzz/
    , invalid hash error
---
## Configuration (optional)
```elixir
config/runtime.exs (or config.exs)
config :indexer, :swarm,
gateway_url: System.get_env("INDEXER_SWARM_GATEWAY_URL", "https://gateway.ethswarm.org"),
bearer_token: System.get_env("INDEXER_SWARM_GATEWAY_BEARER_TOKEN")
```
Both keys are optional — the module works with zero configuration using the public Swarm gateway.
---
## Related
Closes #<issue> (if any)
Follows the same pattern as the Arweave integration introduced in this commit.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
*
New Features
* Added Swarm network support for token metadata retrieval
* Support for bzz:// URI scheme and HTTP gateway-style paths
* Automatic metadata validation and fetching from Swarm storage
*
Tests
* Added comprehensive test coverage for Swarm metadata retrieval and URL handling
<!-- end of auto-generated comment: release notes by coderabbit.ai -->