Skip to content

Add Rust transpilation#6

Draft
Herklos wants to merge 26 commits into
dkfrom
feature/add-rust
Draft

Add Rust transpilation#6
Herklos wants to merge 26 commits into
dkfrom
feature/add-rust

Conversation

@Herklos
Copy link
Copy Markdown

@Herklos Herklos commented Feb 14, 2026

@Herklos Herklos self-assigned this Feb 14, 2026
claude and others added 5 commits March 17, 2026 11:34
- Add comprehensive regression test suite (56 tests) in rust/tests/regression.rs
  covering safe accessor methods, Value helpers, describe() shape validation,
  fixture-based comparison, and live network tests
- Add manually-maintained safe accessor implementations to Exchange trait:
  safe_string, safe_integer, safe_float, safe_value, safe_bool, safe_dict,
  safe_list, safe_number, parse_number, safe_timestamp and all _2/_n variants
- Add free helper functions: safe_get, value_to_string_opt, value_to_i64_opt,
  value_to_f64_opt
- Update rustTranspiler.ts with MANUALLY_IMPLEMENTED_METHODS set to skip
  generating stubs for methods already implemented in the Exchange trait
- Add test fixtures in rust/tests/fixtures/ for JS-parity validation
- Regenerate all exchange .rs files (safe accessor stubs removed)

https://claude.ai/code/session_01KE37uEYUSbY3Ug9yFSjpzZ
Signed-off-by: Herklos <herklos@drakkar.software>
Create shared test helper module (tests/common/mod.rs) with thorough
validators for ticker, order book, and OHLCV data modeled after the
canonical CCXT TypeScript test suite. Validates prices > 0, volumes >= 0,
bid-ask spread, OHLC bounds, timestamp sanity, symbol matching, and
sort order for order book entries.

Expand pro exchange smoke tests from 27 to 71 exchanges covering okx,
bybit, kraken, kucoin, gate, hyperliquid, phemex, dydx, coinbase, and
30+ more. Refactor both test files to use shared validators.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds 57 individual smoke tests covering every pro exchange with the full
validation suite (describe, status, ticker, tickers, order_book, ohlcv).
Softens status shape check to handle raw exchange response variance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove RUST_STUB_MODE flag entirely from rustTranspiler.ts
- Exchange-specific methods now get fully transpiled JS→Rust bodies
  instead of `{ Value::Undefined }` stubs
- Base Exchange class methods still use stubs (runtime not ready)
- Inherited base methods removed from exchange traits (available via
  Exchange supertrait) to avoid E0034 ambiguity
- Fix TryStatement to emit try block inline (catch as comment)
- Add AST visitors: SpreadElement, ArrowFunction, FunctionExpression,
  TemplateLiteral, ForOf/ForIn, SwitchStatement
- Fix dispatch call matching (case-insensitive API method names)
- Fix method call generation: use UFCS for overrides, instance calls
  for inherited methods
- Add BoolExt trait, From<i32>, From<Value> for serde_json::Value
- Add Precise static methods, Math methods, Array::is_array
- Add runtime stub methods for pre-delimiter Exchange.js functions
  (load_markets, omit, iso8601, etc.)
- Fix argument count table for safe* methods and other utilities
- Make Exchange require ValueTrait supertrait for self.get() access

Result: binance.rs goes from 499 stub methods to 0 stubs, with 202
real transpiled functions across 13,477 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove RUST_STUB_MODE flag entirely from rustTranspiler.ts
- Exchange-specific methods get fully transpiled JS→Rust bodies
- Base Exchange class methods use stubs (runtime not ready yet)
- Inherited base methods removed from exchange traits (via supertrait)
- Add AST visitors: SpreadElement, ArrowFunction, TemplateLiteral,
  ForOf/ForIn, SwitchStatement, Object.keys/JSON.stringify
- Fix TryStatement, dispatch matching, UFCS, mutability inference
- Add BoolExt, From<i32>, IntoIterator, Not, Promise::all,
  Precise methods, Math methods, Array::is_array
- Add runtime stubs for pre-delimiter Exchange.js functions
- Fix argument count table, usize/rvalue paren mismatch
- binance.rs: 202 real functions, 0 stubs, compiles clean
- All 112 default tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
claude and others added 5 commits March 21, 2026 21:36
…(97.6%)

Key transpiler fixes:
- Fix dispatch function to use self.request() for exchanges without own
  request override, UFCS only when exchange overrides request
- Add pattern-based fallback dispatch detection for API methods not in
  the explicit apiMethods set (privateGet*, publicPost*, etc.)
- Fix HANDWRITTEN_METHODS to conditionally use UFCS or self.request()
  based on whether the exchange overrides request
- Add Value method padding (slice now requires 2 args)
- Fix crypto hash identifiers (keccak, secp256k1, etc.) used as values
  by converting bare references to function calls
- Fix error type constructors used in JSON describe objects
- Add missing free functions: parse_float, ecdsa, totp, jwt, keccak,
  shift_1/3/4, decimals, and error type constructors
- Add argCounts entries for binaryConcat, ethEncodeStructuredData, etc.
- Fix parseToInt argCount (2->1), safeIntegerProduct (3->4)

Runtime (exchange.rs) fixes:
- Add 60+ utility method stubs to Exchange trait (capitalize, uuid,
  base16_to_binary, binary_concat, seconds, etc.)
- Add Value::pad_start(), Value::reduce(), Value::to_fixed() methods
- Upgrade Value::slice() from 1-arg to 2-arg (start, end)
- Add usize <-> Value comparison (PartialEq, PartialOrd, Div)
- Generate dispatch function for all exchanges (not just those with api)

All 112 regression + smoke tests pass. Default build (binance) compiles.

https://claude.ai/code/session_01Kts6beu4ZpQQB8cffDwnDm
…xchanges

- Transpiler: replace `_ => unimplemented!()` in dispatch with descriptive
  `panic!()` messages for unknown API methods
- exchange.rs: implement 60+ runtime/utility stubs with real logic:
  - omit/omitZero, iso8601/parse8601, milliseconds/seconds/microseconds
  - urlencode/rawencode/encodeURIComponent, sortBy/indexBy/filterBy/groupBy
  - hash (sha256/sha384/sha512/md5/keccak) and hmac with hex/base64 encoding
  - parseJson, parseTimeframe, precisionFromString, numberToString
  - uuid/uuid16/uuid22/uuid5, capitalize, randNumber, randomBytes
  - base16/base58/base64 encoding/decoding, binaryConcat, numberToBE
  - deepExtend2, keysort, unique, sort, sortBy2, implodeParams
  - yyyymmdd/ymd/yymmdd date formatting, padStart, isEmpty, toFixed
  - stringToCharsArray, arraySlice, remove0xPrefix, convertToBigInt
- Regenerated all 111 exchange + 78 pro exchange files via --force transpile

All 114 tests pass (112 regression + 1 pro + 1 strict smoke).

https://claude.ai/code/session_01Kts6beu4ZpQQB8cffDwnDm
- Implement 13 stub methods in exchange.rs with real logic (fetch_markets,
  get_base_domain_from_url, get_network_code_by_network_url, sign,
  handle_errors, set_margin_mode, etc.)
- Implement ExchangeImpl::init with proper defaults (precisionMode,
  paddingMode, markets, currencies, symbols, ids)
- Fix 393 compilation errors across all 111 exchange files:
  - Wrap bool/usize values with Value::from() where Value expected
  - Fix borrow checker issues by splitting compound self expressions
  - Extract async calls from json!() macro into let bindings
  - Fix format string errors in panic!() with raw string literals
  - Change &self to &mut self where mutable access needed
  - Fix type annotation ambiguities (.into() -> Value::from())
- Add #![allow(non_snake_case)] to all exchange files for PascalCase
  error constructors
- Add smoke tests for 40 previously untested exchanges (both
  public_data_smoke and pro_public_data)
- Add regression tests for new base class methods
- All 118 regression tests pass, all smoke tests pass
- Full-exchanges build compiles cleanly with zero errors

