Addresses
@symmio/trading-core ships a per-chain registry of every deployment address, endpoint URL, and configured service. It lives in the core package at:
packages/trading-core/src/core/chains/registry.tsThe registry is the single source of truth for chain-specific values. Every action reads it via Config.getChainConfig(chainId) — you never hand-thread addresses through action arguments unless you’re overriding a default.
Runtime access
import { createConfig, SymmioSupportedChainId } from "@symmio/trading-core";
const config = createConfig({
symmioConfig: {
[SymmioSupportedChainId.ARBITRUM]: { addresses: { affiliatesAddress: "0xYourRegisteredAffiliate…" } },
},
getClient: () => publicClient,
});
const chain = config.getChainConfig(SymmioSupportedChainId.ARBITRUM);
chain.addresses.symmioAddress;
chain.addresses.instantLayerAddress;
chain.addresses.accountLayerAddress;
chain.addresses.affiliatesAddress;
chain.addresses.collateralAddress;
chain.addresses.collateralDecimals;Throws UNSUPPORTED_CHAIN when the chain id isn’t in the registry. See Config.
What’s in the registry
Every entry is a SymmioChainConfig — the fully-resolved settings for one chain:
chainIdnumberNumeric chain id (for example, 42161 for Arbitrum One).
addressesSymmioContractAddressesOn-chain contract addresses (detailed below).
subgraphsSymmioSubgraphUrlsGraphQL endpoints — analytics and events.
solversRecord<SolverId, SymmioSolverConfig>Solver / hedger REST API, TP/SL handler, optional per-solver price service, and the required per-solver
notifications config, keyed by solver id ("enigma" / "rasa"). Arbitrum carries the enigma solver; Base carries
rasa. Resolve one with config.getSolver({ chainId, solverId }).
defaultSolverIdSolverIdThe solver an action or hook resolves when solverId is omitted — enigma on Arbitrum, rasa on Base. Read it at
runtime with config.getDefaultSolverId(chainId?).
priceServiceSymmioPriceServiceConfigPrice provider — the Enigma price service on Arbitrum (type: "enigma"), or Binance USD-M Futures on Base (type: "binance"). Both expose REST + WebSocket.
muonSymmioMuonConfigMuon oracle gateway URLs.
listingSymmioListingConfigoptionalThe Pools listing backend — a single url, and that url is the host root: no version segment
and no trailing slash, because the generated client’s own paths already begin with /v2. Chain-level rather than
per-solver, since several solvers on one chain could share one deployment. Present only on Arbitrum today. See Pools
listing service.
contractsVersion"0.8.5" | "0.8.6"Which perps-core contracts generation the deployment runs. A per-chain deployment fact, not a caller choice —
Base is "0.8.5", Arbitrum is "0.8.6". Features that exist only on the newer generation (today,
gasless) gate on it.
gaslessSymmioGaslessConfigoptionalThe GaslessQ relayer — url, protocolInstance, gaslessLayerAddress, plus the consumer’s
execution policy, an optional statusStream declaration, and an optional partner apiKey for server-side use
(access is anonymous without one, unless the deployment turns anonymous access off). No chain ships a built-in
block — a consumer supplies the whole block through a createConfig override, and a base-less override missing
url or gaslessLayerAddress throws GASLESS_OVERRIDE_INCOMPLETE.
inventorySymmioInventoryConfigoptionalThe inventory service — the custody backend behind the Pools, and a different vendor from
both the solver and the listing backend. A single url, again the host root: the generated client’s own paths
already begin with /api/v1, so appending /api here would request /api/api/v1/… and 404. Chain-level, and
unlike listing there is no solver capability to declare — a chain either carries the block or it does not, which
is why resolveInventoryService takes a bare chainId. Missing, it
throws INVENTORY_NOT_CONFIGURED. Present only on Arbitrum today.
The addresses field — the section people usually want:
symmioAddressAddressSYMMIO diamond contract.
instantLayerAddressAddressInstantLayer (delegated instant actions).
accountLayerAddressAddressAccountLayer (SubAccount / VA management).
affiliatesAddressAddressYour frontend’s affiliate identity (fee attribution). Required per chain via createConfig’s
symmioConfig[chainId].addresses.affiliatesAddress — the field must be present (createConfig throws when it
is missing). The zero address is accepted as a no-affiliate test placeholder; `
register your affiliate to earn a share of the trading fees.
collateralAddressAddressCollateral token (e.g. USDC).
collateralDecimalsnumberDecimals of the collateral token.
Each entry in solvers is a SymmioSolverConfig — the solver’s own endpoints, including its notifications config:
namestringHuman-readable solver name.
addressAddressSolver’s on-chain address (used as partyB in sendQuote).
urlstringSolver / hedger REST API base URL.
tpslSymmioTpSlConfigoptionalTP/SL (conditional-order handler) config — the solver supports conditional orders only when set.
priceServiceSymmioPriceServiceConfigoptionalPrice source for this solver’s markets. Falls back to the chain’s priceService when omitted.
notificationsSymmioNotificationsConfigPer-solver notifications config — WebSocket url + a protocol discriminant ("enigma" / "rasa"). The
enigma variant adds channel and an optional searchUrl (the notification service that backs
searchNotifications); the rasa variant has neither — its history search runs through the
solver’s own position-state endpoint, also via searchNotifications. Required on every solver: notifications
are inherently solver-specific, so there is no chain-level default to inherit.
Everything else (subgraph, Muon gateways, the chain-level price service) lives on the sibling SymmioChainConfig fields above.
Current chains
Two chains ship in the registry — each runs a different solver kind and product. See Solvers & Chains for how the two axes fit together.
Arbitrum (42161) — enigma / lowcap
contractsVersion—"0.8.6"symmioAddress—0x57331027091994FCb9c5Aec48ea92cEf0a93CF6AinstantLayerAddress—0x54c27E4bf1125391aA76e1D6497B069d91e179f6accountLayerAddress—0x573310d1D6ec18cB21E1aB949414470D9bf5c24EaffiliatesAddress—0x58bB5Bdc279321507DfB7AB54B9e7EF3DdA6E24D(built-in default; override it per chain via the requiredsymmioConfig[chainId].addresses.affiliatesAddress— set your registered affiliate to earn a share of the trading fees)collateralAddress—0xaf88d065e77c8cC2239327C5EDb3A432268e5831(native USDC, 6 decimals)solvers.enigma.address—0x0420b24359d2DCccA53904042aa36A641162445c,defaultSolverId: "enigma"solvers.enigma.url—https://solver.enigma.bz/apisolvers.enigma.tpsl.url—https://tpsl.enigma.bzsolvers.enigma.tpsl.appName—Arbitrum_COH_Productionsolvers.enigma.tpsl.cohWalletAddress—0xFC3a98d30AdAA220Ae4150fcaC06Bd200b6E146Bsolvers.enigma.notifications.protocol—"enigma"(carries asearchUrl— the notification service)subgraphs.analytics—https://api.goldsky.com/api/public/project_cm1hfr4527p0f01u85mz499u8/subgraphs/arbitrum-vibe-mainnet-analytics/latest/gnsubgraphs.events—https://api.goldsky.com/api/public/project_cm1hfr4527p0f01u85mz499u8/subgraphs/arbitrum-vibe-mainnet-events/stage/gnpriceService.type—"enigma"listing.url—https://listing85.enigma.bz(the Pools listing backend; host root, no/v2)inventory.url—https://inventory85.enigma.bz(the custody backend behind the Pools; host root, no/api)
The only chain on the perps-core ("0.8.6") contracts generation, and therefore the only one where
gasless can run at all — once a gasless block is supplied through an override.
Base (8453) — rasa / majors
symmioAddress—0x91Cf2D8Ed503EC52768999aA6D8DBeA6e52dbe43instantLayerAddress—0x0825435285ac0E5c02c7a7c443F631f3e07fE375accountLayerAddress—0x56caf00c6C5cB5478570Bb23807B9d1D697863DCaffiliatesAddress—0x45Eecd7B4f442388ACD90467E423A5CAAC3a9C3f(built-in default; override with your registered affiliate)collateralAddress—0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913(USDC on Base, 6 decimals)solvers.rasa.address—0x81631953E0C093e72935C1CAA4C7D519B2A0E407,defaultSolverId: "rasa"solvers.rasa.notifications.protocol—"rasa"(nosearchUrl; history search runs through the solver’s ownposition-stateendpoint viasearchNotifications)priceService.type—"binance"(Binance USD-M Futures,fapi.binance.com)
Base is staging-configured. The rasa solver.url points at a staging host (stage-archon.rasa.capital), and the
chain has no tpsl block: the COH wallet is not deployed yet, so conditional orders (TP/SL) are unsupported on
Base. Its contract addresses and subgraphs are production values. Muon gateways are real (Muon is
deployment-agnostic). Swap the staging solver URL for production when it’s published.
Each entry also carries URLs for the solver, price service, notifications, subgraphs, and Muon gateways.
Per-chain overrides
Override any field at runtime via createConfig({ symmioConfig }). Deep-merged onto the built-in registry — you can override just the subgraph URL or just one address, keeping the rest.
const config = createConfig({
getClient: () => publicClient,
symmioConfig: {
[SymmioSupportedChainId.ARBITRUM]: {
addresses: { affiliatesAddress: "0xYourRegisteredAffiliate…" },
subgraphs: {
analytics: "https://staging.example/subgraphs/analytics",
},
// Notifications are per-solver — override under `solvers[solverId].notifications`.
solvers: {
enigma: { notifications: { searchUrl: "https://staging.example/notification" } },
},
},
},
});Useful for staging deployments and new chains that ship before an SDK release.
Adding a chain
- Add its id to
packages/trading-core/src/core/chains/supported-chains.ts— sourced fromviem/chains, never a numeric literal. - Add its entry to
CHAIN_CONFIGSinpackages/trading-core/src/core/chains/registry.ts— every field ofSymmioChainConfigis required. - Colocate tests for
getChainConfigif you introduce novel behavior.
Open a PR. New chains follow the existing entries’ conventions.
Related
- Config — how
getChainConfig/symmioConfigplug in. - ABI fragments — pair addresses with typed ABIs for viem-direct calls.
- Shared Types —
ChainIdParametermixin on every action.