pmxtjs 2.49.10 → 2.49.11

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.
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { InvalidSignature } from "./hosted-errors.js";
12
12
  import { to6dec } from "./hosted-mappers.js";
13
+ import { loadEthers } from "./signers.js";
13
14
  // The constants module is updated in a parallel-agent change to add these
14
15
  // allowlists. We import them at runtime so we don't hard-fail if the change
15
16
  // hasn't landed yet (the imports are typed below).
@@ -343,14 +344,26 @@ function validateWorstPrice(message, route, buildRequest, buildResponse) {
343
344
  }
344
345
  }
345
346
  function validateOpinionMarketId(message, buildResponse) {
346
- const expected = firstPresent(getPath(buildResponse, "resolved", "opinion_market_id"), getPath(buildResponse, "resolved", "opinionMarketId"), getField(buildResponse, "opinion_market_id"), getField(buildResponse, "opinionMarketId"), getPath(buildResponse, "params", "opinion_market_id"), getPath(buildResponse, "params", "opinionMarketId"));
347
- if (expected === MISSING)
347
+ // The current trading-API Opinion message schema does not embed
348
+ // opinion_market_id the signed economic identity is the outcome
349
+ // tokenId. Validate that against the build response's resolved token.
350
+ // The legacy opinion_market_id check only applies when the message
351
+ // actually carries the field (older API versions).
352
+ const expectedToken = firstPresent(getPath(buildResponse, "resolved", "token_id"), getPath(buildResponse, "resolved", "tokenId"), getField(buildResponse, "token_id"), getField(buildResponse, "tokenId"));
353
+ const actualToken = firstPresent(getField(message, "tokenId"), getField(message, "token_id"));
354
+ if (actualToken === MISSING)
355
+ economicFail("message.tokenId missing");
356
+ if (expectedToken !== MISSING && idValue(actualToken) !== idValue(expectedToken)) {
357
+ economicFail(`tokenId expected ${expectedToken} got ${actualToken}`);
358
+ }
359
+ const actualMarketId = firstPresent(getField(message, "opinion_market_id"), getField(message, "opinionMarketId"));
360
+ if (actualMarketId === MISSING)
361
+ return; // current schema: tokenId-only message
362
+ const expectedMarketId = firstPresent(getPath(buildResponse, "resolved", "opinion_market_id"), getPath(buildResponse, "resolved", "opinionMarketId"), getField(buildResponse, "opinion_market_id"), getField(buildResponse, "opinionMarketId"), getPath(buildResponse, "params", "opinion_market_id"), getPath(buildResponse, "params", "opinionMarketId"));
363
+ if (expectedMarketId === MISSING)
348
364
  economicFail("resolved.opinion_market_id missing");
349
- const actual = firstPresent(getField(message, "opinion_market_id"), getField(message, "opinionMarketId"));
350
- if (actual === MISSING)
351
- economicFail("message.opinion_market_id missing");
352
- if (idValue(actual) !== idValue(expected)) {
353
- economicFail(`opinion_market_id expected ${expected} got ${actual}`);
365
+ if (idValue(actualMarketId) !== idValue(expectedMarketId)) {
366
+ economicFail(`opinion_market_id expected ${expectedMarketId} got ${actualMarketId}`);
354
367
  }
355
368
  }
356
369
  // ---------------------------------------------------------------------------
@@ -388,11 +401,10 @@ export function verifySignature(typedData, signature, walletAddress) {
388
401
  }
389
402
  let ethers;
390
403
  try {
391
- // eslint-disable-next-line @typescript-eslint/no-require-imports
392
- ethers = require("ethers");
404
+ ethers = loadEthers("ethers is required for hosted signature verification");
393
405
  }
394
- catch {
395
- throw new InvalidSignature(0, "ethers is required for hosted signature verification");
406
+ catch (err) {
407
+ throw new InvalidSignature(0, err instanceof Error ? err.message : "ethers is required for hosted signature verification");
396
408
  }
397
409
  let recovered;
398
410
  try {
@@ -35,6 +35,13 @@ export interface Signer {
35
35
  readonly address: string;
36
36
  signTypedData(typedData: TypedData): Promise<string>;
37
37
  }
38
+ /**
39
+ * Load ethers lazily in BOTH module systems. The CJS build has native
40
+ * `require`; the ESM build does not — bare `require("ethers")` there threw
41
+ * ReferenceError, which callers swallowed, silently dropping the signer and
42
+ * killing every hosted write with "hosted write requires a signer".
43
+ */
44
+ export declare function loadEthers(installHint?: string): any;
38
45
  /**
39
46
  * Built-in signer backed by an ethers `Wallet`.
40
47
  *
@@ -8,6 +8,35 @@
8
8
  * Mirrors `sdks/python/pmxt/signers.py`.
9
9
  */
10
10
  const ETHERS_INSTALL_HINT = "hosted trading requires the optional 'ethers' peer dependency. Install with: npm install ethers";
11
+ /**
12
+ * Load ethers lazily in BOTH module systems. The CJS build has native
13
+ * `require`; the ESM build does not — bare `require("ethers")` there threw
14
+ * ReferenceError, which callers swallowed, silently dropping the signer and
15
+ * killing every hosted write with "hosted write requires a signer".
16
+ */
17
+ export function loadEthers(installHint = ETHERS_INSTALL_HINT) {
18
+ if (typeof require === "function") {
19
+ try {
20
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
21
+ return require("ethers");
22
+ }
23
+ catch {
24
+ throw new Error(installHint);
25
+ }
26
+ }
27
+ // ESM: synthesize a require. getBuiltinModule is sync-safe in both
28
+ // module systems (Node >= 20.16).
29
+ const nodeModule = globalThis.process?.getBuiltinModule?.("node:module");
30
+ const req = nodeModule?.createRequire?.(`${process.cwd()}/__pmxt_resolver__.js`);
31
+ if (!req)
32
+ throw new Error(installHint);
33
+ try {
34
+ return req("ethers");
35
+ }
36
+ catch {
37
+ throw new Error(installHint);
38
+ }
39
+ }
11
40
  /**
12
41
  * Built-in signer backed by an ethers `Wallet`.
13
42
  *
@@ -18,14 +47,7 @@ export class EthersSigner {
18
47
  _wallet; // ethers.Wallet
19
48
  address;
20
49
  constructor(privateKey) {
21
- let ethers;
22
- try {
23
- // eslint-disable-next-line @typescript-eslint/no-require-imports
24
- ethers = require("ethers");
25
- }
26
- catch {
27
- throw new Error(ETHERS_INSTALL_HINT);
28
- }
50
+ const ethers = loadEthers();
29
51
  this._wallet = new ethers.Wallet(privateKey);
30
52
  this.address = this._wallet.address;
31
53
  }
@@ -49,6 +49,7 @@ exports.validateEconomics = validateEconomics;
49
49
  exports.verifySignature = verifySignature;
50
50
  const hosted_errors_1 = require("./hosted-errors");
51
51
  const hosted_mappers_1 = require("./hosted-mappers");
52
+ const signers_1 = require("./signers");
52
53
  // The constants module is updated in a parallel-agent change to add these
53
54
  // allowlists. We import them at runtime so we don't hard-fail if the change
54
55
  // hasn't landed yet (the imports are typed below).
@@ -382,14 +383,26 @@ function validateWorstPrice(message, route, buildRequest, buildResponse) {
382
383
  }
383
384
  }
384
385
  function validateOpinionMarketId(message, buildResponse) {
385
- const expected = firstPresent(getPath(buildResponse, "resolved", "opinion_market_id"), getPath(buildResponse, "resolved", "opinionMarketId"), getField(buildResponse, "opinion_market_id"), getField(buildResponse, "opinionMarketId"), getPath(buildResponse, "params", "opinion_market_id"), getPath(buildResponse, "params", "opinionMarketId"));
386
- if (expected === MISSING)
386
+ // The current trading-API Opinion message schema does not embed
387
+ // opinion_market_id the signed economic identity is the outcome
388
+ // tokenId. Validate that against the build response's resolved token.
389
+ // The legacy opinion_market_id check only applies when the message
390
+ // actually carries the field (older API versions).
391
+ const expectedToken = firstPresent(getPath(buildResponse, "resolved", "token_id"), getPath(buildResponse, "resolved", "tokenId"), getField(buildResponse, "token_id"), getField(buildResponse, "tokenId"));
392
+ const actualToken = firstPresent(getField(message, "tokenId"), getField(message, "token_id"));
393
+ if (actualToken === MISSING)
394
+ economicFail("message.tokenId missing");
395
+ if (expectedToken !== MISSING && idValue(actualToken) !== idValue(expectedToken)) {
396
+ economicFail(`tokenId expected ${expectedToken} got ${actualToken}`);
397
+ }
398
+ const actualMarketId = firstPresent(getField(message, "opinion_market_id"), getField(message, "opinionMarketId"));
399
+ if (actualMarketId === MISSING)
400
+ return; // current schema: tokenId-only message
401
+ const expectedMarketId = firstPresent(getPath(buildResponse, "resolved", "opinion_market_id"), getPath(buildResponse, "resolved", "opinionMarketId"), getField(buildResponse, "opinion_market_id"), getField(buildResponse, "opinionMarketId"), getPath(buildResponse, "params", "opinion_market_id"), getPath(buildResponse, "params", "opinionMarketId"));
402
+ if (expectedMarketId === MISSING)
387
403
  economicFail("resolved.opinion_market_id missing");
388
- const actual = firstPresent(getField(message, "opinion_market_id"), getField(message, "opinionMarketId"));
389
- if (actual === MISSING)
390
- economicFail("message.opinion_market_id missing");
391
- if (idValue(actual) !== idValue(expected)) {
392
- economicFail(`opinion_market_id expected ${expected} got ${actual}`);
404
+ if (idValue(actualMarketId) !== idValue(expectedMarketId)) {
405
+ economicFail(`opinion_market_id expected ${expectedMarketId} got ${actualMarketId}`);
393
406
  }
394
407
  }
395
408
  // ---------------------------------------------------------------------------
@@ -427,11 +440,10 @@ function verifySignature(typedData, signature, walletAddress) {
427
440
  }
428
441
  let ethers;
429
442
  try {
430
- // eslint-disable-next-line @typescript-eslint/no-require-imports
431
- ethers = require("ethers");
443
+ ethers = (0, signers_1.loadEthers)("ethers is required for hosted signature verification");
432
444
  }
433
- catch {
434
- throw new hosted_errors_1.InvalidSignature(0, "ethers is required for hosted signature verification");
445
+ catch (err) {
446
+ throw new hosted_errors_1.InvalidSignature(0, err instanceof Error ? err.message : "ethers is required for hosted signature verification");
435
447
  }
436
448
  let recovered;
437
449
  try {
@@ -35,6 +35,13 @@ export interface Signer {
35
35
  readonly address: string;
36
36
  signTypedData(typedData: TypedData): Promise<string>;
37
37
  }
38
+ /**
39
+ * Load ethers lazily in BOTH module systems. The CJS build has native
40
+ * `require`; the ESM build does not — bare `require("ethers")` there threw
41
+ * ReferenceError, which callers swallowed, silently dropping the signer and
42
+ * killing every hosted write with "hosted write requires a signer".
43
+ */
44
+ export declare function loadEthers(installHint?: string): any;
38
45
  /**
39
46
  * Built-in signer backed by an ethers `Wallet`.
40
47
  *
@@ -10,8 +10,38 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EthersSigner = void 0;
13
+ exports.loadEthers = loadEthers;
13
14
  exports.signerFromPrivateKey = signerFromPrivateKey;
14
15
  const ETHERS_INSTALL_HINT = "hosted trading requires the optional 'ethers' peer dependency. Install with: npm install ethers";
16
+ /**
17
+ * Load ethers lazily in BOTH module systems. The CJS build has native
18
+ * `require`; the ESM build does not — bare `require("ethers")` there threw
19
+ * ReferenceError, which callers swallowed, silently dropping the signer and
20
+ * killing every hosted write with "hosted write requires a signer".
21
+ */
22
+ function loadEthers(installHint = ETHERS_INSTALL_HINT) {
23
+ if (typeof require === "function") {
24
+ try {
25
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
26
+ return require("ethers");
27
+ }
28
+ catch {
29
+ throw new Error(installHint);
30
+ }
31
+ }
32
+ // ESM: synthesize a require. getBuiltinModule is sync-safe in both
33
+ // module systems (Node >= 20.16).
34
+ const nodeModule = globalThis.process?.getBuiltinModule?.("node:module");
35
+ const req = nodeModule?.createRequire?.(`${process.cwd()}/__pmxt_resolver__.js`);
36
+ if (!req)
37
+ throw new Error(installHint);
38
+ try {
39
+ return req("ethers");
40
+ }
41
+ catch {
42
+ throw new Error(installHint);
43
+ }
44
+ }
15
45
  /**
16
46
  * Built-in signer backed by an ethers `Wallet`.
17
47
  *
@@ -22,14 +52,7 @@ class EthersSigner {
22
52
  _wallet; // ethers.Wallet
23
53
  address;
24
54
  constructor(privateKey) {
25
- let ethers;
26
- try {
27
- // eslint-disable-next-line @typescript-eslint/no-require-imports
28
- ethers = require("ethers");
29
- }
30
- catch {
31
- throw new Error(ETHERS_INSTALL_HINT);
32
- }
55
+ const ethers = loadEthers();
33
56
  this._wallet = new ethers.Wallet(privateKey);
34
57
  this.address = this._wallet.address;
35
58
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.49.10",
3
+ "version": "2.49.11",
4
4
  "description": "OpenAPI client for pmxtjs",
5
5
  "author": "OpenAPI-Generator",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.49.10",
3
+ "version": "2.49.11",
4
4
  "description": "Unified prediction market data API - The ccxt for prediction markets",
5
5
  "author": "PMXT Contributors",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  "unified"
44
44
  ],
45
45
  "dependencies": {
46
- "pmxt-core": "2.49.10",
46
+ "pmxt-core": "2.49.11",
47
47
  "ws": "^8.18.0"
48
48
  },
49
49
  "peerDependencies": {
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { InvalidSignature } from "./hosted-errors";
13
13
  import { to6dec } from "./hosted-mappers";
14
- import { TypedData } from "./signers";
14
+ import { TypedData, loadEthers } from "./signers";
15
15
 
16
16
  // The constants module is updated in a parallel-agent change to add these
17
17
  // allowlists. We import them at runtime so we don't hard-fail if the change
@@ -508,7 +508,33 @@ function validateOpinionMarketId(
508
508
  message: Record<string, unknown>,
509
509
  buildResponse: any,
510
510
  ): void {
511
- const expected = firstPresent(
511
+ // The current trading-API Opinion message schema does not embed
512
+ // opinion_market_id — the signed economic identity is the outcome
513
+ // tokenId. Validate that against the build response's resolved token.
514
+ // The legacy opinion_market_id check only applies when the message
515
+ // actually carries the field (older API versions).
516
+ const expectedToken = firstPresent(
517
+ getPath(buildResponse, "resolved", "token_id"),
518
+ getPath(buildResponse, "resolved", "tokenId"),
519
+ getField(buildResponse, "token_id"),
520
+ getField(buildResponse, "tokenId"),
521
+ );
522
+ const actualToken = firstPresent(
523
+ getField(message, "tokenId"),
524
+ getField(message, "token_id"),
525
+ );
526
+ if (actualToken === MISSING) economicFail("message.tokenId missing");
527
+ if (expectedToken !== MISSING && idValue(actualToken) !== idValue(expectedToken)) {
528
+ economicFail(`tokenId expected ${expectedToken} got ${actualToken}`);
529
+ }
530
+
531
+ const actualMarketId = firstPresent(
532
+ getField(message, "opinion_market_id"),
533
+ getField(message, "opinionMarketId"),
534
+ );
535
+ if (actualMarketId === MISSING) return; // current schema: tokenId-only message
536
+
537
+ const expectedMarketId = firstPresent(
512
538
  getPath(buildResponse, "resolved", "opinion_market_id"),
513
539
  getPath(buildResponse, "resolved", "opinionMarketId"),
514
540
  getField(buildResponse, "opinion_market_id"),
@@ -516,16 +542,9 @@ function validateOpinionMarketId(
516
542
  getPath(buildResponse, "params", "opinion_market_id"),
517
543
  getPath(buildResponse, "params", "opinionMarketId"),
518
544
  );
519
- if (expected === MISSING) economicFail("resolved.opinion_market_id missing");
520
-
521
- const actual = firstPresent(
522
- getField(message, "opinion_market_id"),
523
- getField(message, "opinionMarketId"),
524
- );
525
- if (actual === MISSING) economicFail("message.opinion_market_id missing");
526
-
527
- if (idValue(actual) !== idValue(expected)) {
528
- economicFail(`opinion_market_id expected ${expected} got ${actual}`);
545
+ if (expectedMarketId === MISSING) economicFail("resolved.opinion_market_id missing");
546
+ if (idValue(actualMarketId) !== idValue(expectedMarketId)) {
547
+ economicFail(`opinion_market_id expected ${expectedMarketId} got ${actualMarketId}`);
529
548
  }
530
549
  }
531
550
 
@@ -575,12 +594,11 @@ export function verifySignature(
575
594
 
576
595
  let ethers: any;
577
596
  try {
578
- // eslint-disable-next-line @typescript-eslint/no-require-imports
579
- ethers = require("ethers");
580
- } catch {
597
+ ethers = loadEthers("ethers is required for hosted signature verification");
598
+ } catch (err) {
581
599
  throw new InvalidSignature(
582
600
  0,
583
- "ethers is required for hosted signature verification",
601
+ err instanceof Error ? err.message : "ethers is required for hosted signature verification",
584
602
  );
585
603
  }
586
604
 
package/pmxt/signers.ts CHANGED
@@ -38,6 +38,33 @@ export interface Signer {
38
38
  const ETHERS_INSTALL_HINT =
39
39
  "hosted trading requires the optional 'ethers' peer dependency. Install with: npm install ethers";
40
40
 
41
+ /**
42
+ * Load ethers lazily in BOTH module systems. The CJS build has native
43
+ * `require`; the ESM build does not — bare `require("ethers")` there threw
44
+ * ReferenceError, which callers swallowed, silently dropping the signer and
45
+ * killing every hosted write with "hosted write requires a signer".
46
+ */
47
+ export function loadEthers(installHint: string = ETHERS_INSTALL_HINT): any {
48
+ if (typeof require === "function") {
49
+ try {
50
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
51
+ return require("ethers");
52
+ } catch {
53
+ throw new Error(installHint);
54
+ }
55
+ }
56
+ // ESM: synthesize a require. getBuiltinModule is sync-safe in both
57
+ // module systems (Node >= 20.16).
58
+ const nodeModule = (globalThis as any).process?.getBuiltinModule?.("node:module");
59
+ const req = nodeModule?.createRequire?.(`${process.cwd()}/__pmxt_resolver__.js`);
60
+ if (!req) throw new Error(installHint);
61
+ try {
62
+ return req("ethers");
63
+ } catch {
64
+ throw new Error(installHint);
65
+ }
66
+ }
67
+
41
68
  /**
42
69
  * Built-in signer backed by an ethers `Wallet`.
43
70
  *
@@ -49,13 +76,7 @@ export class EthersSigner implements Signer {
49
76
  readonly address: string;
50
77
 
51
78
  constructor(privateKey: string) {
52
- let ethers: any;
53
- try {
54
- // eslint-disable-next-line @typescript-eslint/no-require-imports
55
- ethers = require("ethers");
56
- } catch {
57
- throw new Error(ETHERS_INSTALL_HINT);
58
- }
79
+ const ethers = loadEthers();
59
80
  this._wallet = new ethers.Wallet(privateKey);
60
81
  this.address = this._wallet.address;
61
82
  }