https://claude.ai/code/session_01Kts6beu4ZpQQB8cffDwnDm
Signed-off-by: Herklos <herklos@drakkar.software>
Signed-off-by: Herklos <herklos@drakkar.software>
Herklos and others added 10 commits March 22, 2026 10:13
Signed-off-by: Herklos <herklos@drakkar.software>
Fixes ~1900+ compilation errors in the `full-pro` feature across
the auto-generated `rust/src/pro/*.rs` WebSocket exchange files.

Changes to `build/rustTranspiler.ts`:
- argCounts: add parseWsOHLCVs, reject:2, reset:1, resolve:2,
  createOrderRequest:6 to normalize call-site argument counts
- BinaryExpression: when left is usize and right is non-usize,
  emit right as Value to use PartialEq<Value>/PartialOrd<Value>
- CallExpression: use .unwrap_usize() instead of .clone().into()
  for Value-to-usize conversions; handle bool-return methods with
  .into() in value context; handle this.clone(x) → x.clone()
- ArrayExpression: auto-await self method calls in async context
  to avoid Pin<Box<dyn Future>> in vec elements
- MemberExpression .length: use Value::from(x.len()) in value ctx
- dispatch method: use .as_str() instead of .as_ref()
- NewExpression: emit constructor args in value context
- isSelfImmutable: add endsWith('FromPrecision'), endsWith('OrMaker'),
  endsWith('Url'), calculateFee; add startsWith('parseWs')
- getReturnType: add startsWith/endsWith as bool-returning methods
- Boolean literals: use Value::from(true/false) instead of true.into()
- Computed property .set(key, ...): emit key in value context
- #[async_trait] → #[async_trait(?Send)] for all pro traits

Changes to `rust/src/exchange.rs`:
- Exchange trait: #[async_trait] → #[async_trait(?Send)]
- Add stubs: on_pong, parse_create_edit_order_args (7 params),
  custom_parse_order_book (8 params)
- Fix stub signatures: reject(1 param→2), reset(0→1), resolve(2),
  safe_market_custom/coin_to_market_id/order_book/order_book_variants
  changed to &self; duplicate neg stub removed

REST exchange files (111 files):
- #[async_trait] → #[async_trait(?Send)] to match Exchange trait

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves per-exchange market-fetching logic into Exchange::load_markets as a
durable default implementation, keyed by exchange id. Parse helpers live as
module-level functions receiving already-fetched response JSON, keeping the
connector layer fully generic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…h compile clean

- Add OHLCV (uppercase) and parseWS* exclusion to isSelfImmutable rules
- Fix signIn argCount to 1 so call sites match base trait definition
- Add transpileFor single-exchange retranspile method + npm scripts
- Fix transpileBaseMethods regex to handle 4-space-indented delimiter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- try/catch: emit labeled blocks 'try_block_N with __try_error_N capture
- throw: context-aware emission (inside try → break label, outside → return Undefined)
- isSelfImmutable: broadened parse*/find*/format*/calculate* prefixes + body-scan AST walk for mutating callers
- BinaryExpression/UnaryExpression in value context: emit Value::from() instead of .into() to avoid E0283 ambiguity in json!() macro
- ObjectExpression property values: use value context for correct type propagation
- LogicalExpression ||/&&/?? in value context: emit paren-wrapped if-else to preserve Value type
- AssignmentExpression RHS: use value context for .set() calls
- Arithmetic operators: propagate usize context when needed
- argCounts: remove exchange-specific overrides now handled by per-class FUNCTION_INFO
- exchange.rs: check_address to &self

cargo check --features full-exchanges: 0 errors, 116 warnings
cargo test: all 127 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add dynamic-route-discovery handwritten Rust bodies for:
- fetchBalance, fetchMyTrades
- fetchOrders, fetchOpenOrders, fetchClosedOrders
- fetchPositions
- createOrder, cancelOrder
- fetchDeposits, fetchWithdrawals

Each body scans describe().api for matching path tokens before falling
back to hardcoded private-API candidates. Pattern mirrors existing
fetchTicker/fetchTickers handlers.

