pmxt 1.5.4__py3-none-any.whl → 1.5.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pmxt/__init__.py CHANGED
@@ -33,7 +33,7 @@ from .models import (
33
33
  CreateOrderParams,
34
34
  )
35
35
 
36
- __version__ = "1.5.4"
36
+ __version__ = "1.5.6"
37
37
  __all__ = [
38
38
  # Exchanges
39
39
  "Polymarket",
@@ -83184,10 +83184,14 @@ var require_lib36 = __commonJS({
83184
83184
  var require_auth = __commonJS({
83185
83185
  "dist/exchanges/polymarket/auth.js"(exports2) {
83186
83186
  "use strict";
83187
+ var __importDefault = exports2 && exports2.__importDefault || function(mod) {
83188
+ return mod && mod.__esModule ? mod : { "default": mod };
83189
+ };
83187
83190
  Object.defineProperty(exports2, "__esModule", { value: true });
83188
83191
  exports2.PolymarketAuth = void 0;
83189
83192
  var clob_client_1 = (init_dist2(), __toCommonJS(dist_exports));
83190
83193
  var ethers_1 = require_lib36();
83194
+ var axios_1 = __importDefault(require_axios());
83191
83195
  var POLYMARKET_HOST = "https://clob.polymarket.com";
83192
83196
  var POLYGON_CHAIN_ID = 137;
83193
83197
  var PolymarketAuth = class {
@@ -83218,20 +83222,84 @@ var require_auth = __commonJS({
83218
83222
  let creds;
83219
83223
  try {
83220
83224
  creds = await l1Client.deriveApiKey();
83225
+ if (!creds || !creds.key || !creds.secret || !creds.passphrase) {
83226
+ throw new Error("Derived credentials are incomplete/empty");
83227
+ }
83221
83228
  } catch (deriveError) {
83229
+ console.log("[PolymarketAuth] Derivation failed:", deriveError.message || deriveError);
83230
+ console.log("[PolymarketAuth] Attempting to create new API key...");
83222
83231
  try {
83223
83232
  creds = await l1Client.createApiKey();
83233
+ console.log("[PolymarketAuth] createApiKey returned:", JSON.stringify(creds, null, 2));
83224
83234
  } catch (createError) {
83225
- console.error("Failed to both derive and create API key:", createError?.message || createError);
83226
- throw new Error("Authentication failed: Could not create or derive API key.");
83235
+ const apiError = createError?.response?.data?.error || createError?.message || createError;
83236
+ console.error("[PolymarketAuth] Failed to both derive and create API key. Create error:", apiError);
83237
+ throw new Error(`Authentication failed: Could not create or derive API key. Latest error: ${apiError}`);
83227
83238
  }
83228
83239
  }
83229
- if (!creds) {
83230
- throw new Error("Authentication failed: Credentials are empty.");
83240
+ if (!creds || !creds.key || !creds.secret || !creds.passphrase) {
83241
+ console.error("[PolymarketAuth] Incomplete credentials:", { hasKey: !!creds?.key, hasSecret: !!creds?.secret, hasPassphrase: !!creds?.passphrase });
83242
+ throw new Error("Authentication failed: Derived credentials are incomplete.");
83231
83243
  }
83244
+ console.log(`[PolymarketAuth] Successfully obtained API credentials for key ${creds.key.substring(0, 8)}...`);
83232
83245
  this.apiCreds = creds;
83233
83246
  return creds;
83234
83247
  }
83248
+ /**
83249
+ * Discover the proxy address and signature type for the signer.
83250
+ */
83251
+ async discoverProxy() {
83252
+ if (this.discoveredProxyAddress) {
83253
+ return {
83254
+ proxyAddress: this.discoveredProxyAddress,
83255
+ signatureType: this.discoveredSignatureType ?? 0
83256
+ };
83257
+ }
83258
+ const address = this.signer.address;
83259
+ try {
83260
+ const response = await axios_1.default.get(`https://data-api.polymarket.com/profiles/${address}`);
83261
+ const profile = response.data;
83262
+ console.log(`[PolymarketAuth] Profile for ${address}:`, JSON.stringify(profile));
83263
+ if (profile && profile.proxyAddress) {
83264
+ this.discoveredProxyAddress = profile.proxyAddress;
83265
+ this.discoveredSignatureType = profile.isGnosisSafe ? 2 : 1;
83266
+ console.log(`[PolymarketAuth] Auto-discovered proxy for ${address}: ${this.discoveredProxyAddress} (Type: ${this.discoveredSignatureType})`);
83267
+ return {
83268
+ proxyAddress: this.discoveredProxyAddress,
83269
+ signatureType: this.discoveredSignatureType
83270
+ };
83271
+ }
83272
+ } catch (error) {
83273
+ console.warn(`[PolymarketAuth] Could not auto-discover proxy for ${address}:`, error instanceof Error ? error.message : error);
83274
+ }
83275
+ return {
83276
+ proxyAddress: address,
83277
+ signatureType: 0
83278
+ };
83279
+ }
83280
+ /**
83281
+ * Maps human-readable signature type names to their numeric values.
83282
+ */
83283
+ mapSignatureType(type) {
83284
+ if (type === void 0 || type === null)
83285
+ return 0;
83286
+ if (typeof type === "number")
83287
+ return type;
83288
+ const normalized = type.toLowerCase().replace(/[^a-z0-9]/g, "");
83289
+ switch (normalized) {
83290
+ case "eoa":
83291
+ return 0;
83292
+ case "polyproxy":
83293
+ case "polymarketproxy":
83294
+ return 1;
83295
+ case "gnosissafe":
83296
+ case "safe":
83297
+ return 2;
83298
+ default:
83299
+ const parsed = parseInt(normalized);
83300
+ return isNaN(parsed) ? 0 : parsed;
83301
+ }
83302
+ }
83235
83303
  /**
83236
83304
  * Get an authenticated CLOB client for L2 operations (trading).
83237
83305
  * This client can place orders, cancel orders, query positions, etc.
@@ -83240,12 +83308,40 @@ var require_auth = __commonJS({
83240
83308
  if (this.clobClient) {
83241
83309
  return this.clobClient;
83242
83310
  }
83311
+ let proxyAddress = this.credentials.funderAddress || void 0;
83312
+ let signatureType = this.mapSignatureType(this.credentials.signatureType);
83313
+ if (!proxyAddress) {
83314
+ const discovered = await this.discoverProxy();
83315
+ proxyAddress = discovered.proxyAddress;
83316
+ if (this.credentials.signatureType === void 0 || this.credentials.signatureType === null) {
83317
+ signatureType = discovered.signatureType;
83318
+ }
83319
+ }
83243
83320
  const apiCreds = await this.getApiCredentials();
83244
- const signatureType = this.credentials.signatureType ?? 0;
83245
- const funderAddress = this.credentials.funderAddress ?? this.signer.address;
83246
- this.clobClient = new clob_client_1.ClobClient(POLYMARKET_HOST, POLYGON_CHAIN_ID, this.signer, apiCreds, signatureType, funderAddress);
83321
+ const signerAddress = this.signer.address;
83322
+ const finalProxyAddress = proxyAddress || signerAddress;
83323
+ const finalSignatureType = signatureType;
83324
+ console.log(`[PolymarketAuth] Initializing ClobClient | Signer: ${signerAddress} | Funder: ${finalProxyAddress} | SigType: ${finalSignatureType}`);
83325
+ this.clobClient = new clob_client_1.ClobClient(POLYMARKET_HOST, POLYGON_CHAIN_ID, this.signer, apiCreds, finalSignatureType, finalProxyAddress);
83247
83326
  return this.clobClient;
83248
83327
  }
83328
+ /**
83329
+ * Get the funder address (Proxy) if available.
83330
+ * Note: This is an async-safe getter if discovery is needed.
83331
+ */
83332
+ async getEffectiveFunderAddress() {
83333
+ if (this.credentials.funderAddress) {
83334
+ return this.credentials.funderAddress;
83335
+ }
83336
+ const discovered = await this.discoverProxy();
83337
+ return discovered.proxyAddress;
83338
+ }
83339
+ /**
83340
+ * Synchronous getter for credentials funder address.
83341
+ */
83342
+ getFunderAddress() {
83343
+ return this.credentials.funderAddress || this.signer.address;
83344
+ }
83249
83345
  /**
83250
83346
  * Get the signer's address.
83251
83347
  */
@@ -104947,11 +105043,15 @@ var require_polymarket = __commonJS({
104947
105043
  const client = await auth.getClobClient();
104948
105044
  try {
104949
105045
  const order = await client.getOrder(orderId);
105046
+ if (!order || !order.id) {
105047
+ const errorMsg = order?.error || "Order not found (Invalid ID)";
105048
+ throw new Error(errorMsg);
105049
+ }
104950
105050
  return {
104951
105051
  id: order.id,
104952
105052
  marketId: order.market || "unknown",
104953
105053
  outcomeId: order.asset_id,
104954
- side: order.side.toLowerCase(),
105054
+ side: (order.side || "").toLowerCase(),
104955
105055
  type: order.order_type === "GTC" ? "limit" : "market",
104956
105056
  price: parseFloat(order.price),
104957
105057
  amount: parseFloat(order.original_size),
@@ -104991,7 +105091,7 @@ var require_polymarket = __commonJS({
104991
105091
  }
104992
105092
  async fetchPositions() {
104993
105093
  const auth = this.ensureAuth();
104994
- const address = auth.getAddress();
105094
+ const address = await auth.getEffectiveFunderAddress();
104995
105095
  return (0, fetchPositions_1.fetchPositions)(address);
104996
105096
  }
104997
105097
  async fetchBalance() {
@@ -104999,11 +105099,32 @@ var require_polymarket = __commonJS({
104999
105099
  const client = await auth.getClobClient();
105000
105100
  try {
105001
105101
  const USDC_DECIMALS = 6;
105002
- const balRes = await client.getBalanceAllowance({
105003
- asset_type: clob_client_1.AssetType.COLLATERAL
105004
- });
105005
- const rawBalance = parseFloat(balRes.balance);
105006
- const total = rawBalance / Math.pow(10, USDC_DECIMALS);
105102
+ let total = 0;
105103
+ try {
105104
+ const balRes = await client.getBalanceAllowance({
105105
+ asset_type: clob_client_1.AssetType.COLLATERAL
105106
+ });
105107
+ const rawBalance = parseFloat(balRes.balance);
105108
+ total = rawBalance / Math.pow(10, USDC_DECIMALS);
105109
+ } catch (clobError) {
105110
+ }
105111
+ if (total === 0) {
105112
+ try {
105113
+ const { ethers } = require_lib36();
105114
+ const provider = new ethers.providers.JsonRpcProvider("https://polygon-rpc.com");
105115
+ const usdcAddress = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
105116
+ const usdcAbi = ["function balanceOf(address) view returns (uint256)", "function decimals() view returns (uint8)"];
105117
+ const usdcContract = new ethers.Contract(usdcAddress, usdcAbi, provider);
105118
+ const targetAddress = await auth.getEffectiveFunderAddress();
105119
+ const usdcBal = await usdcContract.balanceOf(targetAddress);
105120
+ const decimals = await usdcContract.decimals();
105121
+ const onChainTotal = parseFloat(ethers.utils.formatUnits(usdcBal, decimals));
105122
+ if (onChainTotal > 0) {
105123
+ total = onChainTotal;
105124
+ }
105125
+ } catch (chainError) {
105126
+ }
105127
+ }
105007
105128
  const openOrders = await client.getOpenOrders({});
105008
105129
  let locked = 0;
105009
105130
  if (openOrders && Array.isArray(openOrders)) {
@@ -105469,6 +105590,29 @@ var require_auth2 = __commonJS({
105469
105590
  this.apiCreds = creds;
105470
105591
  return creds;
105471
105592
  }
105593
+ /**
105594
+ * Maps human-readable signature type names to their numeric values.
105595
+ */
105596
+ mapSignatureType(type) {
105597
+ if (type === void 0 || type === null)
105598
+ return 0;
105599
+ if (typeof type === "number")
105600
+ return type;
105601
+ const normalized = type.toLowerCase().replace(/[^a-z0-9]/g, "");
105602
+ switch (normalized) {
105603
+ case "eoa":
105604
+ return 0;
105605
+ case "polyproxy":
105606
+ case "polymarketproxy":
105607
+ return 1;
105608
+ case "gnosissafe":
105609
+ case "safe":
105610
+ return 2;
105611
+ default:
105612
+ const parsed = parseInt(normalized);
105613
+ return isNaN(parsed) ? 0 : parsed;
105614
+ }
105615
+ }
105472
105616
  /**
105473
105617
  * Get an authenticated CLOB client for L2 operations (trading).
105474
105618
  * This client can place orders, cancel orders, query positions, etc.
@@ -105478,7 +105622,7 @@ var require_auth2 = __commonJS({
105478
105622
  return this.clobClient;
105479
105623
  }
105480
105624
  const apiCreds = await this.getApiCredentials();
105481
- const signatureType = this.credentials.signatureType ?? 0;
105625
+ const signatureType = this.mapSignatureType(this.credentials.signatureType);
105482
105626
  const funderAddress = this.credentials.funderAddress ?? this.signer.address;
105483
105627
  this.clobClient = new clob_client_1.ClobClient(LIMITLESS_HOST, BASE_CHAIN_ID, this.signer, apiCreds, signatureType, funderAddress);
105484
105628
  return this.clobClient;
@@ -106576,10 +106720,12 @@ var require_websocket5 = __commonJS({
106576
106720
  this.orderBookResolvers = /* @__PURE__ */ new Map();
106577
106721
  this.tradeResolvers = /* @__PURE__ */ new Map();
106578
106722
  this.orderBooks = /* @__PURE__ */ new Map();
106579
- this.subscribedTickers = /* @__PURE__ */ new Set();
106723
+ this.subscribedOrderBookTickers = /* @__PURE__ */ new Set();
106724
+ this.subscribedTradeTickers = /* @__PURE__ */ new Set();
106580
106725
  this.messageIdCounter = 1;
106581
106726
  this.isConnecting = false;
106582
106727
  this.isConnected = false;
106728
+ this.isTerminated = false;
106583
106729
  this.auth = auth;
106584
106730
  this.config = {
106585
106731
  wsUrl: config.wsUrl || "wss://api.elections.kalshi.com/trade-api/ws/v2",
@@ -106587,11 +106733,17 @@ var require_websocket5 = __commonJS({
106587
106733
  };
106588
106734
  }
106589
106735
  async connect() {
106590
- if (this.isConnected || this.isConnecting) {
106736
+ if (this.isConnected) {
106591
106737
  return;
106592
106738
  }
106739
+ if (this.isTerminated) {
106740
+ return;
106741
+ }
106742
+ if (this.connectionPromise) {
106743
+ return this.connectionPromise;
106744
+ }
106593
106745
  this.isConnecting = true;
106594
- return new Promise((resolve, reject) => {
106746
+ this.connectionPromise = new Promise((resolve, reject) => {
106595
106747
  try {
106596
106748
  const url2 = new URL(this.config.wsUrl);
106597
106749
  const path = url2.pathname;
@@ -106601,9 +106753,13 @@ var require_websocket5 = __commonJS({
106601
106753
  this.ws.on("open", () => {
106602
106754
  this.isConnected = true;
106603
106755
  this.isConnecting = false;
106756
+ this.connectionPromise = void 0;
106604
106757
  console.log("Kalshi WebSocket connected");
106605
- if (this.subscribedTickers.size > 0) {
106606
- this.subscribeToOrderbook(Array.from(this.subscribedTickers));
106758
+ if (this.subscribedOrderBookTickers.size > 0) {
106759
+ this.subscribeToOrderbook(Array.from(this.subscribedOrderBookTickers));
106760
+ }
106761
+ if (this.subscribedTradeTickers.size > 0) {
106762
+ this.subscribeToTrades(Array.from(this.subscribedTradeTickers));
106607
106763
  }
106608
106764
  resolve();
106609
106765
  });
@@ -106618,21 +106774,30 @@ var require_websocket5 = __commonJS({
106618
106774
  this.ws.on("error", (error) => {
106619
106775
  console.error("Kalshi WebSocket error:", error);
106620
106776
  this.isConnecting = false;
106777
+ this.connectionPromise = void 0;
106621
106778
  reject(error);
106622
106779
  });
106623
106780
  this.ws.on("close", () => {
106624
- console.log("Kalshi WebSocket closed");
106781
+ if (!this.isTerminated) {
106782
+ console.log("Kalshi WebSocket closed");
106783
+ this.scheduleReconnect();
106784
+ }
106625
106785
  this.isConnected = false;
106626
106786
  this.isConnecting = false;
106627
- this.scheduleReconnect();
106787
+ this.connectionPromise = void 0;
106628
106788
  });
106629
106789
  } catch (error) {
106630
106790
  this.isConnecting = false;
106791
+ this.connectionPromise = void 0;
106631
106792
  reject(error);
106632
106793
  }
106633
106794
  });
106795
+ return this.connectionPromise;
106634
106796
  }
106635
106797
  scheduleReconnect() {
106798
+ if (this.isTerminated) {
106799
+ return;
106800
+ }
106636
106801
  if (this.reconnectTimer) {
106637
106802
  clearTimeout(this.reconnectTimer);
106638
106803
  }
@@ -106803,9 +106968,9 @@ var require_websocket5 = __commonJS({
106803
106968
  if (!this.isConnected) {
106804
106969
  await this.connect();
106805
106970
  }
106806
- if (!this.subscribedTickers.has(ticker)) {
106807
- this.subscribedTickers.add(ticker);
106808
- this.subscribeToOrderbook([ticker]);
106971
+ if (!this.subscribedOrderBookTickers.has(ticker)) {
106972
+ this.subscribedOrderBookTickers.add(ticker);
106973
+ this.subscribeToOrderbook(Array.from(this.subscribedOrderBookTickers));
106809
106974
  }
106810
106975
  return new Promise((resolve, reject) => {
106811
106976
  if (!this.orderBookResolvers.has(ticker)) {
@@ -106818,9 +106983,9 @@ var require_websocket5 = __commonJS({
106818
106983
  if (!this.isConnected) {
106819
106984
  await this.connect();
106820
106985
  }
106821
- if (!this.subscribedTickers.has(ticker)) {
106822
- this.subscribedTickers.add(ticker);
106823
- this.subscribeToTrades([ticker]);
106986
+ if (!this.subscribedTradeTickers.has(ticker)) {
106987
+ this.subscribedTradeTickers.add(ticker);
106988
+ this.subscribeToTrades(Array.from(this.subscribedTradeTickers));
106824
106989
  }
106825
106990
  return new Promise((resolve, reject) => {
106826
106991
  if (!this.tradeResolvers.has(ticker)) {
@@ -106830,12 +106995,32 @@ var require_websocket5 = __commonJS({
106830
106995
  });
106831
106996
  }
106832
106997
  async close() {
106998
+ this.isTerminated = true;
106833
106999
  if (this.reconnectTimer) {
106834
107000
  clearTimeout(this.reconnectTimer);
107001
+ this.reconnectTimer = void 0;
106835
107002
  }
107003
+ this.orderBookResolvers.forEach((resolvers, ticker) => {
107004
+ resolvers.forEach((r) => r.reject(new Error(`WebSocket closed for ${ticker}`)));
107005
+ });
107006
+ this.orderBookResolvers.clear();
107007
+ this.tradeResolvers.forEach((resolvers, ticker) => {
107008
+ resolvers.forEach((r) => r.reject(new Error(`WebSocket closed for ${ticker}`)));
107009
+ });
107010
+ this.tradeResolvers.clear();
106836
107011
  if (this.ws) {
106837
- this.ws.close();
107012
+ const ws = this.ws;
106838
107013
  this.ws = void 0;
107014
+ if (ws.readyState !== ws_1.default.CLOSED && ws.readyState !== ws_1.default.CLOSING) {
107015
+ return new Promise((resolve) => {
107016
+ ws.once("close", () => {
107017
+ this.isConnected = false;
107018
+ this.isConnecting = false;
107019
+ resolve();
107020
+ });
107021
+ ws.close();
107022
+ });
107023
+ }
106839
107024
  }
106840
107025
  this.isConnected = false;
106841
107026
  this.isConnecting = false;
@@ -107121,14 +107306,16 @@ var require_kalshi = __commonJS({
107121
107306
  if (!this.ws) {
107122
107307
  this.ws = new websocket_1.KalshiWebSocket(auth, this.wsConfig);
107123
107308
  }
107124
- return this.ws.watchOrderBook(id);
107309
+ const marketTicker = id.replace(/-NO$/, "");
107310
+ return this.ws.watchOrderBook(marketTicker);
107125
107311
  }
107126
107312
  async watchTrades(id, since, limit) {
107127
107313
  const auth = this.ensureAuth();
107128
107314
  if (!this.ws) {
107129
107315
  this.ws = new websocket_1.KalshiWebSocket(auth, this.wsConfig);
107130
107316
  }
107131
- return this.ws.watchTrades(id);
107317
+ const marketTicker = id.replace(/-NO$/, "");
107318
+ return this.ws.watchTrades(marketTicker);
107132
107319
  }
107133
107320
  async close() {
107134
107321
  if (this.ws) {
@@ -107201,12 +107388,15 @@ var require_app = __commonJS({
107201
107388
  }
107202
107389
  });
107203
107390
  app.use((error, req, res, next) => {
107204
- console.error("Error:", error);
107391
+ console.error("API Error:", error);
107392
+ if (error.stack) {
107393
+ console.error(error.stack);
107394
+ }
107205
107395
  res.status(error.status || 500).json({
107206
107396
  success: false,
107207
107397
  error: {
107208
- message: error.message || "Internal server error"
107209
- // stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
107398
+ message: error.message || "Internal server error",
107399
+ stack: process.env.NODE_ENV === "development" ? error.stack : void 0
107210
107400
  }
107211
107401
  });
107212
107402
  });
@@ -107219,7 +107409,9 @@ var require_app = __commonJS({
107219
107409
  privateKey: credentials?.privateKey || process.env.POLYMARKET_PK || process.env.POLYMARKET_PRIVATE_KEY,
107220
107410
  apiKey: credentials?.apiKey || process.env.POLYMARKET_API_KEY,
107221
107411
  apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
107222
- passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE
107412
+ passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE,
107413
+ funderAddress: credentials?.funderAddress,
107414
+ signatureType: credentials?.signatureType
107223
107415
  });
107224
107416
  case "limitless":
107225
107417
  return new limitless_1.LimitlessExchange({
pmxt/client.py CHANGED
@@ -195,6 +195,8 @@ class Exchange(ABC):
195
195
  private_key: Optional[str] = None,
196
196
  base_url: str = "http://localhost:3847",
197
197
  auto_start_server: bool = True,
198
+ proxy_address: Optional[str] = None,
199
+ signature_type: Optional[Any] = None,
198
200
  ):
199
201
  """
200
202
  Initialize an exchange client.
@@ -209,6 +211,8 @@ class Exchange(ABC):
209
211
  self.exchange_name = exchange_name.lower()
210
212
  self.api_key = api_key
211
213
  self.private_key = private_key
214
+ self.proxy_address = proxy_address
215
+ self.signature_type = signature_type
212
216
 
213
217
  # Initialize server manager
214
218
  self._server_manager = ServerManager(base_url)
@@ -264,6 +268,10 @@ class Exchange(ABC):
264
268
  creds["apiKey"] = self.api_key
265
269
  if self.private_key:
266
270
  creds["privateKey"] = self.private_key
271
+ if self.proxy_address:
272
+ creds["funderAddress"] = self.proxy_address
273
+ if self.signature_type is not None:
274
+ creds["signatureType"] = self.signature_type
267
275
  return creds if creds else None
268
276
 
269
277
  # Market Data Methods
@@ -933,6 +941,8 @@ class Polymarket(Exchange):
933
941
  private_key: Optional[str] = None,
934
942
  base_url: str = "http://localhost:3847",
935
943
  auto_start_server: bool = True,
944
+ proxy_address: Optional[str] = None,
945
+ signature_type: Optional[Any] = None,
936
946
  ):
937
947
  """
938
948
  Initialize Polymarket client.
@@ -941,12 +951,16 @@ class Polymarket(Exchange):
941
951
  private_key: Polygon private key (required for trading)
942
952
  base_url: Base URL of the PMXT sidecar server
943
953
  auto_start_server: Automatically start server if not running (default: True)
954
+ proxy_address: Optional Polymarket Proxy/Smart Wallet address
955
+ signature_type: Optional signature type (0=EOA, 1=Proxy)
944
956
  """
945
957
  super().__init__(
946
958
  exchange_name="polymarket",
947
959
  private_key=private_key,
948
960
  base_url=base_url,
949
961
  auto_start_server=auto_start_server,
962
+ proxy_address=proxy_address,
963
+ signature_type=signature_type,
950
964
  )
951
965
 
952
966
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pmxt
3
- Version: 1.5.4
3
+ Version: 1.5.6
4
4
  Summary: Unified prediction market data API - The ccxt for prediction markets
5
5
  Author: PMXT Contributors
6
6
  License: MIT
@@ -1,21 +1,21 @@
1
- pmxt/__init__.py,sha256=514Ya5ykWH3muf7V__O3Mdo8u62XFMuVVccY9udTlRw,1178
2
- pmxt/client.py,sha256=YEArwWnyDbd5Hb_HxMWXIqsihUD0RZDaTrBZh4hOlq4,34026
1
+ pmxt/__init__.py,sha256=L4Ry5foefYktLuO9kXI26RaKxnp9T2ZigKFjLITj00s,1178
2
+ pmxt/client.py,sha256=Qm0gUWCM3sygaRrEVTwCE_YDv9GpA6wrFCFfoFa1PJ0,34711
3
3
  pmxt/models.py,sha256=-jiQ9mmv_qnF6mzj3DrvNgEA77tE_Pl0RCblM1VbV7o,8581
4
4
  pmxt/server_manager.py,sha256=6uS1LIZ2d5d_K-MtbMUAlCZvbvhZ_iyofKok55HEofc,11606
5
5
  pmxt/_server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pmxt/_server/bin/pmxt-ensure-server,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
7
7
  pmxt/_server/bin/pmxt-ensure-server.js,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
8
- pmxt/_server/server/bundled.js,sha256=OGyrocIIrgT1FLzQ1xJo4c4-rmO3IJMhIpU4oJ22sjs,4232813
9
- pmxt_internal/__init__.py,sha256=PrpXrNXiMvHMKpJIPUF_9TIlaLReA_f3SQF-q_evsNk,7578
10
- pmxt_internal/api_client.py,sha256=u3baftkgR0VZRwgGQh4EcIkJeJ3UiTIuJOgm_FQ6aHU,27889
8
+ pmxt/_server/server/bundled.js,sha256=z3C4afJO903hHwA5FemFYu-SghMHShVoxrhjpwJH40U,4241214
9
+ pmxt_internal/__init__.py,sha256=dAcjhk4vURY5ggLZ44vzP0NoMAsmnJwx3DQtOvCQAU4,7756
10
+ pmxt_internal/api_client.py,sha256=mE5sbCyvcXI_MqlisZfK-MP1oIpNGZVVLycs2Yxm3aE,27889
11
11
  pmxt_internal/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
12
- pmxt_internal/configuration.py,sha256=2h6DJrgjaiwNgARfyN4NjKXmsY0c7PUcVfYAiNFwKo8,18320
12
+ pmxt_internal/configuration.py,sha256=TsiCWWLgYZCZx3C33QJ8cnmeCEzTXJ9jiz1gu_L3nlQ,18320
13
13
  pmxt_internal/exceptions.py,sha256=txF8A7vlan57JS69kFPs-IZF-Qhp7IZobBTJVa4fOaM,6644
14
14
  pmxt_internal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  pmxt_internal/rest.py,sha256=FMj4yaV6XLr842u_ScWHSzQsTFdk0jaUeuWLJoRbogQ,9760
16
16
  pmxt_internal/api/__init__.py,sha256=ppJSCipQ5IAk2z6UZkFaGSsEmnoAnSSHb8sjb_DYUkY,101
17
17
  pmxt_internal/api/default_api.py,sha256=6nMYcL__0wtDJAyDAHadN8zk1Sw-qE3nhcpvqUf3ymw,206490
18
- pmxt_internal/models/__init__.py,sha256=nviUepbTwMI-ro_lY6JbUgsQ1MskT7AKN3mb5WKJR74,4141
18
+ pmxt_internal/models/__init__.py,sha256=4gus0xXkoI492owXL9k_8OmtD5dRY4ZBOxlDD0sGPaY,4243
19
19
  pmxt_internal/models/balance.py,sha256=Dj5kFiLrsXOZyyXTC18bPjWrgw7qdWnTgTSCmk_l6xk,2962
20
20
  pmxt_internal/models/base_request.py,sha256=ZNipF7ycXFkQJ6j3QmB1TzA0UO3fB54AMPlAgIA3KOA,2987
21
21
  pmxt_internal/models/base_response.py,sha256=g-NG4Swxl3cg4-YOCPl65dUeHzOnA9S7ubTj8HOYZs0,2975
@@ -25,7 +25,8 @@ pmxt_internal/models/create_order_params.py,sha256=byTxIMNeABia2D7j0UBPnr5qWPxq-
25
25
  pmxt_internal/models/create_order_request.py,sha256=prj6TnIFbhB8eDq-6e-MK2DtfDzAB6P-SoEEEST0cP8,3616
26
26
  pmxt_internal/models/error_detail.py,sha256=590jlnQmIgqcjUQ5ef07_nWMn7fnyjuAvkUjmSoAkMs,2605
27
27
  pmxt_internal/models/error_response.py,sha256=c5DgOpTGqx9Qoz7hYKhRPAM3UfoX4GBWkyhfxerMXEI,2979
28
- pmxt_internal/models/exchange_credentials.py,sha256=BtZCkGnnGQ24KPolTRtoA_jtXp-5_1Y1FmQLe1L5WCo,3308
28
+ pmxt_internal/models/exchange_credentials.py,sha256=hqYhQkDIusvtP1jlWi5oyWo4tFUfXxiqPlD2mdqMvOE,4091
29
+ pmxt_internal/models/exchange_credentials_signature_type.py,sha256=mtan7CkDiu_2cbAy5KdanUdn785nlt2KLFeq3SS250o,5528
29
30
  pmxt_internal/models/execution_price_result.py,sha256=gsYJWD4GXVC9-_YmtLleegxmS4p7Q9bLNaJNEz6Ljsk,3012
30
31
  pmxt_internal/models/fetch_balance200_response.py,sha256=VN5yrsVSKnI_WprK1U4wbl60jGEiSnu4VAOGkSM5K4o,3539
31
32
  pmxt_internal/models/fetch_markets200_response.py,sha256=olOMs8IBKPL2Foqw3r66jeGcRlJpOpGcGq0jNccUPuA,3564
@@ -65,7 +66,7 @@ pmxt_internal/models/unified_market.py,sha256=DoYhiH4HycYGlq858PEeB-CIA7haT6rxmJ
65
66
  pmxt_internal/models/watch_order_book_request.py,sha256=kavGUI-SLz2-Kam_jcJ_h0GDe0-9UkxqCmVsAi6Uios,3726
66
67
  pmxt_internal/models/watch_order_book_request_args_inner.py,sha256=ZHrjmFDGxRG5MXbuz4mUp9KFfo3XS7zuXWTyMNgi4xI,5464
67
68
  pmxt_internal/models/watch_trades_request.py,sha256=brrg8JbEe-aeg7mIe_Y2HzRPogp-IfRhkXChrxzqoLU,3722
68
- pmxt-1.5.4.dist-info/METADATA,sha256=c647vHjvAz-yn2wtXg3xtf6nZCD269MgK3zo7Dfkycg,6449
69
- pmxt-1.5.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
70
- pmxt-1.5.4.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
71
- pmxt-1.5.4.dist-info/RECORD,,
69
+ pmxt-1.5.6.dist-info/METADATA,sha256=o0vWlqzdF517MxC_zMVWPpbvv1-9g1VJ4_qibp-AAm8,6449
70
+ pmxt-1.5.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
71
+ pmxt-1.5.6.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
72
+ pmxt-1.5.6.dist-info/RECORD,,
pmxt_internal/__init__.py CHANGED
@@ -14,7 +14,7 @@
14
14
  """ # noqa: E501
15
15
 
16
16
 
17
- __version__ = "1.5.4"
17
+ __version__ = "1.5.6"
18
18
 
19
19
  # Define package exports
20
20
  __all__ = [
@@ -38,6 +38,7 @@ __all__ = [
38
38
  "ErrorDetail",
39
39
  "ErrorResponse",
40
40
  "ExchangeCredentials",
41
+ "ExchangeCredentialsSignatureType",
41
42
  "ExecutionPriceResult",
42
43
  "FetchBalance200Response",
43
44
  "FetchMarkets200Response",
@@ -104,6 +105,7 @@ from pmxt_internal.models.create_order_request import CreateOrderRequest as Crea
104
105
  from pmxt_internal.models.error_detail import ErrorDetail as ErrorDetail
105
106
  from pmxt_internal.models.error_response import ErrorResponse as ErrorResponse
106
107
  from pmxt_internal.models.exchange_credentials import ExchangeCredentials as ExchangeCredentials
108
+ from pmxt_internal.models.exchange_credentials_signature_type import ExchangeCredentialsSignatureType as ExchangeCredentialsSignatureType
107
109
  from pmxt_internal.models.execution_price_result import ExecutionPriceResult as ExecutionPriceResult
108
110
  from pmxt_internal.models.fetch_balance200_response import FetchBalance200Response as FetchBalance200Response
109
111
  from pmxt_internal.models.fetch_markets200_response import FetchMarkets200Response as FetchMarkets200Response
@@ -91,7 +91,7 @@ class ApiClient:
91
91
  self.default_headers[header_name] = header_value
92
92
  self.cookie = cookie
93
93
  # Set default User-Agent.
94
- self.user_agent = 'OpenAPI-Generator/1.5.4/python'
94
+ self.user_agent = 'OpenAPI-Generator/1.5.6/python'
95
95
  self.client_side_validation = configuration.client_side_validation
96
96
 
97
97
  def __enter__(self):
@@ -506,7 +506,7 @@ class Configuration:
506
506
  "OS: {env}\n"\
507
507
  "Python Version: {pyversion}\n"\
508
508
  "Version of the API: 0.4.4\n"\
509
- "SDK Package Version: 1.5.4".\
509
+ "SDK Package Version: 1.5.6".\
510
510
  format(env=sys.platform, pyversion=sys.version)
511
511
 
512
512
  def get_host_settings(self) -> List[HostSetting]:
@@ -23,6 +23,7 @@ from pmxt_internal.models.create_order_request import CreateOrderRequest
23
23
  from pmxt_internal.models.error_detail import ErrorDetail
24
24
  from pmxt_internal.models.error_response import ErrorResponse
25
25
  from pmxt_internal.models.exchange_credentials import ExchangeCredentials
26
+ from pmxt_internal.models.exchange_credentials_signature_type import ExchangeCredentialsSignatureType
26
27
  from pmxt_internal.models.execution_price_result import ExecutionPriceResult
27
28
  from pmxt_internal.models.fetch_balance200_response import FetchBalance200Response
28
29
  from pmxt_internal.models.fetch_markets200_response import FetchMarkets200Response
@@ -19,6 +19,7 @@ import json
19
19
 
20
20
  from pydantic import BaseModel, ConfigDict, Field, StrictStr
21
21
  from typing import Any, ClassVar, Dict, List, Optional
22
+ from pmxt_internal.models.exchange_credentials_signature_type import ExchangeCredentialsSignatureType
22
23
  from typing import Optional, Set
23
24
  from typing_extensions import Self
24
25
 
@@ -30,7 +31,9 @@ class ExchangeCredentials(BaseModel):
30
31
  private_key: Optional[StrictStr] = Field(default=None, description="Private key for signing transactions", alias="privateKey")
31
32
  api_secret: Optional[StrictStr] = Field(default=None, description="API secret (if required by exchange)", alias="apiSecret")
32
33
  passphrase: Optional[StrictStr] = Field(default=None, description="Passphrase (if required by exchange)")
33
- __properties: ClassVar[List[str]] = ["apiKey", "privateKey", "apiSecret", "passphrase"]
34
+ funder_address: Optional[StrictStr] = Field(default=None, description="The address funding the trades (Proxy address)", alias="funderAddress")
35
+ signature_type: Optional[ExchangeCredentialsSignatureType] = Field(default=None, alias="signatureType")
36
+ __properties: ClassVar[List[str]] = ["apiKey", "privateKey", "apiSecret", "passphrase", "funderAddress", "signatureType"]
34
37
 
35
38
  model_config = ConfigDict(
36
39
  populate_by_name=True,
@@ -71,6 +74,9 @@ class ExchangeCredentials(BaseModel):
71
74
  exclude=excluded_fields,
72
75
  exclude_none=True,
73
76
  )
77
+ # override the default output from pydantic by calling `to_dict()` of signature_type
78
+ if self.signature_type:
79
+ _dict['signatureType'] = self.signature_type.to_dict()
74
80
  return _dict
75
81
 
76
82
  @classmethod
@@ -86,7 +92,9 @@ class ExchangeCredentials(BaseModel):
86
92
  "apiKey": obj.get("apiKey"),
87
93
  "privateKey": obj.get("privateKey"),
88
94
  "apiSecret": obj.get("apiSecret"),
89
- "passphrase": obj.get("passphrase")
95
+ "passphrase": obj.get("passphrase"),
96
+ "funderAddress": obj.get("funderAddress"),
97
+ "signatureType": ExchangeCredentialsSignatureType.from_dict(obj["signatureType"]) if obj.get("signatureType") is not None else None
90
98
  })
91
99
  return _obj
92
100
 
@@ -0,0 +1,143 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ PMXT Sidecar API
5
+
6
+ A unified local sidecar API for prediction markets (Polymarket, Kalshi). This API acts as a JSON-RPC-style gateway. Each endpoint corresponds to a specific method on the generic exchange implementation.
7
+
8
+ The version of the OpenAPI document: 0.4.4
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import json
17
+ import pprint
18
+ from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, ValidationError, field_validator
19
+ from typing import Any, List, Optional
20
+ from pydantic import StrictStr, Field
21
+ from typing import Union, List, Set, Optional, Dict
22
+ from typing_extensions import Literal, Self
23
+
24
+ EXCHANGECREDENTIALSSIGNATURETYPE_ONE_OF_SCHEMAS = ["int", "str"]
25
+
26
+ class ExchangeCredentialsSignatureType(BaseModel):
27
+ """
28
+ Signature type (0=EOA, 1=Poly Proxy, 2=Gnosis Safe, or names like 'gnosis_safe')
29
+ """
30
+ # data type: int
31
+ oneof_schema_1_validator: Optional[StrictInt] = None
32
+ # data type: str
33
+ oneof_schema_2_validator: Optional[StrictStr] = None
34
+ actual_instance: Optional[Union[int, str]] = None
35
+ one_of_schemas: Set[str] = { "int", "str" }
36
+
37
+ model_config = ConfigDict(
38
+ validate_assignment=True,
39
+ protected_namespaces=(),
40
+ )
41
+
42
+
43
+ def __init__(self, *args, **kwargs) -> None:
44
+ if args:
45
+ if len(args) > 1:
46
+ raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
47
+ if kwargs:
48
+ raise ValueError("If a position argument is used, keyword arguments cannot be used.")
49
+ super().__init__(actual_instance=args[0])
50
+ else:
51
+ super().__init__(**kwargs)
52
+
53
+ @field_validator('actual_instance')
54
+ def actual_instance_must_validate_oneof(cls, v):
55
+ instance = ExchangeCredentialsSignatureType.model_construct()
56
+ error_messages = []
57
+ match = 0
58
+ # validate data type: int
59
+ try:
60
+ instance.oneof_schema_1_validator = v
61
+ match += 1
62
+ except (ValidationError, ValueError) as e:
63
+ error_messages.append(str(e))
64
+ # validate data type: str
65
+ try:
66
+ instance.oneof_schema_2_validator = v
67
+ match += 1
68
+ except (ValidationError, ValueError) as e:
69
+ error_messages.append(str(e))
70
+ if match > 1:
71
+ # more than 1 match
72
+ raise ValueError("Multiple matches found when setting `actual_instance` in ExchangeCredentialsSignatureType with oneOf schemas: int, str. Details: " + ", ".join(error_messages))
73
+ elif match == 0:
74
+ # no match
75
+ raise ValueError("No match found when setting `actual_instance` in ExchangeCredentialsSignatureType with oneOf schemas: int, str. Details: " + ", ".join(error_messages))
76
+ else:
77
+ return v
78
+
79
+ @classmethod
80
+ def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self:
81
+ return cls.from_json(json.dumps(obj))
82
+
83
+ @classmethod
84
+ def from_json(cls, json_str: str) -> Self:
85
+ """Returns the object represented by the json string"""
86
+ instance = cls.model_construct()
87
+ error_messages = []
88
+ match = 0
89
+
90
+ # deserialize data into int
91
+ try:
92
+ # validation
93
+ instance.oneof_schema_1_validator = json.loads(json_str)
94
+ # assign value to actual_instance
95
+ instance.actual_instance = instance.oneof_schema_1_validator
96
+ match += 1
97
+ except (ValidationError, ValueError) as e:
98
+ error_messages.append(str(e))
99
+ # deserialize data into str
100
+ try:
101
+ # validation
102
+ instance.oneof_schema_2_validator = json.loads(json_str)
103
+ # assign value to actual_instance
104
+ instance.actual_instance = instance.oneof_schema_2_validator
105
+ match += 1
106
+ except (ValidationError, ValueError) as e:
107
+ error_messages.append(str(e))
108
+
109
+ if match > 1:
110
+ # more than 1 match
111
+ raise ValueError("Multiple matches found when deserializing the JSON string into ExchangeCredentialsSignatureType with oneOf schemas: int, str. Details: " + ", ".join(error_messages))
112
+ elif match == 0:
113
+ # no match
114
+ raise ValueError("No match found when deserializing the JSON string into ExchangeCredentialsSignatureType with oneOf schemas: int, str. Details: " + ", ".join(error_messages))
115
+ else:
116
+ return instance
117
+
118
+ def to_json(self) -> str:
119
+ """Returns the JSON representation of the actual instance"""
120
+ if self.actual_instance is None:
121
+ return "null"
122
+
123
+ if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json):
124
+ return self.actual_instance.to_json()
125
+ else:
126
+ return json.dumps(self.actual_instance)
127
+
128
+ def to_dict(self) -> Optional[Union[Dict[str, Any], int, str]]:
129
+ """Returns the dict representation of the actual instance"""
130
+ if self.actual_instance is None:
131
+ return None
132
+
133
+ if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict):
134
+ return self.actual_instance.to_dict()
135
+ else:
136
+ # primitive type
137
+ return self.actual_instance
138
+
139
+ def to_str(self) -> str:
140
+ """Returns the string representation of the actual instance"""
141
+ return pprint.pformat(self.model_dump())
142
+
143
+
File without changes