Gap
The core ExchangeCredentials interface includes walletAddress?: string — used by LimitlessExchange for delegated signing (looking up a profile ID from a wallet address). The Python SDK's _get_credentials_dict method, which serializes credentials into the sidecar request body, does not include walletAddress in the dict it builds. Even if a caller somehow passes wallet_address during construction (it is not a constructor parameter on the base Exchange), it would be silently dropped before reaching the sidecar.
Core
core/src/BaseExchange.ts:371-392
export interface ExchangeCredentials {
apiKey?: string;
apiSecret?: string;
passphrase?: string;
apiToken?: string;
privateKey?: string;
signatureType?: number | string;
funderAddress?: string;
walletAddress?: string; // ← used by Limitless for delegated signing
baseUrl?: string;
}
core/src/exchanges/limitless/index.ts:104,115 — walletAddress is read from credentials.walletAddress and used to look up the signing profile for delegated orders.
Python SDK
sdks/python/pmxt/client.py:490-506
def _get_credentials_dict(self) -> Optional[Dict[str, Any]]:
"""Build credentials dictionary for API requests."""
if not self.api_key and not self.private_key and not self.api_token:
return None
creds = {}
if self.api_key:
creds["apiKey"] = self.api_key
if self.private_key:
creds["privateKey"] = self.private_key
if self.api_token:
creds["apiToken"] = self.api_token
if self.proxy_address:
creds["funderAddress"] = self.proxy_address
if self.signature_type is not None:
creds["signatureType"] = self.signature_type
return creds if creds else None
walletAddress is never set in this dict. The base Exchange.__init__ also has no wallet_address parameter, so there is no way to supply the value at all.
TypeScript SDK
The TypeScript SDK's getCredentials() method in client.ts similarly builds a credentials object from the constructor options. walletAddress is not part of ExchangeOptions in the TypeScript SDK either, so neither SDK forwards this credential.
Note: Issue #853 tracks the per-exchange OpinionExchangeOptions.walletAddress gap. This issue tracks the lower-level, cross-cutting failure: even if a future fix adds walletAddress to the exchange constructor, the Python credential serialization layer would still silently drop it.
Evidence
grep -n "walletAddress\|wallet_address" sdks/python/pmxt/client.py → zero results.
grep -n "walletAddress" core/src/BaseExchange.ts → line 388.
grep -n "walletAddress" core/src/exchanges/limitless/index.ts → lines 104, 115 confirming the field is consumed by exchange logic.
Impact
Limitless delegated signing workflows cannot pass the walletAddress credential through the Python SDK, even if the caller knows the wallet address. The credential is absent from the serialized dict sent to the sidecar, so the sidecar-side LimitlessExchange sees credentials.walletAddress === undefined and falls through to the default signing path. Delegated signing fails silently — no error, just wrong behavior (orders placed on the caller's own profile instead of the delegated profile).
Found by automated Core-to-SDK surface coverage audit
Gap
The core
ExchangeCredentialsinterface includeswalletAddress?: string— used byLimitlessExchangefor delegated signing (looking up a profile ID from a wallet address). The Python SDK's_get_credentials_dictmethod, which serializes credentials into the sidecar request body, does not includewalletAddressin the dict it builds. Even if a caller somehow passeswallet_addressduring construction (it is not a constructor parameter on the baseExchange), it would be silently dropped before reaching the sidecar.Core
core/src/BaseExchange.ts:371-392core/src/exchanges/limitless/index.ts:104,115—walletAddressis read fromcredentials.walletAddressand used to look up the signing profile for delegated orders.Python SDK
sdks/python/pmxt/client.py:490-506walletAddressis never set in this dict. The baseExchange.__init__also has nowallet_addressparameter, so there is no way to supply the value at all.TypeScript SDK
The TypeScript SDK's
getCredentials()method inclient.tssimilarly builds a credentials object from the constructor options.walletAddressis not part ofExchangeOptionsin the TypeScript SDK either, so neither SDK forwards this credential.Note: Issue #853 tracks the per-exchange
OpinionExchangeOptions.walletAddressgap. This issue tracks the lower-level, cross-cutting failure: even if a future fix addswalletAddressto the exchange constructor, the Python credential serialization layer would still silently drop it.Evidence
grep -n "walletAddress\|wallet_address" sdks/python/pmxt/client.py→ zero results.grep -n "walletAddress" core/src/BaseExchange.ts→ line 388.grep -n "walletAddress" core/src/exchanges/limitless/index.ts→ lines 104, 115 confirming the field is consumed by exchange logic.Impact
Limitless delegated signing workflows cannot pass the
walletAddresscredential through the Python SDK, even if the caller knows the wallet address. The credential is absent from the serialized dict sent to the sidecar, so the sidecar-sideLimitlessExchangeseescredentials.walletAddress === undefinedand falls through to the default signing path. Delegated signing fails silently — no error, just wrong behavior (orders placed on the caller's own profile instead of the delegated profile).Found by automated Core-to-SDK surface coverage audit