cargo check --features full-exchanges: 0 errors, 94 warnings
cargo test: 127 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 107+ REST exchanges and all pro exchanges now compile with 0 errors.
Enable full-exchanges by default so `cargo check` (no flags) exercises
the full exchange set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Promote the HANDWRITTEN_METHODS bodies for fetch_balance and
fetch_positions from generated exchange overrides into the Exchange
base trait default impls, so any exchange that doesn't define its
own override still gets functional route discovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- rust/src/exchanges/mod.rs: add pub fn create_exchange(name, config) mapping
  all 107 exchanges by lowercase name string; handles binance unconditionally,
  all others behind cfg(feature = "full-exchanges")
- rust/README.md: document runtime vs generated boundary (lines 2825-EOF_MARKER),
  HANDWRITTEN_METHODS vs MANUALLY_IMPLEMENTED_METHODS, retranspile scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Herklos and others added 2 commits May 9, 2026 12:16
- Add `fn describe` override to each `impl Exchange for XxxImpl` so
  calling `Exchange::describe(impl)` correctly delegates to the per-exchange
  trait instead of returning Undefined. This makes HANDWRITTEN_METHODS
  route-discovery work for all 111 exchanges.
- Break circular describe call in deepcoin (Exchange::describe → Deepcoin::describe → loop).
- Fix pro_public_data.rs macro: auto-detect require_pro from describe() instead of hardcoding true.
- Fix public_data_smoke.rs macro: use UFCS for describe, Exchange:: dispatch for other methods.
- Remove 4 unregistered exchange entries (alp, aster, bydfi, zebpay) from both test files.
- Transpiler: emit describe override in exchange footer; generate create_exchange factory in mod.rs.
- Resolve stale polymarket Python merge conflict (deleted by us).

cargo check --features full-exchanges: 0 errors
cargo check --features full-pro: 0 errors
cargo test: 437/437 pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Generate `impl Exchange for XxxImpl` bridges for every parse_* method the
  per-exchange trait overrides (parse_trade, parse_ohlcv, parse_order,
  parse_ticker, parse_position, parse_balance, parse_funding_rate, etc.) so
  callers holding `&dyn Exchange` reach the per-exchange implementation
  instead of the trait default `Value::Undefined`. Same shape for
  fetch_ticker / fetch_tickers / fetch_order_book / fetch_ohlcv /
  fetch_trades / fetch_l2_order_book / fetch_bids_asks / fetch_time /
  fetch_status. Bridges are skipped when the per-exchange override emits
  `&mut self` (would conflict with the `&self` Exchange-trait signature).

- Force `&self` for the parse_* methods we bridge so the bridge body
  compiles, by keying off a new IMMUTABLE_TRAIT_METHODS set. Add
  `addHyphen*`, `removeComma*`, `fixComma*`, `getMarketFrom*`, etc. to the
  pure-helper prefix list so per-exchange string transforms also stay
  `&self` (otherwise their `&mut self` poisons calling parse_* methods).

- Update fetchOHLCV / fetchTrades / fetchOrderBook / fetchTicker
  HANDWRITTEN templates to (a) widen path-substring matching to cover
  exchange-specific tokens (`barhist`, `kline`, etc.) and (b) unwrap the
  raw HTTP response via the new `unwrap_response_array` /
  `unwrap_response_order_book` runtime helpers in exchange.rs, then call
  `<Self as Exchange>::parse_*` per item to produce a normalised array.

- Also re-transpiled all 112 exchanges. The full-exchanges feature
  currently surfaces 41 pre-existing transpiler issues (variadic `sum`,
  missing `await` desugaring, per-method argCount mismatches, dydx
  usize/Value confusion) — all flagged in TRANSPILER_TODO.md and
  unblocked individually as their exchange is needed.

NOTE: Tests still won't pass for non-Binance exchanges even at zero
compile errors — the `urls.api` runtime URL builder hits the website
root (e.g. https://ascendex.com/barhist) instead of the API path
(/api/pro/v1/barhist). That's a separate runtime fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants