@pear-protocol/exchanges-sdk 0.21.0 → 0.22.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.
@@ -1,29 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
- function toFundingPaymentEntries(events, instrumentIds, connector) {
6
- return events.reduce((entries, event) => {
7
- const instrumentId = event.market_id.toString();
8
- if (!instrumentIds.has(instrumentId)) {
9
- console.warn(`Lighter market id ${event.market_id} not found in instrument id map.`);
10
- return entries;
11
- }
12
- const unsignedSize = new BigNumber(event.position_size).abs();
13
- const signedSize = event.position_side === "short" ? unsignedSize.negated() : unsignedSize;
14
- const fundingPerUnit = signedSize.isZero() ? "0" : new BigNumber(event.change).div(signedSize).toFixed();
15
- entries.push({
16
- connector,
17
- instrumentId,
18
- fundingRate: event.rate,
19
- notional: event.change,
20
- fundingPerUnit,
21
- // Lighter reports funding timestamps in seconds; the payment contract expects ms.
22
- timestamp: event.timestamp * 1e3
23
- });
24
- return entries;
25
- }, []);
26
- }
27
- __name(toFundingPaymentEntries, "toFundingPaymentEntries");
28
-
29
- export { toFundingPaymentEntries };
@@ -1,157 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { fetchAccount, fetchTradesSince, fetchPositionFundingSince } from '../../client/lighter/rest';
3
- import { retrieveLighterAuthToken } from '../../helper/lighter/auth-token.helper';
4
- import { BaseAccountSyncer } from '../base';
5
- import { toFundingPaymentEntries } from './funding';
6
-
7
- var __defProp = Object.defineProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- const LIGHTER_FEE_TICK_DENOMINATOR = new BigNumber(1e6);
10
- class LighterAccountSyncer extends BaseAccountSyncer {
11
- static {
12
- __name(this, "LighterAccountSyncer");
13
- }
14
- accountIndex;
15
- apiKeyIndex;
16
- apiPrivateKey;
17
- constructor(config) {
18
- super(config);
19
- const credentials = config.credentials;
20
- this.accountIndex = Number(config.account.exchangeIdentifier);
21
- this.apiKeyIndex = credentials.api_key_index;
22
- this.apiPrivateKey = credentials.api_private_key;
23
- }
24
- /** Returns this account's shared Lighter auth token. */
25
- async retrieveAuthToken() {
26
- return retrieveLighterAuthToken(this.sdk, this.connector, {
27
- accountIndex: this.accountIndex,
28
- apiKeyIndex: this.apiKeyIndex,
29
- apiPrivateKey: this.apiPrivateKey
30
- }, this.demo);
31
- }
32
- async listExternalPositions({ instruments }) {
33
- this.assertAuthenticatedSyncAvailable();
34
- const contractSizeByInstrumentId = new Map(instruments.map((instrument) => [
35
- instrument.id,
36
- instrument.precision.quantity.contractSize
37
- ]));
38
- const token = await this.retrieveAuthToken();
39
- const response = await fetchAccount(this.accountIndex, token, this.connector, this.demo, this.throttle);
40
- const rawPositions = response.accounts?.[0]?.positions ?? [];
41
- return rawPositions.reduce((positions, rawPosition) => {
42
- const instrumentId = rawPosition.market_id.toString();
43
- const signedSize = new BigNumber(rawPosition.position).times(rawPosition.sign);
44
- if (signedSize.isZero()) return positions;
45
- const contractSize = contractSizeByInstrumentId.get(instrumentId) ?? 1;
46
- const size = signedSize.abs().times(contractSize).toFixed();
47
- const side = rawPosition.sign === 1 ? "BUY" : "SELL";
48
- const markPrice = new BigNumber(rawPosition.position_value).abs().div(size).toFixed();
49
- positions.push({
50
- symbol: instrumentId,
51
- size,
52
- side,
53
- entryPrice: rawPosition.avg_entry_price,
54
- markPrice
55
- });
56
- return positions;
57
- }, []);
58
- }
59
- async listExternalFills({ since, instruments }) {
60
- this.assertAuthenticatedSyncAvailable();
61
- const token = await this.retrieveAuthToken();
62
- const trades = await fetchTradesSince(this.accountIndex, token, since, this.connector, this.demo, this.throttle);
63
- const instrumentIds = new Set(instruments.map((instrument) => instrument.id));
64
- return trades.toSorted((a, b) => a.timestamp - b.timestamp).reduce((fills, rawFill) => {
65
- const instrumentId = rawFill.market_id.toString();
66
- if (!instrumentIds.has(instrumentId)) {
67
- console.warn(`Lighter market id ${rawFill.market_id} not found in instrument id map.`);
68
- return fills;
69
- }
70
- const accountSide = this.getAccountSide(rawFill);
71
- if (!accountSide) return fills;
72
- const side = accountSide === "ask" ? "SELL" : "BUY";
73
- fills.push({
74
- connector: this.connector,
75
- exchangeFillId: rawFill.trade_id_str ?? rawFill.trade_id.toString(),
76
- cloid: this.getClientOrderId(rawFill, accountSide),
77
- symbol: instrumentId,
78
- price: rawFill.price,
79
- quantity: rawFill.size,
80
- side,
81
- reduceOnly: this.isReduceOnly(rawFill),
82
- timestamp: rawFill.timestamp,
83
- tradeFee: this.getTradeFee(rawFill, accountSide),
84
- builderFee: this.getIntegratorFee(rawFill, accountSide),
85
- liquidation: rawFill.type === "liquidation" && !this.isMaker(rawFill, accountSide) ? {
86
- mark: rawFill.price
87
- } : null
88
- });
89
- return fills;
90
- }, []);
91
- }
92
- async listExternalFunding({ since, instruments }) {
93
- this.assertAuthenticatedSyncAvailable();
94
- const token = await this.retrieveAuthToken();
95
- const fundingEvents = await fetchPositionFundingSince(this.accountIndex, token, since, this.connector, this.demo, this.throttle);
96
- const instrumentIds = new Set(instruments.map((instrument) => instrument.id));
97
- return toFundingPaymentEntries(fundingEvents, instrumentIds, this.connector);
98
- }
99
- isReduceOnly(rawFill) {
100
- const accountSide = this.getAccountSide(rawFill);
101
- if (!accountSide) {
102
- return false;
103
- }
104
- if (rawFill.type === "liquidation" && !this.isMaker(rawFill, accountSide) || rawFill.type === "deleverage" || rawFill.type === "market-settlement") {
105
- return true;
106
- }
107
- const positionSignChanged = this.isMaker(rawFill, accountSide) ? rawFill.maker_position_sign_changed : rawFill.taker_position_sign_changed;
108
- if (positionSignChanged) {
109
- return false;
110
- }
111
- const positionSizeBefore = this.getPositionSizeBefore(rawFill, accountSide);
112
- if (positionSizeBefore.isZero()) {
113
- return false;
114
- }
115
- return positionSizeBefore.isPositive() && accountSide === "ask" || positionSizeBefore.isNegative() && accountSide === "bid";
116
- }
117
- getAccountSide(rawFill) {
118
- if (rawFill.ask_account_id === this.accountIndex) return "ask";
119
- if (rawFill.bid_account_id === this.accountIndex) return "bid";
120
- return null;
121
- }
122
- /** The client order id on our side of the fill, or null when Lighter reports none. */
123
- getClientOrderId(rawFill, side) {
124
- const clientOrderId = side === "ask" ? rawFill.ask_client_id_str : rawFill.bid_client_id_str;
125
- return clientOrderId && clientOrderId !== "0" ? clientOrderId : null;
126
- }
127
- isMaker(rawFill, side) {
128
- return side === "ask" ? rawFill.is_maker_ask : !rawFill.is_maker_ask;
129
- }
130
- getPositionSizeBefore(rawFill, side) {
131
- const value = this.isMaker(rawFill, side) ? rawFill.maker_position_size_before : rawFill.taker_position_size_before;
132
- return new BigNumber(value ?? 0);
133
- }
134
- /** Signed like the rate: positive is a cost, a negative rate a maker rebate (#748). */
135
- getTradeFee(rawFill, side) {
136
- const rateTick = this.isMaker(rawFill, side) ? rawFill.maker_fee : rawFill.taker_fee;
137
- return this.feeTickToAmount(rateTick, rawFill.usd_amount).toFixed();
138
- }
139
- /** The integrator's cut, which the wire carries unsigned. */
140
- getIntegratorFee(rawFill, side) {
141
- const rateTick = this.isMaker(rawFill, side) ? rawFill.integrator_maker_fee : rawFill.integrator_taker_fee;
142
- return this.feeTickToAmount(rateTick, rawFill.usd_amount).abs().toFixed();
143
- }
144
- /** Prevents testnet reads from silently minting a mainnet auth token. */
145
- assertAuthenticatedSyncAvailable() {
146
- if (this.demo) {
147
- throw new Error("Lighter demo authenticated sync is unavailable because backend signing is mainnet-only");
148
- }
149
- }
150
- // Lighter fees come as ppm rates (÷1e6), not amounts — the charged fee is that rate times the trade's USD notional.
151
- feeTickToAmount(rateTick, usdAmount) {
152
- const rate = new BigNumber(rateTick ?? 0).div(LIGHTER_FEE_TICK_DENOMINATOR);
153
- return rate.times(usdAmount);
154
- }
155
- }
156
-
157
- export { LighterAccountSyncer };
@@ -1,75 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { fetchPositions, fetchFillsHistorySince } from '../../client/okx/rest';
3
- import { BaseAccountSyncer } from '../base';
4
- import { toSignedTradeFee } from '../trade-fee';
5
-
6
- var __defProp = Object.defineProperty;
7
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
- class OkxAccountSyncer extends BaseAccountSyncer {
9
- static {
10
- __name(this, "OkxAccountSyncer");
11
- }
12
- creds;
13
- constructor(config) {
14
- super(config);
15
- this.creds = config.credentials;
16
- }
17
- async listExternalPositions({ instruments }) {
18
- const rawPositions = await fetchPositions(this.creds, this.demo);
19
- const contractSizeByInstrumentId = new Map(instruments.map((instrument) => [
20
- instrument.id,
21
- instrument.precision.quantity.contractSize
22
- ]));
23
- return rawPositions.reduce((positions, rawPosition) => {
24
- if (!rawPosition.pos || rawPosition.pos === "0") return positions;
25
- const contractSize = contractSizeByInstrumentId.get(rawPosition.instId) ?? 1;
26
- const signedSize = new BigNumber(rawPosition.pos);
27
- positions.push({
28
- symbol: rawPosition.instId,
29
- size: signedSize.abs().times(contractSize).toFixed(),
30
- side: signedSize.isGreaterThan(0) ? "BUY" : "SELL",
31
- entryPrice: rawPosition.avgPx,
32
- markPrice: rawPosition.avgPx
33
- });
34
- return positions;
35
- }, []);
36
- }
37
- async listExternalFills({ since, instruments }) {
38
- const fills = await fetchFillsHistorySince(this.creds, since, this.demo);
39
- const contractSizeByInstrumentId = new Map(instruments.map((instrument) => [
40
- instrument.id,
41
- instrument.precision.quantity.contractSize
42
- ]));
43
- return fills.reduce((result, rawFill) => {
44
- const contractSize = contractSizeByInstrumentId.get(rawFill.instId) ?? 1;
45
- result.push({
46
- connector: "okx",
47
- exchangeFillId: rawFill.billId || rawFill.tradeId,
48
- cloid: rawFill.clOrdId || null,
49
- symbol: rawFill.instId,
50
- price: rawFill.fillPx,
51
- quantity: this.contractsToBase(rawFill.fillSz, contractSize),
52
- side: rawFill.side === "buy" ? "BUY" : "SELL",
53
- reduceOnly: this.isReduceOnly(rawFill),
54
- timestamp: Number(rawFill.fillTime || rawFill.ts),
55
- tradeFee: toSignedTradeFee("okx", rawFill.fee),
56
- builderFee: "0",
57
- liquidation: null
58
- });
59
- return result;
60
- }, []);
61
- }
62
- async listExternalFunding(_params) {
63
- throw new Error("funding sync is not implemented for okx");
64
- }
65
- isReduceOnly(rawFill) {
66
- if (rawFill.posSide === "long") return rawFill.side === "sell";
67
- if (rawFill.posSide === "short") return rawFill.side === "buy";
68
- return false;
69
- }
70
- contractsToBase(quantity, contractSize) {
71
- return new BigNumber(quantity).times(contractSize).toFixed();
72
- }
73
- }
74
-
75
- export { OkxAccountSyncer };
@@ -1,21 +0,0 @@
1
- import { parse, negate } from '@pear-protocol/utils';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
- function toSignedTradeFee(connector, rawFee) {
6
- const fee = parse(rawFee || "0");
7
- switch (connector) {
8
- // Binance `userTrades.commission`: a charge is positive. The docs do not state a rebate's sign; it is
9
- // taken to be negative, the same convention as ours.
10
- case "binance":
11
- // Bybit `execution/list.execFee`: positive is an expense, negative a rebate (v5 transaction-log docs).
12
- case "bybit":
13
- return fee.toFixed();
14
- // OKX `fills-history.fee`: a deduction is negative, a rebate positive (v5 docs), the opposite of ours.
15
- case "okx":
16
- return negate(fee).toFixed();
17
- }
18
- }
19
- __name(toSignedTradeFee, "toSignedTradeFee");
20
-
21
- export { toSignedTradeFee };