Skip to main content

doc/binance-live-testing.md

# Binance Live Testing Plan

This document records the manual live-test policy for the generated Elixir
Binance target.

## Credentials

The runtime reads one active credential set from the process environment:

```sh
BINANCE_API_KEY=...
BINANCE_API_SECRET=...
BINANCE_ENV=prod
```

`BINANCE_ENV` supports:

- `prod`, `production`, `mainnet`: Binance production
- `demo`: Binance demo URLs
- `test`, `testnet`, `sandbox`: Binance testnet URLs

Keep multiple key sets in `.env` with distinct names if needed, then map only
the active set to `BINANCE_API_KEY` and `BINANCE_API_SECRET` before running a
test. Do not add multi-environment credential routing to `HttpExecutor`; it
should stay aligned with CCXT's current-exchange credential model.

The live smoke test loader also accepts environment-specific names and maps
them to the active CCXT-style variables inside the test process when
`BINANCE_API_KEY` / `BINANCE_API_SECRET` are not already set:

```sh
BINANCE_DEMO_API_KEY=...
BINANCE_DEMO_API_SECRET=...

BINANCE_PROD_API_KEY=...
BINANCE_PROD_API_SECRET=...

BINANCE_TESTNET_API_KEY=...
BINANCE_TESTNET_API_SECRET=...
```

For example, with `BINANCE_ENV=demo`, the live test maps
`BINANCE_DEMO_API_KEY` and `BINANCE_DEMO_API_SECRET` to the active credential
variables. This mapping is test-only; the runtime and `HttpExecutor` still read
the standard active credential names.

## Environment Coverage

Production supports all generated Binance namespaces currently routed by the
Elixir target:

- `public`, `private`, `v1`
- `sapi`, `sapiV2`, `sapiV3`, `sapiV4`
- `fapiPublic`, `fapiPublicV2`, `fapiPublicV3`
- `fapiPrivate`, `fapiPrivateV2`, `fapiPrivateV3`
- `dapiPublic`, `dapiPrivate`, `dapiPrivateV2`
- `eapiPublic`, `eapiPrivate`
- `fapiData`, `dapiData`
- `papi`, `papiV2`

Demo and testnet currently support only:

- `public`, `private`, `v1`
- `fapiPublic`, `fapiPublicV2`, `fapiPublicV3`
- `fapiPrivate`, `fapiPrivateV2`, `fapiPrivateV3`
- `dapiPublic`, `dapiPrivate`, `dapiPrivateV2`

Demo and testnet do not expose:

- `sapi`, `sapiV2`, `sapiV3`, `sapiV4`
- `eapiPublic`, `eapiPrivate`
- `fapiData`, `dapiData`
- `papi`, `papiV2`

## Test Policy

Use production for methods that do not change balances, orders, positions, or
account configuration. Use read-only production API keys for these tests.

Use demo/testnet for state-changing methods whenever the required namespace is
available there.

For state-changing methods that require production-only namespaces, do not run
the live request by default. First test generated routing/signing with injected
transport or dry-run assertions, then run the real request only after explicit
manual approval.

## Production-Only State-Changing Methods

These methods change funds or account state and require production because their
generated routes use namespaces that demo/testnet do not expose.

### Funds Movement

- `withdraw/6`
  - Route: `sapi_post_capital_withdraw_apply`
  - Effect: real withdrawal.
  - Risk: highest. Run only with withdrawal whitelist and explicit approval.

- `transfer/6`
  - Route: `sapi_post_asset_transfer`
  - Effect: account-to-account asset transfer.

- `futures_transfer/5`
  - Route: `sapi_post_futures_transfer`
  - Effect: spot/futures account transfer.

- `create_gift_code/4`
  - Route: `sapi_post_giftcard_createcode`
  - Effect: creates a funded gift card code.

- `redeem_gift_code/3`
  - Route: `sapi_post_giftcard_redeemcode`
  - Effect: redeems a gift card code into the account.

- `create_convert_trade/5`
  - Routes: `sapi_post_convert_acceptquote`,
    `sapi_post_asset_convert_transfer`
  - Effect: converts assets or transfers converted assets.

- Simple Earn redeem raw endpoints
  - Routes: `sapi_post_simple_earn_flexible_redeem`,
    `sapi_post_simple_earn_locked_redeem`
  - Effect: redeems Simple Earn positions back toward the spot account.
  - Coverage: dry-run only by default; live redemption requires separate
    explicit approval and product-specific parameters.

### Margin Borrow and Repay

- `borrow_cross_margin/4`
- `borrow_isolated_margin/5`
- `repay_cross_margin/4`
- `repay_isolated_margin/5`

Routes include:

- `sapi_post_margin_borrow_repay`
- `papi_post_marginloan`
- `papi_post_margin_repay_debt`
- `papi_post_repayloan`

Effect: changes margin loans or repayments. These should be treated as
production-only state-changing tests.

### Options Trading

Option-market order methods route through `eapiPrivate`, which demo/testnet do
not expose in the current target:

- `create_order/7`
- `create_orders/3`
- `edit_order/7`
- `edit_orders/3`
- `cancel_order/4`
- `cancel_all_orders/3`
- `cancel_orders/4`

Effect: places, edits, or cancels real option orders. Use production only after
explicit approval.

### Portfolio Margin State

Portfolio-margin branches route through `papi` / `papiV2`, which demo/testnet
do not expose:

- `set_leverage/4`
- `set_position_mode/4`
- portfolio-margin order branches in `create_order/7`, `edit_order/7`,
  `cancel_order/4`, `cancel_all_orders/3`, and `cancel_orders/4`

Effect: changes portfolio-margin account trading state or real orders. Use
production only after explicit approval.

## Recommended Execution Order

1. Run public live smoke with no credentials.
2. Run private read-only production smoke with read-only keys.
3. Run demo/testnet state-changing smoke for supported namespaces.
4. Run production-only state-changing tests only one method at a time, with
   explicit approval and minimal size.

## Test Commands

Public live smoke:

```sh
mix test --include live test/ccxt_live_smoke_test.exs --timeout 420000
```

Production read-only private smoke:

```sh
BINANCE_ENV=prod mix test \
  --include live \
  --include private \
  --include prod_readonly \
  test/ccxt_binance_prod_readonly_live_test.exs \
  --timeout 420000
```

Demo state-changing smoke:

```sh
BINANCE_ENV=demo mix test \
  --include live \
  --include private \
  --include demo_state \
  test/ccxt_binance_demo_state_live_test.exs \
  --timeout 420000
```

Production low-risk spot order smoke. This sends a real production limit order
at 90% of the current ticker price and immediately cancels it. The default
amount is `0.0002` BTC and can be overridden with
`BINANCE_PROD_STATE_ORDER_AMOUNT`.

```sh
BINANCE_ENV=prod mix test \
  --include live \
  --include private \
  --include prod_state \
  test/ccxt_binance_prod_state_live_test.exs \
  --timeout 420000
```

Production-only dry-run checks. These do not send HTTP requests and use fake
credentials only:

```sh
mix test test/ccxt_binance_prod_only_dry_run_test.exs
```