@polymarket/clob-client-v2 1.2.0-canary.1 → 1.2.0
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.
- package/README.md +40 -5
- package/dist/client.cjs +70 -40
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +16 -1
- package/dist/client.d.ts +16 -1
- package/dist/client.js +70 -40
- package/dist/client.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/order-builder/helpers/buildMarketOrderCreationArgs.cjs +3 -2
- package/dist/order-builder/helpers/buildMarketOrderCreationArgs.cjs.map +1 -1
- package/dist/order-builder/helpers/buildMarketOrderCreationArgs.js +3 -2
- package/dist/order-builder/helpers/buildMarketOrderCreationArgs.js.map +1 -1
- package/dist/order-builder/helpers/buildOrderCreationArgs.cjs +3 -2
- package/dist/order-builder/helpers/buildOrderCreationArgs.cjs.map +1 -1
- package/dist/order-builder/helpers/buildOrderCreationArgs.js +3 -2
- package/dist/order-builder/helpers/buildOrderCreationArgs.js.map +1 -1
- package/dist/order-builder/helpers/createMarketOrder.cjs +6 -4
- package/dist/order-builder/helpers/createMarketOrder.cjs.map +1 -1
- package/dist/order-builder/helpers/createMarketOrder.js +6 -4
- package/dist/order-builder/helpers/createMarketOrder.js.map +1 -1
- package/dist/order-builder/helpers/createOrder.cjs +6 -4
- package/dist/order-builder/helpers/createOrder.cjs.map +1 -1
- package/dist/order-builder/helpers/createOrder.js +6 -4
- package/dist/order-builder/helpers/createOrder.js.map +1 -1
- package/dist/order-builder/helpers/orderAsset.cjs +18 -0
- package/dist/order-builder/helpers/orderAsset.cjs.map +1 -0
- package/dist/order-builder/helpers/orderAsset.js +16 -0
- package/dist/order-builder/helpers/orderAsset.js.map +1 -0
- package/dist/order-builder/orderBuilder.cjs +2 -2
- package/dist/order-builder/orderBuilder.cjs.map +1 -1
- package/dist/order-builder/orderBuilder.d.cts +2 -2
- package/dist/order-builder/orderBuilder.d.ts +2 -2
- package/dist/order-builder/orderBuilder.js +2 -2
- package/dist/order-builder/orderBuilder.js.map +1 -1
- package/dist/types/clob.cjs.map +1 -1
- package/dist/types/clob.d.cts +0 -1
- package/dist/types/clob.d.ts +0 -1
- package/dist/types/clob.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/ordersV1.cjs.map +1 -1
- package/dist/types/ordersV1.d.cts +2 -0
- package/dist/types/ordersV1.d.ts +2 -0
- package/dist/types/ordersV1.js.map +1 -1
- package/dist/types/ordersV2.cjs.map +1 -1
- package/dist/types/ordersV2.d.cts +17 -13
- package/dist/types/ordersV2.d.ts +17 -13
- package/dist/types/ordersV2.js.map +1 -1
- package/package.json +1 -1
- package/dist/protocol.cjs +0 -22
- package/dist/protocol.cjs.map +0 -1
- package/dist/protocol.js +0 -21
- package/dist/protocol.js.map +0 -1
package/README.md
CHANGED
|
@@ -46,12 +46,23 @@ const resp = await client.createAndPostOrder(
|
|
|
46
46
|
console.log(resp);
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
For a position-backed outcome, provide `positionID` instead. The client uses
|
|
50
|
+
the identifier field to select Exchange V3 signing automatically:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
const resp = await client.createAndPostOrder(
|
|
54
|
+
{
|
|
55
|
+
positionID: "", // position ID of the market outcome
|
|
56
|
+
price: 0.4,
|
|
57
|
+
side: Side.BUY,
|
|
58
|
+
size: 100,
|
|
59
|
+
},
|
|
60
|
+
{ tickSize: "0.01" },
|
|
61
|
+
OrderType.GTC,
|
|
62
|
+
);
|
|
63
|
+
```
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
Legacy CTF token IDs use the server's exchange version. To override automatic
|
|
53
|
-
selection, pass `version: 1`, `version: 2`, or `version: 3` in the order options,
|
|
54
|
-
for example `{ tickSize: "0.01", version: 3 }`.
|
|
65
|
+
See [examples](examples/) for more information.
|
|
55
66
|
|
|
56
67
|
### Market Orders
|
|
57
68
|
|
|
@@ -72,6 +83,30 @@ const resp = await client.createAndPostMarketOrder(
|
|
|
72
83
|
console.log(resp);
|
|
73
84
|
```
|
|
74
85
|
|
|
86
|
+
### Warm up order cache metadata
|
|
87
|
+
|
|
88
|
+
The first order on a new client fetches the order version and the market's tick size,
|
|
89
|
+
neg-risk flag, and fee details before it can be signed. Both are public GET requests and
|
|
90
|
+
need no signer or credentials. To take them off the first trade, run them ahead of time
|
|
91
|
+
on the same client instance that will submit orders:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
await Promise.all([
|
|
95
|
+
client.getVersion(), // adopted as the order version for this client
|
|
96
|
+
client.getClobMarketInfo(conditionID), // caches tick size, neg risk, and fees for both outcomes
|
|
97
|
+
]);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Each call asks the server and refreshes the caches, so repeating it costs one request. If
|
|
101
|
+
the version request fails, `getVersion` adopts the default version 2 and the first order
|
|
102
|
+
corrects it through the mismatch recovery built into order posting. With `throwOnError`
|
|
103
|
+
both calls throw `ApiError` instead, so treat a rejected warm-up as a background failure.
|
|
104
|
+
A new client instance starts with empty caches. Order creation and `getVersion` reuse a
|
|
105
|
+
version or market request that is still in flight instead of starting another one. Orders
|
|
106
|
+
never require these calls. An order placed before `getClobMarketInfo` resolves still
|
|
107
|
+
performs its own token-to-market lookup. Books, balances, allowances, credentials, and
|
|
108
|
+
builder fee rates are not cached by these calls.
|
|
109
|
+
|
|
75
110
|
### Authentication
|
|
76
111
|
|
|
77
112
|
The client has two authentication levels:
|
package/dist/client.cjs
CHANGED
|
@@ -4,6 +4,7 @@ const require_errors = require('./errors.cjs');
|
|
|
4
4
|
const require_index = require('./fees/index.cjs');
|
|
5
5
|
const require_index$1 = require('./headers/index.cjs');
|
|
6
6
|
const require_index$2 = require('./http-helpers/index.cjs');
|
|
7
|
+
const require_orderAsset = require('./order-builder/helpers/orderAsset.cjs');
|
|
7
8
|
const require_signatureTypeV2 = require('./order-utils/model/signatureTypeV2.cjs');
|
|
8
9
|
const require_side = require('./order-utils/model/side.cjs');
|
|
9
10
|
const require_clob = require('./types/clob.cjs');
|
|
@@ -15,7 +16,6 @@ const require_calculateBuyMarketPrice = require('./order-builder/helpers/calcula
|
|
|
15
16
|
const require_calculateSellMarketPrice = require('./order-builder/helpers/calculateSellMarketPrice.cjs');
|
|
16
17
|
const require_roundingConfig = require('./order-builder/helpers/roundingConfig.cjs');
|
|
17
18
|
const require_orderBuilder = require('./order-builder/orderBuilder.cjs');
|
|
18
|
-
const require_protocol = require('./protocol.cjs');
|
|
19
19
|
|
|
20
20
|
//#region src/client.ts
|
|
21
21
|
const RESOLVE_TRADES_TIMEOUT_MS = 3e4;
|
|
@@ -40,6 +40,8 @@ var ClobClient = class {
|
|
|
40
40
|
signatureType;
|
|
41
41
|
funderAddress;
|
|
42
42
|
cachedVersion;
|
|
43
|
+
versionRequest;
|
|
44
|
+
marketInfoRequests = /* @__PURE__ */ new Map();
|
|
43
45
|
retryOnError;
|
|
44
46
|
throwOnError;
|
|
45
47
|
feeSlippage;
|
|
@@ -80,8 +82,26 @@ var ClobClient = class {
|
|
|
80
82
|
data: { heartbeat_id: heartbeatId }
|
|
81
83
|
});
|
|
82
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Fetches the current order version from the server and adopts it for the
|
|
87
|
+
* orders this client signs afterwards. Joins a version request that is
|
|
88
|
+
* already in flight. An error response yields the default version 2, which
|
|
89
|
+
* the first order corrects through the order version mismatch recovery.
|
|
90
|
+
* Throws ApiError when the client was created with throwOnError.
|
|
91
|
+
*/
|
|
83
92
|
async getVersion() {
|
|
84
|
-
return
|
|
93
|
+
return this.versionRequest ?? this.startVersionRequest();
|
|
94
|
+
}
|
|
95
|
+
startVersionRequest() {
|
|
96
|
+
const request = this.get(`${this.host}/version`).then((response) => {
|
|
97
|
+
const version = response?.version ?? 2;
|
|
98
|
+
this.cachedVersion = version;
|
|
99
|
+
return version;
|
|
100
|
+
}).finally(() => {
|
|
101
|
+
if (this.versionRequest === request) this.versionRequest = void 0;
|
|
102
|
+
});
|
|
103
|
+
this.versionRequest = request;
|
|
104
|
+
return request;
|
|
85
105
|
}
|
|
86
106
|
async getServerTime() {
|
|
87
107
|
return this.get(`${this.host}${require_endpoints.TIME}`);
|
|
@@ -101,7 +121,23 @@ var ClobClient = class {
|
|
|
101
121
|
async getMarket(conditionID) {
|
|
102
122
|
return this.get(`${this.host}${require_endpoints.GET_MARKET}${conditionID}`);
|
|
103
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Fetches the market parameters for a condition and caches the tick size,
|
|
126
|
+
* neg-risk flag, and fee details of both outcomes for later orders. Every
|
|
127
|
+
* call refreshes the caches. Concurrent calls for a condition share one request.
|
|
128
|
+
*/
|
|
104
129
|
async getClobMarketInfo(conditionID) {
|
|
130
|
+
const pending = this.marketInfoRequests.get(conditionID);
|
|
131
|
+
if (pending) return pending;
|
|
132
|
+
const request = this.fetchClobMarketInfo(conditionID);
|
|
133
|
+
this.marketInfoRequests.set(conditionID, request);
|
|
134
|
+
try {
|
|
135
|
+
return await request;
|
|
136
|
+
} finally {
|
|
137
|
+
this.marketInfoRequests.delete(conditionID);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async fetchClobMarketInfo(conditionID) {
|
|
105
141
|
const result = await this.get(`${this.host}${require_endpoints.GET_CLOB_MARKET}${conditionID}`);
|
|
106
142
|
if (!result?.t) throw new Error(`failed to fetch market info for condition id ${conditionID}`);
|
|
107
143
|
for (const token of result.t) {
|
|
@@ -430,16 +466,17 @@ var ClobClient = class {
|
|
|
430
466
|
this.canL1Auth();
|
|
431
467
|
const orderToSign = { ...userOrder };
|
|
432
468
|
if (this.builderConfig?.builderCode && !orderToSign.builderCode) orderToSign.builderCode = this.builderConfig.builderCode;
|
|
433
|
-
const
|
|
434
|
-
const
|
|
469
|
+
const routing = require_orderAsset.resolveOrderRouting(orderToSign, options?.version);
|
|
470
|
+
const { assetID } = routing;
|
|
471
|
+
const tickSize = await this._resolveTickSize(assetID, options?.tickSize);
|
|
435
472
|
if (!require_utilities.priceValid(orderToSign.price, tickSize)) throw new Error(`invalid price (${orderToSign.price}), min: ${parseFloat(tickSize)} - max: ${1 - parseFloat(tickSize)}`);
|
|
436
473
|
orderToSign.price = require_utilities.roundNormal(orderToSign.price, require_roundingConfig.ROUNDING_CONFIG[tickSize].price);
|
|
437
|
-
const version = await this.
|
|
438
|
-
if (version !== 1 && orderToSign.side === require_side.Side.BUY && "userUSDCBalance" in orderToSign && orderToSign.userUSDCBalance !== void 0) orderToSign.size = await this.adjustBuyAmountForBalance(
|
|
439
|
-
const negRisk = options?.negRisk ?? await this.getNegRisk(
|
|
474
|
+
const version = routing.exchangeVersion ?? await this.resolveVersion();
|
|
475
|
+
if (version !== 1 && orderToSign.side === require_side.Side.BUY && "userUSDCBalance" in orderToSign && orderToSign.userUSDCBalance !== void 0) orderToSign.size = await this.adjustBuyAmountForBalance(assetID, orderToSign.size * orderToSign.price, orderToSign.price, orderToSign.userUSDCBalance, orderToSign.builderCode) / orderToSign.price;
|
|
476
|
+
const negRisk = version === 3 ? false : options?.negRisk ?? await this.getNegRisk(assetID);
|
|
440
477
|
if (version === 1) {
|
|
441
478
|
const userFeeRateBps = "feeRateBps" in orderToSign ? orderToSign.feeRateBps : void 0;
|
|
442
|
-
orderToSign.feeRateBps = await this._resolveFeeRateBps(
|
|
479
|
+
orderToSign.feeRateBps = await this._resolveFeeRateBps(assetID, userFeeRateBps);
|
|
443
480
|
}
|
|
444
481
|
return this.orderBuilder.buildOrder(orderToSign, {
|
|
445
482
|
tickSize,
|
|
@@ -448,23 +485,24 @@ var ClobClient = class {
|
|
|
448
485
|
}
|
|
449
486
|
async createMarketOrder(userMarketOrder, options) {
|
|
450
487
|
this.canL1Auth();
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
488
|
+
const routing = require_orderAsset.resolveOrderRouting(userMarketOrder, options?.version);
|
|
489
|
+
const { assetID } = routing;
|
|
490
|
+
await this._ensureMarketInfoCached(assetID);
|
|
491
|
+
const tickSize = await this._resolveTickSize(assetID, options?.tickSize);
|
|
492
|
+
if (!userMarketOrder.price) userMarketOrder.price = await this.calculateMarketPrice(assetID, userMarketOrder.side, userMarketOrder.amount, userMarketOrder.orderType);
|
|
455
493
|
if (!require_utilities.priceValid(userMarketOrder.price, tickSize)) throw new Error(`invalid price (${userMarketOrder.price}), min: ${parseFloat(tickSize)} - max: ${1 - parseFloat(tickSize)}`);
|
|
456
494
|
const orderToSign = { ...userMarketOrder };
|
|
457
495
|
if (this.builderConfig?.builderCode && !orderToSign.builderCode) orderToSign.builderCode = this.builderConfig.builderCode;
|
|
458
496
|
await this.ensureBuilderFeeRateCached(orderToSign.builderCode);
|
|
459
497
|
if (orderToSign.side === require_side.Side.BUY && "userUSDCBalance" in orderToSign && orderToSign.userUSDCBalance !== void 0) {
|
|
460
498
|
const price = orderToSign.price;
|
|
461
|
-
orderToSign.amount = await this.adjustBuyAmountForBalance(
|
|
499
|
+
orderToSign.amount = await this.adjustBuyAmountForBalance(assetID, orderToSign.amount, price, orderToSign.userUSDCBalance, orderToSign.builderCode);
|
|
462
500
|
}
|
|
463
|
-
const
|
|
464
|
-
const
|
|
501
|
+
const version = routing.exchangeVersion ?? await this.resolveVersion();
|
|
502
|
+
const negRisk = version === 3 ? false : options?.negRisk ?? await this.getNegRisk(assetID);
|
|
465
503
|
if (version === 1) {
|
|
466
504
|
const userFeeRateBps = "feeRateBps" in orderToSign ? orderToSign.feeRateBps : void 0;
|
|
467
|
-
orderToSign.feeRateBps = await this._resolveFeeRateBps(
|
|
505
|
+
orderToSign.feeRateBps = await this._resolveFeeRateBps(assetID, userFeeRateBps);
|
|
468
506
|
}
|
|
469
507
|
return this.orderBuilder.buildMarketOrder(orderToSign, {
|
|
470
508
|
tickSize,
|
|
@@ -478,20 +516,16 @@ var ClobClient = class {
|
|
|
478
516
|
return this.orderBuilder.buildExchangeV3OrderFromAmounts(orderToSign);
|
|
479
517
|
}
|
|
480
518
|
async createAndPostOrder(userOrder, options, orderType = require_clob.OrderType.GTC, postOnly = false, deferExec = false) {
|
|
481
|
-
|
|
482
|
-
await this._retryOnVersionUpdate(userOrder.tokenID, options?.version, async () => {
|
|
519
|
+
return this._retryOnVersionUpdate(async () => {
|
|
483
520
|
const order = await this.createOrder(userOrder, options);
|
|
484
|
-
|
|
521
|
+
return this.postOrder(order, orderType, postOnly, deferExec);
|
|
485
522
|
});
|
|
486
|
-
return postOrderResponse;
|
|
487
523
|
}
|
|
488
524
|
async createAndPostMarketOrder(userMarketOrder, options, orderType = require_clob.OrderType.FOK, deferExec = false) {
|
|
489
|
-
|
|
490
|
-
await this._retryOnVersionUpdate(userMarketOrder.tokenID, options?.version, async () => {
|
|
525
|
+
return this._retryOnVersionUpdate(async () => {
|
|
491
526
|
const order = await this.createMarketOrder(userMarketOrder, options);
|
|
492
|
-
|
|
527
|
+
return this.postOrder(order, orderType, false, deferExec);
|
|
493
528
|
});
|
|
494
|
-
return postOrderMarketResponse;
|
|
495
529
|
}
|
|
496
530
|
async getOpenOrders(params, only_first_page = false, next_cursor) {
|
|
497
531
|
this.canL2Auth();
|
|
@@ -871,6 +905,7 @@ var ClobClient = class {
|
|
|
871
905
|
if (!result?.condition_id) throw new Error(`failed to resolve condition id for token ${tokenID}`);
|
|
872
906
|
this.tokenConditionMap[tokenID] = result.condition_id;
|
|
873
907
|
}
|
|
908
|
+
if (tokenID in this.feeInfos) return;
|
|
874
909
|
await this.getClobMarketInfo(this.tokenConditionMap[tokenID]);
|
|
875
910
|
}
|
|
876
911
|
async ensureBuilderFeeRateCached(builderCode) {
|
|
@@ -894,25 +929,20 @@ var ClobClient = class {
|
|
|
894
929
|
if (marketFeeRateBps > 0 && userFeeRateBps !== void 0 && userFeeRateBps !== marketFeeRateBps) throw new Error(`invalid user provided fee rate: ${userFeeRateBps}, fee rate for the market must be ${marketFeeRateBps}`);
|
|
895
930
|
return marketFeeRateBps;
|
|
896
931
|
}
|
|
897
|
-
async resolveOrderVersion(tokenID, version) {
|
|
898
|
-
return version ?? (require_protocol.isV2PositionId(tokenID) ? 3 : this.resolveVersion());
|
|
899
|
-
}
|
|
900
932
|
async resolveVersion(forceUpdate = false) {
|
|
901
933
|
if (!forceUpdate && this.cachedVersion !== void 0) return this.cachedVersion;
|
|
902
|
-
|
|
903
|
-
this.
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
for (let attempt = 0; attempt < 2; attempt++) {
|
|
913
|
-
await retryFunc();
|
|
914
|
-
if (version === await this.resolveVersion()) break;
|
|
934
|
+
if (!forceUpdate && this.versionRequest) return this.versionRequest;
|
|
935
|
+
return this.startVersionRequest();
|
|
936
|
+
}
|
|
937
|
+
async _retryOnVersionUpdate(attempt) {
|
|
938
|
+
try {
|
|
939
|
+
const response = await attempt();
|
|
940
|
+
if (!this._isOrderVersionMismatch(response)) return response;
|
|
941
|
+
} catch (err) {
|
|
942
|
+
const data = err instanceof require_errors.ApiError ? err.data : void 0;
|
|
943
|
+
if (!this._isOrderVersionMismatch(data)) throw err;
|
|
915
944
|
}
|
|
945
|
+
return attempt();
|
|
916
946
|
}
|
|
917
947
|
_isOrderVersionMismatch(resp) {
|
|
918
948
|
const error = resp?.error;
|