Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.superform.xyz/llms.txt

Use this file to discover all available pages before exploring further.

The merkle publish endpoint returns the latest published merkle tree metadata for any vault. It is public — no authentication required. Use it to retrieve the proof artifact, verify the root hash, and check whether the published tree reflects the manager’s current active configuration.

Endpoint

GET /api/v1/merkle/published/{chain_id}/{vault_address}
Base URL: https://erebor.superform.xyz
Auth: None

Path Parameters

ParameterTypeDescription
chain_idintegerChain ID (e.g., 8453 for Base, 1 for Ethereum)
vault_addressstringVault contract address (checksummed or lowercase)

Response

Published tree

{
  "success": true,
  "data": {
    "is_stale": false,
    "published": true,
    "published_at": "2026-04-28T08:47:56.558012Z",
    "root_hash": "0xfadbeed8d842eabf62ae6388506ca506f716ab5722c21af61899baf04b2ed6dc",
    "s3_url": "https://erebor-merkle-trees-231862524346.s3.eu-north-1.amazonaws.com/vaults/8453/0x01c427580a2dfbdd894dabc4bff6c1dce7aab53c/e31ee747-c953-4a9d-ba28-0296c12397ec.json",
    "total_leaves": 4,
    "tree_id": "e31ee747-c953-4a9d-ba28-0296c12397ec"
  }
}

Not yet published

{
  "success": false,
  "published": false,
  "message": "no published tree found for this vault"
}

Response Fields

FieldTypeDescription
publishedbooleanWhether the manager has published a tree for this vault
published_atstringISO 8601 timestamp of the most recent publish
root_hashstring32-byte merkle root. Verify this against the onchain root in SuperVaultAggregator before using any proof
s3_urlstringDirect URL to the full proof JSON artifact
total_leavesintegerNumber of authorized (hook, params) combinations in the tree
tree_idstringUUID of the published tree version
is_stalebooleanWhether the published tree is out of date — see below

Understanding is_stale

is_stale: true when the published tree is not the vault’s current active tree (including the case where no current active tree exists). The published artifact at s3_url was generated from a config version that no longer matches the vault’s current state. When is_stale is true:
  • The root_hash in this response may no longer match the current onchain root
  • The proof artifact may not cover all currently authorized operations
  • Wait for the manager to re-publish before relying on these proofs for execution
When is_stale is false:
  • The published tree was generated from the manager’s current active config
  • The artifact is current, but still verify root_hash against the onchain SuperVaultAggregator state — publishing updates the off-chain record; the onchain root is updated separately through the proposal-timelock-execute cycle
Even when is_stale: false, always verify root_hash against the onchain SuperVaultAggregator before passing proofs to executeHooks(). The off-chain publish and the onchain root sync are independent operations.

Fetching the Proof Artifact

The s3_url is a direct public URL to a JSON file containing the complete merkle tree with all leaf proofs.
# 1. Get metadata
curl https://erebor.superform.xyz/api/v1/merkle/published/8453/0x01c427580a2dfbdd894dabc4bff6c1dce7aab53c

# 2. Fetch the proof artifact (use s3_url from response)
curl https://erebor-merkle-trees-231862524346.s3.eu-north-1.amazonaws.com/vaults/8453/0x01c427580a2dfbdd894dabc4bff6c1dce7aab53c/e31ee747-c953-4a9d-ba28-0296c12397ec.json

Proof Artifact Shape

The JSON at s3_url matches the MerkleTreeWithLeaves shape returned by GET /api/v1/merkle/proofs. Each leaf contains the hook address and name, encoded argument values, leaf hash, index in the tree, and the merkle proof path.
{
  "root_hash": "0xfadbeed8d842eabf62ae6388506ca506f716ab5722c21af61899baf04b2ed6dc",
  "leaves": [
    {
      "index": 0,
      "leaf_hash": "0x...",
      "hook_address": "0x...",
      "hook_name": "depositHook",
      "encoded_args": "0x...",
      "proof": ["0x...", "0x..."]
    }
  ]
}
Pass leaf.proof as strategyProofs[i] when calling executeHooks().

Caching

Responses are cached — 60 seconds on a successful hit, 30 seconds on a negative (unpublished) response. Build polling intervals of at least 60 seconds around this endpoint.

Error Codes

CodeMeaning
200Success — check data.published and data.is_stale
404Vault not registered in Erebor
500Internal error