Canonical, version-pinned source of truth for everything off-chain Adrena services need to talk to the on-chain program:
- The Adrena IDL (Anchor 0.31 format)
- Oracle feed maps for ChaosLabs, Autonom, Switchboard (mainnet + devnet)
- Cross-provider feed metadata (provider ranges, sessioned flags, stablecoin slots)
- The canonical pool manifest + loader (pool name, address, custodies, lpMint, automation flags)
- Ported program state types + events + errors so off-chain consumers can decode raw account data and emitted events without bundling the on-chain program crate
- A signed artifact manifest with sha256 hashes of every shipped file
- Rust constants and
include_str!'d JSON for native consumers - An npm package (
@adrena/abi) that ships the same artifacts to TypeScript consumers
Both Rust services and TypeScript services pin the same git commit of this repo. There is no version drift between consumers, no service-local IDL copies, and no service-local feed maps. Bumping the canonical artifact is a one-place change here followed by a coordinated commit-hash bump across consumers.
adrena-abi/
├── Cargo.toml # Rust crate manifest
├── package.json # npm package manifest (@adrena/abi)
├── README.md # this file
├── idl/
│ ├── adrena.json # canonical IDL (Anchor 0.31 — has `address` field)
│ ├── adrena.d.ts # full preserved Adrena type for TS inference
│ └── adrena.ts # legacy const-style export (kept for transition)
├── configs/
│ ├── artifact_manifest.json # signed manifest with sha256s of every shipped file
│ ├── pools_manifest.json # canonical pool manifest (names, addresses, custodies, lpMint, feedIds, automation flags)
│ ├── pools_manifest_loader.ts # typed TS loader (types + validation + PDA derivation)
│ └── oracles/
│ ├── chaoslabs.{mainnet,devnet}.json # ChaosLabs feed map (slots 0..=29)
│ ├── autonom.{mainnet,devnet}.json # Autonom feed map (slots 30..=141)
│ ├── switchboard.{mainnet,devnet}.json # Switchboard feed map (slots 142..=255), on-chain bound
│ ├── switchboard_other.{mainnet,devnet}.json # OFF-CHAIN-ONLY map (ADX/ALP spot pricing)
│ └── feed_metadata.json # cross-provider metadata: ranges, stables, sessioned[symbol]
├── src/
│ ├── lib.rs # crate entrypoint, re-exports, declare_id, CPI account stubs
│ ├── feed_maps.rs # `include_str!` of every config JSON
│ ├── feed_ids.rs # provider ranges + USDC slots + crypto-block array
│ ├── oracle.rs # OracleProvider, BatchPrices, MultiBatchPrices, OraclePrice, math
│ ├── pda.rs # 29 PDA derivation helpers
│ ├── types.rs # instruction params + state account structs (Pool, Custody, Cortex, Position, Staking, ...)
│ ├── error.rs # AdrenaError enum (ported from program)
│ ├── events.rs # 14 #[event] structs (OpenPosition, ClosePosition, Liquidate, ...)
│ ├── pool_info_snapshot.rs # CustodyInfoSnapshotPda + SyntheticCustodyInfoSnapshotPda
│ ├── vest.rs # Vest zero-copy account decoder
│ ├── genesis_lock.rs # GenesisLock zero-copy account decoder
│ ├── user_profile_enums.rs # ProfilePicture, Title, Achievements enums + tables
│ ├── pools_manifest.rs # Rust-side pools_manifest loader + on-chain validator
│ ├── math.rs # fixed-point helpers (BPS, RATE, USD scaling)
│ ├── limited_string.rs # 32-byte bounded string
│ ├── liquidation_price.rs # liquidation-price formula
│ └── autonom_market_opening_data.rs # signed market-hours payload
└── tests/
├── artifact_hashes.rs # sha256-verifies every embedded file vs manifest
├── feed_metadata_consistency.rs # cross-references provider maps vs metadata
├── pools_manifest_consistency.rs # autonom feedIds in range, symbols registered, sessioned-vs-symbol agreement
├── oracle_invariants.rs # constants + provider routing + OraclePrice math
├── wire_format_invariants.rs # golden hashes for BatchPrices / AutonomMarketOpeningData / LimitedString layout
├── pinned_addresses.rs # program ID, mints, PDAs vs mainnet truth
└── no_dummy_in_production.rs # mainnet feed maps must not contain `_DUMMY: true` entries
Each provider's range starts with the same 6-asset crypto block at offset
+0..=+5 (SOL, jitoSOL, BTC, WBTC, BONK, USDC). Provider ranges are
hard-enforced by OracleProvider::feed_id_range in src/oracle.rs.
| Slot offset | Asset | ChaosLabs (0..=29) |
Autonom (30..=141) |
Switchboard (142..=255) |
|---|---|---|---|---|
| +0 | SOLUSD | 0 | 30 | 142 |
| +1 | JITOSOLUSD | 1 | 31 | 143 |
| +2 | BTCUSD | 2 | 32 | 144 |
| +3 | WBTCUSD | 3 | 33 | 145 |
| +4 | BONKUSD | 4 | 34 | 146 |
| +5 | USDCUSD | 5 | 35 | 147 |
USDC is the only feed where the on-chain code hardcodes the slot — see
get_confidence_from_price in src/oracle.rs. The hardcode
treats feed_id == 5 || feed_id == 35 || feed_id == 147 as stablecoin (0 bps
confidence band). Any change to the canonical USDC slot of any provider
requires editing both the feed map AND the on-chain constant in lockstep.
After the crypto block, Autonom carries the live commodity feeds:
| adrena_feed_id | Symbol | Status |
|---|---|---|
| 36 | XAU | live |
| 37 | XAG | live |
| 38 | WTI | live |
Future commodities (e.g. Brent) append at 39+ in coordinated releases that
bump autonom.mainnet.json, feed_metadata.sessioned, the adrena program
bootstrap ix, and the Autonom backend's feed_id_aliases.json in lockstep.
MrAutonom only manages market hours for sessioned symbols (XAU, XAG, WTI
today); the crypto block is 24/7 and is filtered out via
feed_metadata.sessioned[symbol].
configs/pools_manifest.json is the canonical inventory of live pools. Two
pools currently ship:
| Pool | Type | Address | LP mint | Custodies | Synthetic custodies |
|---|---|---|---|---|---|
main-pool |
gmx | 4bQRutgDJs6vuh6ZcWaPVXiQaBzbHketjbCDjL4oRN34 |
4yCLi5y…Uqwj (ALP) |
USDC, BONK, jitoSOL, WBTC | — |
commodities-pool |
autonom | GN2hyBVHcUitWETeDfAoeXDMqow1x8StqdRFnGaUB2vb |
GMZ7hCG…Lz5Cx (RWALP) |
USDC | XAU, WTI, XAG (slot order) |
Note: synthetic_custodies slot order is [XAU, WTI, XAG] because the WTI
proposal landed on chain before XAG. The Rust loader's
validate_and_build_pool_context performs Vec<Pubkey> equality against the
on-chain Pool.synthetic_custodies array and refuses to boot the pool on
order drift (commodities-pool gets quarantined).
Loaders enforce:
- Pool name uniqueness
getPoolPda(name) == address(catches typos)- Autonom pools must have non-empty
feedIds - All
feedIdsmust be validu8 - (Rust on-chain) custodies, syntheticCustodies, and lpMint must match the
live
Poolaccount field-for-field
Rust:
use adrena_abi::pools_manifest::{
load_pools_manifest_with_override,
validate_and_build_pool_context,
};TypeScript:
import {
loadPoolsManifestWithOverride,
resolvePoolContexts,
} from "@adrena/abi/configs/pools_manifest_loader";Every consumer accepts a --manifest-path <path> runtime override; the
embedded manifest is the default truth.
Every off-chain service pins this repo at a specific git commit. Pin updates are coordinated across all consumers — see "Bumping for a new release" below.
| Repo | Imports | Used for |
|---|---|---|
| MrOracle | feed-map constants + PDA helpers + oracle wire types | Provider range validation, embedded feed maps, on-demand Switchboard signing |
| MrSablier | Pool, Custody, Position, LeverageCheckType, PDA helpers |
Liquidation / SL-TP / limit-order automation |
| MrSablierStaking | Cortex, Pool, Staking, PDA helpers |
Staking-round resolution + reward distribution |
| MrNotification | events::* + BorshDeserialize re-export |
Anchor event decoding for every emitted event |
All four pin via Cargo.toml:
adrena-abi = { git = "https://github.com/AdrenaFoundation/adrena-abi.git", rev = "<commit-hash>" }| Repo | Imports | Used for |
|---|---|---|
| adrena-data/cron | IDL, autonom + switchboard feed maps, feed_metadata.json, pools_manifest.json |
AdrenaClient, oracle ingestion, processor seeding |
| adrena-data/api | IDL, pools_manifest.json (for primary pool selection) |
Datapi AdrenaClient + route handlers |
| adrena-data/processor | IDL (as CURRENT_IDL) |
Slot-keyed event decoder |
| adrena-data/enricher | IDL | Position/order enrichment |
| MrAutonom | IDL, autonom.mainnet.json, feed_metadata.json, artifact_manifest.json, pools_manifest.json |
Market-hours gating, sessioned-symbol filter |
| discord-bot | IDL, switchboard_other.mainnet.json, feed_metadata.json |
ADX/ALP price observability |
| frontend | IDL, pools_manifest.json |
AdrenaClient, pool-aware routing |
All pin via package.json:
"@adrena/abi": "github:AdrenaFoundation/adrena-abi#<commit-hash>"Variable names referencing "the current IDL" or "the current feed map" MUST
NOT bake in a release version number. Use neutral names like CURRENT_IDL,
AdrenaIdl, CURRENT_IDL_JSON. The bad pattern is something like
V2_1_0_IDL_JSON — that name forces a sweep-and-rename every time the
program ships a new release, which is exactly the kind of mechanical churn
this repo exists to eliminate.
The only exception is historical immutable snapshots. For example, in
adrena-data/processor/src/utils.ts, the slot-keyed dispatch table imports
each frozen historical IDL under a version-named binding:
import { IDL as V1_3_8_IDL } from './targetV1-3-8/adrena';That naming is correct because each VX_Y_Z_IDL literally refers to a frozen
artifact at ./targetVX-Y-Z/adrena.json that never changes. The "current" IDL
imported from @adrena/abi is bound to CURRENT_IDL, never to a version name.
src/lib.rs re-exports everything off-chain consumers need:
- Oracle types (
oracle::*) —Oracle,OraclePrice,BatchPrices,BatchPricesWithProvider,MultiBatchPrices,PriceData,OracleProvider,OracleVersion,get_confidence_from_price,infer_provider_from_batch. Wire constants:STALENESS=7s,MAX_ORACLE_PRICES_COUNT=50,ORACLE_EXPONENT_SCALE=-9,ORACLE_PRICE_SCALE=1e9,MAX_WRITE_TIME_FUTURE_DRIFT_SECONDS=2. - State accounts (
types::*) —Pool,Custody,Cortex,Position,Staking,UserStaking,UserProfile,LimitOrderBook,MultiOracleConfig,LeverageCheckType,LeverageCheckStatus,PoolType,PoolVersion,PoolLiquidityState,PositionExitFeeConfig. - Instruction params (
types::*) — every<Action>Paramsstruct used by Anchor methods (close/liquidate/limit-order/swap/add+remove liquidity/update_oracle/autonom_market_opening/...). - Events (
events::*) — 14#[event]structs:OpenPositionEvent,IncreasePositionEvent,ClosePositionEvent,AddCollateralEvent,RemoveCollateralEvent,LiquidateEvent,AddLockedStakeEvent,UpgradeLockedStakeEvent,FinalizeLockedStakeEvent,RemoveLockedStakeEvent,SetStopLossEvent,SetTakeProfitEvent,CancelStopLossEvent,CancelTakeProfitEvent. Carry the same Anchor discriminator as the on-chain emissions. - Errors (
error::*) —AdrenaErrorenum (port of the program's#[error_code]enum). - State decoders —
Vest(vest::*),GenesisLock(genesis_lock::*),CustodyInfoSnapshotPda+SyntheticCustodyInfoSnapshotPda(pool_info_snapshot::*), user-profile enums (user_profile_enums::*). - PDA helpers (
pda::*) — 29 helpers:get_cortex_pda,get_pool_pda,get_genesis_lock_pda,get_oracle_pda,get_custody_pda,get_custody_token_account_pda,get_position_pda,get_staking_pda,get_user_staking_pda,get_lp_token_mint_pda,get_lm_token_mint_pda,get_user_profile_pda,get_vest_pda,get_vest_registry_pda,get_limit_order_book_pda,get_collateral_escrow_pda,get_transfer_authority_pda,get_referrer_reward_token_vault_pda, governance helpers (get_realm_pda,get_realm_config_pda,get_token_owner_record_pda, ...). - Feed-map JSON (
feed_maps::*) —include_str!'d constants for every JSON file underconfigs/oracles/plusARTIFACT_MANIFEST_JSONandPOOLS_MANIFEST_JSON. - Feed-id constants (
feed_ids::*) —CHAOSLABS_RANGE,AUTONOM_RANGE,SWITCHBOARD_RANGE,CHAOSLABS_USDC,AUTONOM_USDC,SWITCHBOARD_USDC,AUTONOM_CRYPTO_FEED_IDS,USDC_OFFSET. - Pools manifest (
pools_manifest::*) —PoolsManifestFile,PoolManifestEntry,PoolType,PoolContext,AutomationFlags,load_embedded_pools_manifest,load_pools_manifest_with_override,build_pool_contexts_from_manifest,validate_and_build_pool_context,resolve_lp_staking_pool. - Pubkey constants —
ADRENA_PROGRAM_ID,CORTEX_ID,MAIN_POOL_ID,GENESIS_LOCK_ID,USDC_MINT,WBTC_MINT,BONK_MINT,JITO_MINT,SOL_MINT,ADX_MINT,ALP_MINT, SPL token / associated-token / governance program IDs,ADRENA_GOVERNANCE_REALM_ID,ADRENA_GOVERNANCE_REALM_CONFIG_ID,ADRENA_GOVERNANCE_SHADOW_TOKEN_MINT. Themain_poolsubmodule exposes the four live custody pubkeys as static constants for grep-friendly call sites. BorshDeserializere-export —pub use anchor_lang::prelude::borsh::BorshDeserialize. Consumers must use this re-export rather than adding a directborsh = "1.x"dep, otherwise#[event]macros expand against a different trait version andtry_from_slicefails with a cryptic "associated item not found".
package.json declares the following exports map. Consumers must use these
explicit subpaths (no deep imports):
The idl/adrena.d.ts carries the full preserved Anchor type body (the
same shape as idl/adrena.ts), not a generic Idl alias. Consumers like
adrena-data rely on Program<Adrena> and IdlAccounts<Adrena> for real
type inference; collapsing to a generic alias would silently weaken that.
There is no prepare or build script. github: installs work directly:
the package contains only static JSON + TS files. Adding a build step would
break consumer installs from forked or unpublished commits.
The IDL is Anchor 0.31 format and carries the program address at the top
level ("address": "13gDzE…wet"), so new Program<Adrena>(IDL, provider)
no longer needs an explicit programId argument.
configs/artifact_manifest.json is the canonical fingerprint of an
adrena-abi commit. Every consumer should log its contents at startup so
running services can be cross-checked for drift.
{
"schema_version": 1,
"adrena_program_id": "13gDzEXCdocbj8iAiqrScGo47NiSuYENGsRqi3SEAwet",
"adrena_program_version": "2.1.4",
"adrena_release": "release/39_4",
"adrena_source_commit": "<full 40-char HEAD of adrena/release branch at PR-write time>",
"idl_sha256": "<sha256 of idl/adrena.json>",
"feed_maps": {
"chaoslabs.mainnet": "<sha256>",
"autonom.mainnet": "<sha256>",
"switchboard.mainnet": "<sha256>",
"switchboard.devnet": "<sha256>",
"switchboard_other.mainnet": "<sha256>",
"switchboard_other.devnet": "<sha256>",
"feed_metadata": "<sha256>",
"pools_manifest": "<sha256>"
}
}Hashes are verified by tests/artifact_hashes.rs
— if anyone edits a feed map, the IDL, or the pools manifest without
regenerating this file, the build goes red. Consumers should compute the
same sha256s at startup and compare.
Seven test files gate every commit. Total count: 89 tests (12 unit + 77 integration).
| Test file | Count | What it proves |
|---|---|---|
feed_ids (unit, in src/feed_ids.rs) |
5 | pub const ranges stay in sync with OracleProvider::feed_id_range; USDC constants sit at range_start + USDC_OFFSET. |
Other inline unit tests across src/ |
7 | Misc invariants on OraclePrice, LimitedString, etc. |
tests/artifact_hashes.rs |
1 | Every embedded JSON's sha256 matches artifact_manifest.json. |
tests/feed_metadata_consistency.rs |
5 | Provider/range/symbol cross-checks; stablecoin set matches {CHAOSLABS,AUTONOM,SWITCHBOARD}_USDC; the 6-asset crypto block is identical at offset +0..+5 of all three providers. |
tests/pools_manifest_consistency.rs |
6 | Autonom-pool feedIds lie in the Autonom range; every feed_id has a registered symbol; sessioned-vs-symbol agreement; pool names unique. |
tests/oracle_invariants.rs |
32 | Wire constants pinned (decimals, BPS, staleness, max-prices); provider routing is exhaustive over u8; OraclePrice low/high band math; provider feed-id round-trip. |
tests/wire_format_invariants.rs |
15 | Golden hash for BatchPrices::build_message_hash and AutonomMarketOpeningData::build_message_hash (drift = on-chain verifier rejects every signed batch); LimitedString byte layout pinned. |
tests/pinned_addresses.rs |
15 | Adrena program ID, well-known program IDs, mints, and every PDA derivation match canonical mainnet pubkeys; pool custodies / synthetic custodies / LP mint match on-chain truth. |
tests/no_dummy_in_production.rs |
3 | Mainnet feed maps contain zero _DUMMY: true entries; devnet allowlist explicit. |
Run them all:
cargo build
cargo testExpected: 89 tests, all green.
When the Adrena program ships a new release, do this in order. Each step is local-edit only until step 6.
cd <adrena-program>
git checkout release/<NN>-postaudit
anchor build # regenerates target/idl/adrena.jsonThen in adrena-abi:
cp <adrena>/target/idl/adrena.json adrena-abi/idl/adrena.json
# Regenerate the .ts type-only file too. Then copy it into adrena.d.ts so
# the type body stays full and preserved (do NOT collapse to a generic Idl alias).
cp <adrena>/target/types/adrena.ts adrena-abi/idl/adrena.ts
cp adrena-abi/idl/adrena.ts adrena-abi/idl/adrena.d.tsIf new feeds got added (e.g. a future commodity at slot 39, the first free Autonom slot after WTI=38), add the entries to:
configs/oracles/chaoslabs.mainnet.json(if ChaosLabs has the feed)configs/oracles/autonom.mainnet.json(if Autonom has the feed)configs/oracles/switchboard.mainnet.json+.devnet.json(if Switchboard has the feed)configs/oracles/feed_metadata.json— add the symbol tosessionedwith the right boolean
If the change touches a USDC slot or another stablecoin, also update:
src/feed_ids.rsCHAOSLABS_USDC/AUTONOM_USDC/SWITCHBOARD_USDCfeed_metadata.jsonstablecoin_feed_idsarray- Coordinate with adrena program:
get_confidence_from_priceinadrena/programs/adrena/src/state/oracle.rsand the mirror inadrena-abi/src/oracle.rshardcode the USDC slots. Both must change in the same PR; the on-chain change requires an audit pass.
If a new pool was deployed, or custodies were added/removed, edit
configs/pools_manifest.json. After the on-chain bootstrap proposals land,
read the live Pool account back from chain and pin the actual custody and
synthetic-custody pubkeys (in on-chain order — slot order matters for
synthetic custodies because the Rust loader does Vec<Pubkey> equality).
cd adrena-abi
# Compute fresh hashes
sha256sum idl/adrena.json
sha256sum configs/oracles/chaoslabs.mainnet.json
sha256sum configs/oracles/autonom.mainnet.json
sha256sum configs/oracles/switchboard.mainnet.json
sha256sum configs/oracles/switchboard.devnet.json
sha256sum configs/oracles/switchboard_other.mainnet.json
sha256sum configs/oracles/switchboard_other.devnet.json
sha256sum configs/oracles/feed_metadata.json
sha256sum configs/pools_manifest.json
# Get the adrena source commit
( cd <adrena-program> && git rev-parse HEAD )Edit configs/artifact_manifest.json to:
- Set
adrena_releaseto the new release tag - Set
adrena_program_versionto the crate version in<adrena>/programs/adrena/Cargo.toml - Set
adrena_source_committo the full 40-charactergit rev-parse HEADfrom above - Set
idl_sha256to the freshly computed hash - Update every
feed_maps.<key>to its freshly computed hash
Do not reuse stale hashes, do not paste a 7-character short hash for the
adrena commit, do not skip any file. tests/artifact_hashes.rs will fail
otherwise.
Bump version in adrena-abi/package.json to reflect the new release. The
suggested format is <adrena_program_version>-release<NN>, e.g.
"2.2.0-release40". Bump version in Cargo.toml per Rust crate semver
rules (independent of the npm version — see "Version numbers" below).
cargo build
cargo testAll 89 tests must pass. If tests/artifact_hashes.rs fails, you missed a
hash update in step 4. If tests/feed_metadata_consistency.rs or
tests/pools_manifest_consistency.rs fails, a symbol or feed_id is
unregistered. If tests/no_dummy_in_production.rs fails, the mainnet
allowlist needs updating.
git add idl configs src package.json Cargo.toml
git commit -m "release/<NN> canonical artifact bump"
git pushCapture the resulting commit hash. This is the PR1 commit for the new release.
Update every consumer to the new commit hash, in separate PRs that all merge together.
Rust (Cargo.toml):
adrena-abi = { git = "https://github.com/AdrenaFoundation/adrena-abi.git", rev = "<new-commit-hash>" }TypeScript (package.json):
"@adrena/abi": "github:AdrenaFoundation/adrena-abi#<new-commit-hash>"For adrena-data/processor, freeze the prior release's IDL as a historical
entry so the slot-keyed dispatcher can still decode events from the old
release window:
mkdir adrena-data/processor/src/targetV<old-version>
cp adrena-abi-OLD-COMMIT/idl/adrena.json adrena-data/processor/src/targetV<old-version>/adrena.json
cp adrena-abi-OLD-COMMIT/idl/adrena.ts adrena-data/processor/src/targetV<old-version>/adrena.tsThen in adrena-data/processor/src/utils.ts:
import { IDL as V<OLD>_IDL } from './targetV<old-version>/adrena';
export function getIdlFromSlot(slot: number) {
if (slot >= NEW_RELEASE_BOUNDARY_SLOT) return CURRENT_IDL; // new release onward
if (slot >= OLD_RELEASE_BOUNDARY_SLOT) return V<OLD>_IDL; // previous release
// ... rest unchanged
}CURRENT_IDL automatically points at the new release because
@adrena/abi/idl/adrena.json is now the new IDL. The variable name
CURRENT_IDL does not need to change. Do not rename it to a version-baked
identifier — that's exactly the pattern this repo exists to eliminate.
cargo test -p MrOracle
cargo test -p MrSablier
cargo test -p MrSablierStaking
cargo test -p MrNotification
(cd adrena-data/cron && npm install && npm run build)
(cd adrena-data/api && npm install && npm run build)
(cd adrena-data/processor && npm install && npm run build)
(cd adrena-data/enricher && npm install && npm run build)
(cd MrAutonom && npm install && npm run build)
(cd discord-bot && npm install && npm run build)
(cd frontend && npm install && npm run build)Everything must be green before the consumer PRs merge.
Boot every service in dry-run mode against the new pinned commit. Each
service should print the same adrena-abi artifact startup block, with
matching idl_sha256 and per-map sha256s. If any service prints a different
sha for the same file, the pin or the override is wrong.
Mainnet feed maps must not contain _DUMMY: true entries —
tests/no_dummy_in_production.rs asserts
the mainnet allowlist is empty. Dummy slots exist on devnet only for
forward-compatibility while feeds are being commissioned.
Currently devnet allows [143, 144] to carry the placeholder hashes
deadbeef… (jitoSOL) and cafebabe… (BTC) until real Switchboard devnet
feeds are wired up. The allowlist lives in
tests/no_dummy_in_production.rs::ALLOWED_DUMMY_FEED_IDS_DEVNET.
- Embedded loaders in consumers skip any
_DUMMY: trueslot with a per-slot warning in the boot log. The service runs normally with the surviving feeds. - Override loaders (CLI flag / env-var paths) hard-error on any
_DUMMY: trueentry. Operator-supplied override files are expected to contain real production hashes.
When real Switchboard devnet hashes become available:
- Edit
configs/oracles/switchboard.devnet.json: replace thedeadbeef…/cafebabe…hash with the real hash, drop the_DUMMYfield. - Update
tests/no_dummy_in_production.rsALLOWED_DUMMY_FEED_IDS_DEVNETto remove the slot you just activated. - Recompute hashes and update
configs/artifact_manifest.json. - Run
cargo testto verify. - Coordinated consumer pin bump like a normal release.
The Autonom backend has its own feed_id_aliases.json mapping
adrena_feed_id → autonom_feed_id. It must stay in sync with
configs/oracles/autonom.mainnet.json in this repo. The Autonom backend
resolves adrena's ?feed_ids=30,31,... request via that alias map; if the
two drift, Autonom will sign batches for the wrong products and adrena-data
will silently insert wrong prices.
There is no automated check today. The recommended workflow:
- Any time you edit
configs/oracles/autonom.mainnet.json, also push the matching change to the Autonom backend'sfeed_id_aliases.json. - Coordinate with the Autonom backend deploy in the same release window as the adrena-data consumer bump.
- Treat the two files as a single artifact with two storage locations.
Every consumer that loads an artifact from this repo should accept a runtime override and log the override path plus the sha256 of the override file contents at startup. This is so operators can spot drift between what the consumer is actually running vs the pinned artifact. Common override knobs:
- MrOracle:
--switchboard-feed-map-path <path>,--cluster mainnet|devnet - MrAutonom:
--idl-path <path>,--manifest-path <path> - adrena-data/cron:
AUTONOM_FEED_MAP_PATH,SWITCHBOARD_FEED_MAP_PATH,SWITCHBOARD_CLUSTERenv vars - Every consumer:
--manifest-path <path>for the pools manifest
Don't suppress override-vs-pinned drift logs.
Versions diverge intentionally between the npm package and the Rust crate:
- npm
package.jsonversion tracks the program release suffix (<adrena_program_version>-release<NN>.<N>, e.g.2.1.4-release39.4.0). - Cargo
Cargo.tomlversion follows Rust crate semver independently.
Don't try to sync them. The variable-naming rule above forbids version-baked identifiers in code regardless of which version label is bumped.
All consumers pin via git commit hash, not via semver. Bumping the
package.json version without pushing a new commit does nothing.
cargo build
cargo testThat's the whole build for this repo. There is no anchor build step (the IDL is generated upstream in the adrena program), no codegen, no protoc, no prepare script.
Apache-2.0 — same as the adrena program.