CCXT.Testnet (ccxt_client v0.6.1)

Copy Markdown View Source

ETS-backed credential registry for integration testing.

Supports multiple credential sets per exchange for multi-API exchanges (e.g., Binance spot vs futures testnets require separate credentials).

Credentials are registered once at test startup (in test_helper.exs), then retrieved by generated tests at runtime. ETS with read_concurrency: true allows lock-free reads from any process.

Usage

# In test_helper.exs - register credentials for each sandbox
CCXT.Testnet.register_all_from_env([
  {:bybit, testnet: true},
  {:binance, testnet: true},
  {:binance, :futures, testnet: true},
  {:okx, testnet: true, passphrase: true}
])

# In tests - retrieve credentials for specific sandbox
creds = CCXT.Testnet.creds(:bybit)             # default sandbox
creds = CCXT.Testnet.creds(:binance, :futures) # futures sandbox

Sandbox Keys

Multi-API exchanges have different testnets per API section:

Sandbox KeyEnv Var InfixExample Hostname
:default(none)testnet.binance.vision
:futures_FUTUREStestnet.binancefuture.com
:coinm_COINMtestnet.binancefuture.com/dapi

Env Var Convention

  • {EXCHANGE}[_{SANDBOX}]_TESTNET_API_KEY
  • {EXCHANGE}[_{SANDBOX}]_TESTNET_API_SECRET
  • {EXCHANGE}_PASSPHRASE (if passphrase: true)

When :testnet is true, the _TEST_ infix is accepted as a silent fallback (e.g. BINANCE_FUTURES_TEST_API_KEY is treated as an alias for BINANCE_FUTURES_TESTNET_API_KEY). The canonical _TESTNET_ name remains preferred and is the one surfaced in creds!/2 error messages.

Summary

Types

Config entry for register_all_from_env/1

Options for register_from_env/2,3

Functions

Returns a specification to start this module under a supervisor.

Clears all registered credentials (for test isolation).

Get credentials for an exchange/sandbox. Returns nil if unregistered.

Get credentials or raise ArgumentError with a helpful message.

Env var prefix for a given exchange + sandbox combination.

List unique exchange atoms with any registered credentials.

Register credentials for multiple exchanges from environment variables.

Register credentials from environment variables.

Returns true when credentials are registered for the given exchange/sandbox.

List all registered {exchange, sandbox_key} tuples.

Derive sandbox_key from a sandbox URL's hostname/path.

Starts the Testnet registry GenServer (owns the ETS table).

Types

config_entry()

@type config_entry() :: {atom(), register_opts()} | {atom(), atom(), register_opts()}

Config entry for register_all_from_env/1

register_opts()

@type register_opts() :: [
  testnet: boolean(),
  passphrase: boolean(),
  sandbox: boolean(),
  secret_suffix: String.t()
]

Options for register_from_env/2,3

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear()

@spec clear() :: :ok

Clears all registered credentials (for test isolation).

creds(exchange, sandbox_key \\ :default)

@spec creds(atom(), atom()) :: CCXT.Credentials.t() | nil

Get credentials for an exchange/sandbox. Returns nil if unregistered.

creds!(exchange, sandbox_key \\ :default)

@spec creds!(atom(), atom()) :: CCXT.Credentials.t()

Get credentials or raise ArgumentError with a helpful message.

env_var_prefix(exchange, sandbox_key)

@spec env_var_prefix(atom(), atom()) :: String.t()

Env var prefix for a given exchange + sandbox combination.

Examples

iex> CCXT.Testnet.env_var_prefix(:binance, :default)
"BINANCE_TESTNET"

iex> CCXT.Testnet.env_var_prefix(:binance, :futures)
"BINANCE_FUTURES_TESTNET"

exchanges_with_creds()

@spec exchanges_with_creds() :: [atom()]

List unique exchange atoms with any registered credentials.

register(exchange, sandbox_key_or_opts, opts \\ [])

@spec register(atom(), atom() | keyword(), keyword()) :: :ok | :skipped

Register credentials directly.

Returns :ok if credentials validate, :skipped if required fields are missing.

register_all_from_env(configs)

@spec register_all_from_env([config_entry()]) :: [{atom(), atom()}]

Register credentials for multiple exchanges from environment variables.

Returns the list of successfully registered {exchange, sandbox_key} tuples.

register_from_env(exchange, sandbox_key_or_opts \\ :default, opts \\ [])

@spec register_from_env(atom(), atom() | register_opts(), register_opts()) ::
  :ok | :skipped

Register credentials from environment variables.

Env var pattern: {EXCHANGE}[_{SANDBOX}][_TESTNET]_API_KEY|_API_SECRET.

Options

  • :testnet - Include _TESTNET in env var names (default: false)
  • :passphrase - Also load passphrase from {EXCHANGE}_PASSPHRASE (default: false)
  • :sandbox - Value for credentials.sandbox (default: value of :testnet)
  • :secret_suffix - Override secret env var suffix (default: "API_SECRET")

Returns :ok on success, :skipped when required env vars are absent.

registered?(exchange, sandbox_key \\ :default)

@spec registered?(atom(), atom()) :: boolean()

Returns true when credentials are registered for the given exchange/sandbox.

registered_exchanges()

@spec registered_exchanges() :: [{atom(), atom()}]

List all registered {exchange, sandbox_key} tuples.

sandbox_key_from_url(url)

@spec sandbox_key_from_url(String.t() | nil) :: atom()

Derive sandbox_key from a sandbox URL's hostname/path.

Examples

iex> CCXT.Testnet.sandbox_key_from_url("https://testnet.binance.vision/api/v3")
:default

iex> CCXT.Testnet.sandbox_key_from_url("https://testnet.binancefuture.com/fapi/v1")
:futures

iex> CCXT.Testnet.sandbox_key_from_url("https://testnet.binancefuture.com/dapi/v1")
:coinm

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the Testnet registry GenServer (owns the ETS table).