Idem is currently self-hosted only — every deployment needs this configuration. Managed cloud is on the roadmap; this page won’t apply once it ships.
How detection works
EVM and Solana are event-driven — the provider pushes a webhook to Idem the moment a matching transfer happens. Tron has no webhook mechanism, so Idem polls the Tronscan REST API on a fixed interval instead. All three also run a one-time startup recovery sweep that replays anything missed since the last recorded checkpoint (for example, during a deploy) — this is not a second polling loop, just a catch-up pass. Whichever path a transfer arrives through, it only becomes a ledger entry if it matches a row inwatched_addresses — see Registering which addresses to watch below. Configuring a provider is necessary but not sufficient on its own.
Alchemy (EVM — Ethereum, Base, Polygon)
These map to
idem.chain.evm.rpc-url, idem.chain.evm-base.rpc-url, idem.chain.evm-polygon.rpc-url, and idem.chain.alchemy-webhook-signing-key in application.yaml, if you’re setting properties directly instead of via environment variables.
1
Set ALCHEMY_API_KEY
Leaving this blank silently disables all three EVM readers — no error at startup, they simply never activate. This is a deliberate opt-in design, not a bug, but it means a half-configured EVM setup looks identical to a fully-disabled one from the logs.
2
Create a Notify webhook in the Alchemy dashboard
Configure an “Address Activity” webhook pointed at
https://<your-host>/internal/webhooks/alchemy, signed with the same value you set as ALCHEMY_WEBHOOK_SIGNING_KEY.QuickNode (Solana)
These map to
idem.chain.solana.rpc-url, idem.chain.solana.batch-size (default 100), and idem.chain.quicknode-webhook-secret.
1
Set QUICKNODE_SOLANA_URL
Same silent-disable behavior as Alchemy applies — a blank URL means no Solana reader is ever constructed.
2
Create a QuickNode Stream
Point it at
https://<your-host>/internal/webhooks/quicknode, signed with QUICKNODE_WEBHOOK_SECRET.Signature validation is
HMAC-SHA256 over nonce + timestamp + rawBody — not the body alone. Idem expects all three headers together on every delivery: X-QN-Signature, X-QN-Nonce, and X-QN-Timestamp.Tron (Tronscan REST polling)
Maps to
idem.chain.tron.api-url (defaults to https://apilist.tronscan.org, so Tron detection is active out of the box) and idem.chain.tron.polling-interval-ms (default 5000).
Unlike Alchemy and QuickNode, there’s no dashboard or webhook to register — Tron polling starts working as soon as the app is running.
Fail-fast on missing webhook secrets
Registering which addresses to watch
Configuring providers makes Idem capable of seeing a transfer — it doesn’t tell Idem which transfers matter to you. That mapping lives in thewatched_addresses table: a row ties a specific wallet address and token contract, per tenant, to the debit/credit account pair that should receive the resulting journal entry.
There is currently no tenant-facing API to register a watched address — this is an operator/database-level step today. If you’re self-hosting, your deployment administrator needs to insert the row directly; it isn’t something you can do through the REST API or a dashboard yet.
Multi-replica deployments
If you’re running more than one replica (for example, on GKE), setIDEM_SCHEDULING_DISTRIBUTED_LOCK_ENABLED=true (maps to idem.scheduling.distributed-lock.enabled, default false). This ensures only one replica runs Tron polling and the startup recovery sweep at a time, backed by a ShedLock table. Single-instance and local setups can leave this unset.