CCXT

CCXT vs the Pacifica API and the Pacifica Python examples

Pacifica signs every write with a Solana Ed25519 key over sorted JSON. Compare its Python examples repo with CCXT on signing, coverage, streaming and rate limits.

Pacifica is a Solana-based perpetuals DEX. Every state-changing request is signed with a Solana Ed25519 key: you build a header of {type, timestamp, expiry_window}, nest your payload under data, sort the JSON keys recursively, serialise it compactly, sign the bytes, and base58-encode the signature.

The client library Pacifica's own API documentation points at is pacifica-fi/python-sdk. Read on the day this page was written, it is an examples repository, not a package: rest/, ws/ and common/ folders, a requirements.txt, no releases, no PyPI distribution, and a README whose instructions are "Modify the PRIVATE_KEY in the desired example file… run python3 -m rest.create_market_order". It is actively maintained — 40 commits, most recent in February 2026 — and it is genuinely useful as a reference for the signing scheme. It is not a dependency you install.

CCXT implements the same signing scheme as a library, behind method names shared with 103 other venues. The question: do you want to copy the reference implementation into your codebase, or import one?

TL;DR

  • Use Pacifica's examples if you are learning the signing scheme, want a one-file-per-endpoint reference alongside the docs, or need something CCXT does not do — hardware-wallet signing in particular.
  • Pick CCXT if you want an installable dependency: 59 unified capabilities, 13 watch* / unWatch* streaming methods, credit-aware rate limiting and testnet support, in seven languages.
  • The cryptography is identical. CCXT's sortJsonKeys / prepareMessage / signMessage produce the same bytes as the examples' sort_json_keys / prepare_message / sign_message, including agent-wallet support. The choice is about packaging and coverage, not signing.

At a glance

CCXTpacifica-fi/python-sdk
Exchanges covered104 (Pacifica is one of them)Pacifica only
Distributionpip install ccxt, npm install ccxt, …clone the repository; no PyPI package, no releases
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java — one APIPython only
Unified market data + trading APIyes — same method names across every exchangeno — one script per endpoint
Unified capabilities implemented59 for pacifica, of which 24 are fetch*n/a
Symbols'BTC/USDC:USDC'"BTC"
CredentialsprivateKey (base58 Solana key); agent wallets via options['agentAddress']PRIVATE_KEY edited into each script
Hardware wallet signingnoyes — sign_with_hardware_wallet() shells out to solana sign-offchain-message
WebSocketsyes — 7 watch* plus 6 unWatch* methodsyes — raw websockets connections, one script per subscription
Raw endpoint accessyes — 67 endpoints as implicit methodsit is all raw
Built-in rate limiteryes, on by default (rateLimit 600 ms) with Pacifica's fractional credit costs modellednone
Unified error typesyes — 41 typed exceptions in one hierarchyraw requests responses; you check status_code
Testnetset_sandbox_mode(True) swaps in test-api.pacifica.fi and test-ws.pacifica.fichange the constant
Popularity43.8k GitHub stars · 4.8M PyPI + 494k npm installs/month (one package, every venue)18 GitHub stars, 23 forks, 40 commits
LicenceMITno licence file in the repository
SupportDiscord, Telegram, GitHub — usually same-dayGitHub issues

Figures verified September 2026 against CCXT v4.5.77, the pacifica-fi/python-sdk repository (README, rest/, ws/, common/utils.py, commit history) and Pacifica's published API and rate-limit documentation.

The same job, written both ways

Fetch a ticker

import ccxt

exchange = ccxt.pacifica()
tickers = exchange.fetch_tickers(['BTC/USDC:USDC'])
print(tickers['BTC/USDC:USDC']['last'])

CCXT returns a unified ticker structure keyed by unified symbol — the same keys, types and units you get from Binance or Hyperliquid — with "BTC" translated to and from 'BTC/USDC:USDC'.

Place a market order

This is where the difference is largest, because Pacifica's write path is a signing exercise.

import ccxt

exchange = ccxt.pacifica({'privateKey': '...'})   # base58 Solana key
order = exchange.create_order('BTC/USDC:USDC', 'market', 'buy', 0.1)
print(order['id'], order['status'])

