Skip to content

SDK drift: apiSecret forwards generically for all 17 TypeScript venue classes; Python's api_secret constructor param exists on only 4 of 17 #2158

Open

Description

@realfishsam

Drift

TypeScript's base Exchange class accepts apiSecret as a generic ExchangeOptions field and forwards it unconditionally to the sidecar for every venue subclass. Python's base Exchange.__init__ has no api_secret parameter at all, and only 4 of the 17 venue subclasses in _exchanges.py add their own api_secret parameter + override to forward it — the other 13 don't accept it as a keyword argument, so passing one raises TypeError.

Note: the earlier, TS-side version of this gap (Exchange.getCredentials() never forwarding apiSecret at all) was already tracked and fixed — see closed issues #1371 (merged via #1375), #1041, #971, #881. This issue is the current, still-open asymmetry that remains after that fix: TypeScript's forwarding is now generic across all venues, while Python's is restricted to a hand-picked subset.

TypeScript SDK

sdks/typescript/pmxt/client.ts:238 — apiSecret?: string; on base ExchangeOptions.
sdks/typescript/pmxt/client.ts:376 — this.apiSecret = options.apiSecret; in the base Exchange constructor.
sdks/typescript/pmxt/client.ts:483-489 (getCredentials()):

protected getCredentials(): ExchangeCredentials | undefined {
    if (!this.apiKey && !this.apiSecret && !this.privateKey) {
        return undefined;
    }
    return {
        apiKey: this.apiKey,
        apiSecret: this.apiSecret,   // forwarded unconditionally for every venue
        privateKey: this.privateKey,
        funderAddress: this.proxyAddress,
        signatureType: this.signatureType,
    };
}

Every venue class that just takes generic ExchangeOptions (e.g. Kalshi, Smarkets, Hyperliquid, Myriad, SuiBets, Rain, Hunch, Mock, Baozi, Opinion, Metaculus, PolymarketUS, KalshiDemo) therefore accepts new Kalshi({ apiSecret: '...' }).

Python SDK

Base Exchange.__init__ (sdks/python/pmxt/client.py:324-338) has no api_secret parameter, and _get_credentials_dict (client.py:559-575) never references it. Only 4 venue classes in sdks/python/pmxt/_exchanges.py add api_secret themselves: Polymarket (line 16), Limitless (line 82), Probable (line 217), GeminiTitan (line 546) — each with its own self.api_secret = api_secret and if self.api_secret: creds["apiSecret"] = self.api_secret override. The other 13 venue classes (e.g. Kalshi at _exchanges.py:131-168) have no api_secret parameter — pmxt.Kalshi(api_secret="...") raises TypeError: __init__() got an unexpected keyword argument 'api_secret'.

Expected

Python's per-venue constructors should generically accept and forward api_secret, matching TypeScript's uniform ExchangeOptions.apiSecret handling across all 17 venues — or, if apiSecret is intentionally meaningful only for specific venues, TypeScript should narrow getCredentials()/ExchangeOptions to the same venue subset Python uses.

Impact

This follows the same architectural pattern as the already-tracked #1889 (proxy_address/signature_type dropped by 15 of 17 Python venue constructors) and #1926 (api_key/private_key dropped by Baozi/Rain/Hunch/Mock/SuiBets in Python) — for the apiSecret field specifically, which neither of those covers. A user porting code from TypeScript to Python that passes apiSecret to any of the 13 unsupported Python venue classes gets an immediate, hard constructor TypeError, not a silently-ignored field.


Found by automated SDK cross-language drift audit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions