The Solana mediator anchors Archon DID batches on Solana by publishing Archon-formatted memos. It supports canonical SOL:mainnet-beta and SOL:devnet registries.
The mediator has two responsibilities:
pin when that registry is available, falls back to hyperswarm, and asks the Solana wallet service to submit a memo transaction.The memo payload intentionally does not validate Archon DID semantics. Gatekeeper remains the validation authority; Solana is used as a publication, ordering, and timestamping layer.
An Archon memo commits to the batch DID’s signed create operation. Import
uses gatekeeper.getGenesis(did) and reads the ordered didDocumentData.batch.ops list.
Retrieval checks identity/shape without requiring publisher authorization or
accepted DID history; contained operations are still authorized normally. A later
batch-asset update cannot
change the operations or their opidx values for the existing anchor. Missing
genesis content is retried rather than replaced with latest asset state.
Each import cycle also syncs finalized Solana block checkpoints into Gatekeeper for every produced block whose block height is at least ARCHON_SOL_START_BLOCK and divisible by 100. The mediator uses Solana slots as an internal scan cursor, but Gatekeeper block records and DID registration metadata use produced block heights so independent nodes can derive the same lower-bound timestamps.
Mediator metrics distinguish slot scan state from produced block heights:
solana_slot_cursor, solana_current_slot, solana_slot_lag, and solana_slots_scanned describe slot-based import scanning.solana_checkpoint_block_height and solana_current_block_height describe produced block heights.solana_block_height, solana_block_count, solana_blocks_pending, and solana_blocks_scanned names remain as compatibility aliases for the slot metrics.The Solana registries use the Solana Memo program with an Archon-specific payload prefix:
ARCHON_BATCH_V1:{"batchHash":"0x...","batchDid":"did:cid:...","opCount":1}
Every node on a canonical Solana registry should scan the same registry address and payload format. The default registry address is a deterministic ed25519 keypair derived from a SHA-256 of the literal string archon-solana-registry-signer-v1, the chain (e.g. SOL:mainnet-beta or SOL:devnet), and the Memo program ID; the wallet uses this keypair as a co-signer on every anchor so the address is genuinely controlled by all nodes. Wallet anchors include that address as a signer on the Memo instruction so discovery can query a narrow address instead of the global Memo program. A future custom Solana program can replace this format under a distinct registry name or explicit non-canonical configuration.
| variable | default | description |
|---|---|---|
ARCHON_NODE_ID |
none | Keymaster agent name used as batch controller |
ARCHON_GATEKEEPER_URL |
http://localhost:4224 |
Gatekeeper service URL |
ARCHON_KEYMASTER_URL |
none | Keymaster service URL |
ARCHON_WALLET_URL |
none | Solana wallet service URL |
ARCHON_ADMIN_API_KEY |
none | Admin API key for service-to-service calls |
ARCHON_SOL_CHAIN |
network derived | Gatekeeper registry name, e.g. SOL:devnet |
ARCHON_SOL_NETWORK |
mainnet-beta |
mainnet-beta, devnet, testnet, or local |
ARCHON_SOL_RPC_URL |
network derived | Solana JSON-RPC endpoint |
ARCHON_SOL_COMMITMENT |
confirmed |
Commitment for transaction submission/pending tracking; imports always use finalized |
ARCHON_SOL_MEMO_PROGRAM_ID |
Memo program | Solana Memo program ID to scan and publish to |
ARCHON_SOL_START_BLOCK |
0 |
First produced block height to checkpoint and import/register |
ARCHON_SOL_SIGNATURE_PAGE_LIMIT |
100 |
Signatures per getSignaturesForAddress page |
ARCHON_SOL_SIGNATURE_PAGE_MAX |
20 |
Maximum signature pages per import loop |
ARCHON_SOL_PENDING_TX_TIMEOUT_SLOTS |
150 |
Slots to wait before re-anchoring a stale pending transaction |
ARCHON_SOL_MIN_BALANCE_LAMPORTS |
10000000 |
Minimum wallet balance required before anchoring |
ARCHON_SOL_IMPORT_INTERVAL |
0 |
Minutes between import cycles; 0 disables importing |
ARCHON_SOL_EXPORT_INTERVAL |
0 |
Minutes between export cycles; 0 makes the mediator read-only |
ARCHON_SOL_REIMPORT |
true |
Reprocess discovered batches on startup |
ARCHON_SOL_DB |
json |
Database adapter: json, sqlite, mongodb, or redis |
ARCHON_SOL_DB_NAME |
chain derived | Persister file/key name, derived from the registry chain by default (transform: chain.replace(/:/g, '-')) |
ARCHON_SOL_METRICS_PORT |
4249 |
Metrics server port |
Gatekeeper’s processEvents().pending is a global queue count. When nonzero,
pendingBatches identifies the batch DIDs still represented in that queue.
After importing every CID, the mediator completes a batch only after a non-busy
processing result that has no pending events for that batch. Unrelated pending
events do not trigger reimports. This records processing completion, not final
authorization; retained history can still be replayed when missing evidence arrives.
Batch import logs report batchImport and batchComplete for this batch;
gatekeeperQueueAfterImport and gatekeeperProcessing describe the node-global
inbound queue. Persisted imported and processed keep the raw API responses.
Unavailable content, incomplete CID results, processing failures, and batches
with their own pending events remain retryable. Older Gatekeepers that omit
pendingBatches retain the conservative global-pending behavior. Persisted
“No progress” errors recover through the normal retry pass without database edits.
Discovery tips, signature listing, parsed transactions, and block retrieval all
use finalized, independently of ARCHON_SOL_COMMITMENT. Gatekeeper therefore
receives finalized Solana anchors; confirmed-only forks are not imported. This
relies on Solana finality and does not provide recovery from a finalized-chain
rollback. The setting still controls outbound transaction/pending tracking.
Previously imported confirmed-only evidence is not automatically audited by
this change; it prevents new discovery from using that weaker commitment.