That second snippet is the example file verbatim, and it is not padding — every write endpoint in the repository repeats that structure with a different type and payload. The parts that must be exactly right are the header field names, the recursive key sort, the compact JSON separators, and the base58 encoding of the signature. CCXT implements all of it (sortJsonKeys, prepareMessage, signMessage), including the agent-wallet path where a delegated key signs while walletAddress stays the main account:

exchange = ccxt.pacifica({
    'privateKey': '...',            # agent key
    'walletAddress': '...',         # main account address
    'options': {'agentAddress': '...'},
})

Stream an order book

import ccxt.pro
import asyncio

async def main():
    exchange = ccxt.pro.pacifica()
    while True:
        orderbook = await exchange.watch_order_book('BTC/USDC:USDC')
        print(orderbook['bids'][0], orderbook['asks'][0])

asyncio.run(main())

The example is a raw socket with a ping interval. What it does not have — because it is an example, not a library — is reconnect, resubscribe-after-reconnect, order-book snapshot/delta merging, gap detection or a bounded cache. Those are the parts that do not fail loudly: a hand-rolled book does not throw, it drifts, and you find out from a fill you did not expect.

CCXT implements 7 streaming methods for pacificawatchOrderBook, watchTrades, watchOHLCV, watchTicker, watchTickers, watchOrders and watchMyTrades — plus 6 matching unWatch* methods for tearing subscriptions down cleanly. watch_order_book returns the same order book structure as fetch_order_book.

Where the differences actually bite

Rate limits modelled as credits, not requests

Pacifica does not meter requests; it meters credits. Its documentation gives an unidentified IP 125 credits per 60 seconds and a valid API config key 300, rising with fee tier to 40,000 at VIP3. Standard requests cost 1 credit, order cancellations cost 0.5, and heavy GETs cost 1–3 or 3–12 depending on whether you are identified. When the bucket empties you get HTTP 429.

CCXT encodes that. rateLimit is 600 ms, the throttler is on by default, and the per-endpoint cost function models the fractional cancel cost and the identified-versus-anonymous heavy-GET difference, so a cancel-heavy strategy is not paced as though every call cost the same.

WebSocket limits are documented too — a maximum of 300 concurrent connections per IP and 20 subscriptions per channel per connection. CCXT pools one client per URL and multiplexes subscriptions over it, so a strategy watching thirty symbols does not open thirty sockets.

One error hierarchy

CCXT maps Pacifica's error responses onto a typed exception treeInsufficientFunds, InvalidOrder, OrderNotFound, RateLimitExceeded, AuthenticationError, NetworkError, ExchangeNotAvailable and 34 more, all descending from BaseError. The examples hand you a requests.Response and print status_code.

Precision, rounding and string math

Pacifica publishes tick_size, lot_size, min_order_size and max_order_size per market. load_markets() loads them, and CCXT exposes them through amount_to_precision, price_to_precision and cost_to_precision, backed by the Precise string-arithmetic class so quantities never drift through float rounding into a rejected order:

amount = exchange.amount_to_precision('BTC/USDC:USDC', 0.0012345678)
price = exchange.price_to_precision('BTC/USDC:USDC', 61234.56789)

Coverage beyond order entry

The unified surface for pacifica is 59 capabilities, including fetchPositions, fetchLeverage / setLeverage, fetchMarginMode / setMarginMode, fetchFundingRates and fetchFundingRateHistory, fetchOpenInterest / fetchOpenInterests, fetchLedger, fetchTradingFee, createOrders, editOrder, cancelOrders and createOrderWithTakeProfitAndStopLoss — each returning a unified structure. Reproducing that from the examples means one signing block per operation.

Seven languages, one API

CCXT is written once in TypeScript and transpiled to JavaScript, Python, PHP, C#/.NET, Go and Java, with identical method names and return structures — including the Ed25519 signing, which is base-class code rather than something you re-derive per language.

import ccxt
exchange = ccxt.pacifica()
tickers = exchange.fetch_tickers(['BTC/USDC:USDC'])

Testnet without a second code path

exchange = ccxt.pacifica({'privateKey': '...'})
exchange.set_sandbox_mode(True)   # test-api.pacifica.fi and test-ws.pacifica.fi

Nothing is hidden — the implicit API

Alongside the 59 unified capabilities, all 67 endpoints in the API definition are generated as callable implicit methods, with signing, rate-limit accounting and error mapping applied. Browse them on the pacifica implicit API page.

What Pacifica's examples repository does better

