Shared types
Cross-cutting parameter and utility types used across every slice of the SDK. They are public because consumers composing their own higher-level actions need to reference the same building blocks. Most are single-property mixins combined into an action’s parameter type via Compute<A & B>, mirroring the @wagmi/core convention.
Import
import type {
ChainIdParameter,
Compute,
ConfigKeyParameter,
ConfigParameter,
DeepPartial,
ExactPartial,
FromParameter,
QueryParameter,
SimulateBeforeWriteParameter,
SymmioQueryOptions,
WebSocketConstructor,
WebSocketLike,
WriteContractParameter,
WriteSolverParameter,
} from "@symmio/trading-core";Parameter mixins
Single-property object types folded into an action’s parameter type. Each carries exactly one field so it can be mixed into many actions without collision.
ChainIdParameter
Optional chain override, mixed into every action’s parameters.
chainIdnumberoptionalTarget chain id. Defaults to the config’s defaultChainId when omitted.
ConfigParameter
Optional config override accepted by every hook and action.
configConfigoptionalUse this config instead of the one from context.
ConfigKeyParameter
Folded into query keys so a runtime config override yields a fresh key instead of serving stale cache. The query-option factories set it internally; you rarely pass it by hand.
configKeystringoptionalStable fingerprint of the resolved chain config. Set automatically from config.getChainConfigKey(chainId) and
folded into query keys.
FromParameter
Optional signer selector, not merely a simulation detail. Named from (not account) so it never collides with an action’s own account / user field.
from is handed to the config’s getWalletClient resolver, which decides which wallet client to return. The SDK does no address matching of its own — passing from is a hint your resolver interprets. That makes it the mechanism by which a session key signs: a resolver that returns a session-key client when from matches the loaded key turns any relayable write into a promptless, gas-free one.
On a relayed write the resolved client’s address becomes the Instant Layer operation’s EIP-712 signer, while the billing account stays the sub-account. On the wallet path it is the sender, and the address a simulation runs as.
fromAddressoptionalThe signer to resolve the wallet client with, and the address a simulation runs as (msg.sender). Defaults to the
connected wallet in the React layer.
A from that is not the account owner only works on the relay. CoreFacet._call is onlyAccountOwner, so a
session-key from on the wallet path reverts NotOwner — and the key holds no native gas to send it with anyway.
SimulateBeforeWriteParameter
Per-write opt-out for the pre-send dry-run.
simulateBeforeWritebooleanoptionalDry-run via simulateContract before sending; abort if it would revert. Defaults to the config’s
simulateBeforeWrite (itself true).
Query types
QueryParameter
Optional TanStack Query overrides accepted by every read factory.
queryPartial<QueryObserverOptions>optionalPartial TanStack Query options minus queryKey/queryFn/queryHash/queryKeyHashFn (the factory fills those).
Pass staleTime, gcTime, select, enabled, retry, etc.
SymmioQueryOptions
The object every …QueryOptions factory returns: your QueryParameter passthrough with the SDK’s queryKey and queryFn already filled in. Feed it straight into useQuery / queryClient.fetchQuery.
queryKeyqueryKeyThe SDK-owned query key, pre-filled by the factory.
queryFn() => Promise<queryFnData>The SDK-owned fetcher, pre-filled by the factory.
Every other field is passthrough from QueryParameter’s query — staleTime, select, enabled, and the rest.
WebSocket types
Minimal structural types for a WebSocket implementation the SDK can drive. core stays free of a DOM-lib dependency by typing only the members its reconnecting socket relies on. Inject an implementation via createConfig({ webSocketConstructor }); when omitted the SDK falls back to globalThis.WebSocket.
WebSocketLike
The subset of a WebSocket instance the SDK’s reconnecting socket relies on. Both the browser WebSocket and the ws package satisfy this shape.
readyStatenumberCurrent connection state: 0 connecting, 1 open, 2 closing, 3 closed.
send(data: string) => voidSend a string frame.
close(code?: number, reason?: string) => voidBegin closing the connection.
onopen((event: unknown) => void) | nullFired once the connection opens.
onclose((event: { code?: number; reason?: string; wasClean?: boolean }) => void) | nullFired when the connection closes, cleanly or otherwise.
onerror((event: unknown) => void) | nullFired on a transport-level error.
onmessage((event: { data: unknown }) => void) | nullFired for each inbound frame; data is typically a JSON string.
WebSocketConstructor
A constructor compatible with WebSocketLike. Both globalThis.WebSocket and the ws package’s export match.
interface WebSocketConstructor {
new (url: string, protocols?: string | string[]): WebSocketLike;
}TypeScript helpers
Pure type-level utilities — no runtime output.
Compute
Flattens an intersection of object types into a single, readable object so hover-tooltips show the flat shape instead of a chain of intersections. Purely cosmetic.
type Params = Compute<ChainIdParameter & { user: Address; size: bigint }>;
// hover shows: { chainId?: number; user: Address; size: bigint }DeepPartial
Recursive Partial, but arrays are leaves — an overriding array replaces the original wholesale rather than being patched element-by-element. Used by createConfig({ symmioConfig }), where a consumer may override a single deeply-nested per-chain field.
type DeepPartial<type> = type extends readonly unknown[]
? type
: type extends object
? { [key in keyof type]?: DeepPartial<type[key]> }
: type;ExactPartial
Non-widening Partial: every field becomes optional and explicitly | undefined, without dropping undefined from a union member. Used for query-option shapes where each action parameter turns optional.
type ExactPartial<type> = {
[key in keyof type]?: type[key] | undefined;
};Write parameter helpers
Mixin bundles an action extends with its own action-specific fields. Each is an alias for an intersection of the mixins above, kept as one name so an action’s parameter type stays focused on what is unique to it.
WriteContractParameter
The standard mixin set every on-chain write action accepts. It has no account field of its own — the action adds that.
type WriteContractParameter = ChainIdParameter & FromParameter & SimulateBeforeWriteParameter;Composes ChainIdParameter, FromParameter, and SimulateBeforeWriteParameter. An action folds it in and adds its own fields, e.g. Compute<WriteContractParameter & { account: Address; amount: bigint }>.
WriteSolverParameter
The standard mixin set every off-chain solver/hedger write accepts. Same as WriteContractParameter minus simulateBeforeWrite — solver writes POST to an HTTP endpoint and never simulate on-chain.
type WriteSolverParameter = ChainIdParameter & FromParameter;Composes ChainIdParameter and FromParameter; from stays optional. The action adds its own fields, e.g. Compute<WriteSolverParameter & { partyA: Address; order: InstantCloseOrder }>.
Concrete action-parameter types (e.g. DepositForAccountParameters, InstantCloseParameters) are documented on their own action pages, not here.
Value helpers
Pure functions shared across slices. They are values, not types, so they import without type:
import { collateralToCore18, core18ToCollateral, decimalPriceToWei, sharePercent } from "@symmio/trading-core";decimalPriceToWei
Convert a decimal price string — what every price feed in the SDK emits — to 18-decimal wei. Tolerates more than 18 decimals by rounding, where viem’s parseUnits throws.
decimalPriceToWei("150.5"); // 150_500000000000000000n
decimalPriceToWei("0"); // 0n — a real zero price
decimalPriceToWei(""); // undefined — no price yetIt returns undefined, never 0n, for an empty, malformed or non-finite input, so a caller can tell “no price yet” apart from “the price is zero”. That distinction is load-bearing: a fabricated 0n mark price makes aggregateGroupUpnl report a −100% loss instead of “unknown”.
sharePercent
part / total × 100 as an 18-decimal fixed-point percent (50% → 50_000000000000000000n). Handles a signed part, so a negative share yields a negative percent. Returns undefined when total is not positive — the ratio does not exist there, and 0 would be a different claim.
sharePercent(25_000000000000000000n, 100_000000000000000000n); // 25_000000000000000000n
sharePercent(1n, 0n); // undefinedIt is the percent convention behind QuoteGroupTpSlSummary coverage and MarginRiskMetrics.liquidationBufferPercent.
collateralToCore18
Scale a collateral-token amount up to SYMMIO Core’s 18-decimal units. Token transfers, deposit and withdrawal amounts, and a GaslessLayer’s depositFee, minimumDeposit and wallet creation fee use the collateral token’s decimals. Core balances, operational-fee allowances and every GaslessFeeQuote amount use 18 decimals. Convert before you compare or add values across the two; the Balance Model has the full table.
collateralToCore18(1_000000n, 6); // 1_000000000000000000n — 1 USDC in Core units
collateralToCore18(5n, 18); // 5n — an 18-decimal collateral is already in Core units
// A relayed withdrawal draws its amount and its fee from the same Core balance.
const required18 = collateralToCore18(amount, collateralDecimals) + fee18;amountbigintrequiredAmount in the collateral token’s base units, e.g. 1_000000n for 1 USDC.
collateralDecimalsnumberrequiredThe collateral token’s decimals, an integer from 0 to 18:
config.getChainConfig(chainId).addresses.collateralDecimals, or GaslessFeeQuote.collateralDecimals.
bigintThe same amount in 18-decimal Core units: amount × 10^(18 − collateralDecimals). The conversion is always exact.
Throws SymmError("validation", "COLLATERAL_DECIMALS_UNSUPPORTED") when collateralDecimals is not an integer from 0 to 18. Core accepts no collateral token with more than 18 decimals, so no real deployment hits it.
core18ToCollateral
Scale an 18-decimal Core amount down to the collateral token’s base units, rounding a remainder the token cannot hold. It rounds up by default, the rule for funding: a fee converted into the tokens that must be sent to cover it is never short. For a non-negative amount that is the familiar (fee18 + scale - 1n) / scale. Pass rounding: "down" for an amount that must not be overstated, such as a balance you display or pay out.
core18ToCollateral(50_000_000_000_000_000n, 6); // 50_000n — 0.05 USDC, exact
core18ToCollateral(1_000000000000000001n, 6); // 1_000001n — rounded up
core18ToCollateral(1_000000000000000001n, 6, { rounding: "down" }); // 1_000000n
const feeInTokenUnits = core18ToCollateral(quote.totalFee18, quote.collateralDecimals);amount18bigintrequiredAmount in 18-decimal Core units.
collateralDecimalsnumberrequiredThe collateral token’s decimals, an integer from 0 to 18.
options.rounding"up" | "down"default "up"optional"up" rounds toward positive infinity, "down" toward negative infinity. Fees, allowances and balances are never
negative, so for them this means rounding up or truncating. Both agree whenever the amount converts exactly.
bigintThrows SymmError("validation", "COLLATERAL_DECIMALS_UNSUPPORTED") on the same inputs as collateralToCore18. The options bag is exported as the Core18ToCollateralOptions type.
Related
- Config — the runtime object every action uses.
- Query options — how the query types plug in.
- WebSocket — where
WebSocketLike/WebSocketConstructorare wired in. - Errors — validation errors reference the field names in these mixins.
- Balance Model — which values are 18-decimal Core units and which use the collateral token’s decimals.