An honest list, and some of these are real gaps:

  • Hardware-wallet signing. common/utils.py includes sign_with_hardware_wallet(), which shells out to solana sign-offchain-message with a Ledger keypath. CCXT signs with an in-process base58 private key and has no hardware-wallet path, so if your keys live on a Ledger, the examples are the reference and CCXT is not an option.
  • It is the canonical reference for the signing scheme. When you need to know exactly what bytes get signed, reading prepare_message() and sign_message() is more direct than reading a transpiled library.
  • New endpoints appear there first. Pacifica writes the API and the examples. Subaccount creation, leverage updates and other recent additions show up as example scripts as they ship, ahead of any unified wrapper.
  • One file per operation is a good teaching shape. rest/create_market_order.py shows the whole request — header, payload, signature, HTTP call — on one screen. A library necessarily hides that.
  • A far smaller footprint. requests plus solders plus base58 is a much smaller dependency set than a library covering 104 exchanges.

If Pacifica is your only venue, you are in Python, and especially if you sign with a hardware wallet, working from the examples is the right call.

Migrating from the Pacifica examples to CCXT

What you are doingPacifica examplesCCXT
Symbols"BTC"'BTC/USDC:USDC'
CredentialsPRIVATE_KEY in each scriptccxt.pacifica({'privateKey': '...'})
Signingsign_message(header, payload, keypair)handled inside every private method
MarketsGET /infoload_markets()
PricesGET /info/pricesfetch_tickers()
Order bookGET /bookfetch_order_book()
CandlesGET /klinefetch_ohlcv()
Public tradesGET /tradesfetch_trades()
Market orderPOST /orders/create_marketcreate_order(symbol, 'market', side, amount)
Limit orderPOST /orders/createcreate_order(symbol, 'limit', side, amount, price)
Cancel orderPOST /orders/cancelcancel_order()
Cancel allPOST /orders/cancel_allcancel_all_orders()
Edit orderPOST /orders/editedit_order()
Open ordersGET /ordersfetch_open_orders()
PositionsGET /positionsfetch_positions()
BalanceGET /accountfetch_balance()
LeveragePOST /account/leveragefetch_leverage() / set_leverage()
Margin modePOST /account/marginfetch_margin_mode() / set_margin_mode()
FundingGET /funding_rate/history, GET /funding/historyfetch_funding_rates() / fetch_funding_rate_history() / fetch_funding_history()
Streamsraw websockets subscription per scriptwatch_* / un_watch_* on ccxt.pro.pacifica
Testnetuncomment the testnet REST_URL / WS_URL constantsset_sandbox_mode(True)
Anything not listedraw signed callthe same endpoint as an implicit method

Start with Install, then the Manual, then the pacifica unified API reference.

FAQ

Does Pacifica have an official SDK I can pip install? Not as of this writing. pacifica-fi/python-sdk — the repository Pacifica's own documentation links to — is an examples repository: it has rest/, ws/ and common/ folders and a requirements.txt, but no releases and no PyPI package. CCXT is an installable dependency that implements the same API.

How does Pacifica authentication work, and does CCXT handle it? Yes. Pacifica signs each write with a Solana Ed25519 key over a compact, recursively key-sorted JSON message of {type, timestamp, expiry_window, data}, base58-encoding the signature. CCXT implements exactly that, including agent wallets: pass the agent key as privateKey, the main account as walletAddress, and the agent address in options['agentAddress'].

Can CCXT sign Pacifica orders with a Ledger? No. CCXT signs with an in-process base58 private key. Pacifica's examples include a sign_with_hardware_wallet() helper that shells out to the Solana CLI's sign-offchain-message; there is no equivalent in CCXT.

Does CCXT support Pacifica WebSockets? Yes — 7 watch* methods (order book, trades, OHLCV, ticker, tickers, orders, own trades) and 6 matching unWatch* methods, with reconnection, resubscription and order-book merging handled for you.

Does CCXT respect Pacifica's credit-based rate limits? Yes. The throttler is on by default and the per-endpoint cost function models Pacifica's published weights, including the 0.5-credit cost of a cancellation and the different cost of heavy GETs with and without an API config key.

Can I test on Pacifica's testnet? Yes. exchange.set_sandbox_mode(True) swaps in test-api.pacifica.fi and test-ws.pacifica.fi in one call.

Next steps

On this page