@dydxprotocol/v4-client-js 1.18.0 → 1.19.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,252 +1,239 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable no-param-reassign */
1
3
  import { Network } from '../src/clients/constants';
2
4
  import { SocketClient } from '../src/clients/socket-client';
3
5
 
4
6
  function test(): void {
5
- let orderBookBidList: [number, number, number][] = [];
6
- let orderBookAskList: [number, number, number][] = [];
7
-
8
- const mySocket = new SocketClient(
9
- Network.mainnet().indexerConfig,
10
- () => {
11
- console.log('socket opened');
12
-
13
- mySocket.subscribeToOrderbook('ETH-USD');
14
- },
15
- () => {
16
- console.log('socket closed');
17
- },
18
- (message) => {
19
- try {
20
- if (typeof message.data === "string") {
21
- const jsonString = message.data;
22
- const parsingData = JSON.parse(jsonString);
23
- const messageId = parsingData.message_id;
24
- const orderBookDataList = parsingData.contents;
25
-
26
- if (orderBookDataList instanceof Array) {
27
- // common orderBook data;
28
- [orderBookBidList, orderBookAskList] = updateOrderBook(
29
- orderBookDataList,
30
- orderBookBidList,
31
- orderBookAskList,
32
- messageId,
33
- );
34
-
35
- // sort
36
- orderBookBidList = sortByNthElementDesc(
37
- orderBookBidList,
38
- 0,
39
- );
40
- orderBookAskList = sortByNthElementAsc(
41
- orderBookAskList,
42
- 0,
43
- );
44
-
45
- // resolving crossed orderBook
46
- if (
47
- orderBookBidList &&
48
- orderBookAskList &&
49
- orderBookBidList.length > 0 &&
50
- orderBookAskList.length > 0 &&
51
- orderBookBidList[0][0] >= orderBookAskList[0][0]
52
- ) {
53
- [orderBookBidList, orderBookAskList] =
54
- resolveCrossedOrderBook(
55
- orderBookBidList,
56
- orderBookAskList,
57
- );
58
- }
59
-
60
- printOrderBook(orderBookBidList, orderBookAskList);
61
-
62
- if (orderBookBidList.length > 300) {
63
- orderBookBidList.splice(50);
64
- }
65
-
66
- if (orderBookAskList.length > 300) {
67
- orderBookAskList.splice(50);
68
- }
69
- } else if (
70
- orderBookDataList !== null &&
71
- orderBookDataList !== undefined
72
- ) {
73
- // initial OrderBook data
74
- setInitialOrderBook(
75
- orderBookDataList,
76
- orderBookBidList,
77
- orderBookAskList,
78
- messageId,
79
- );
80
- }
81
- }
82
- } catch (e) {
83
- console.error('Error parsing JSON message:', e);
7
+ let orderBookBidList: [number, number, number][] = [];
8
+ let orderBookAskList: [number, number, number][] = [];
9
+
10
+ const mySocket = new SocketClient(
11
+ Network.mainnet().indexerConfig,
12
+ () => {
13
+ console.log('socket opened');
14
+
15
+ mySocket.subscribeToOrderbook('ETH-USD');
16
+ },
17
+ () => {
18
+ console.log('socket closed');
19
+ },
20
+ (message) => {
21
+ try {
22
+ if (typeof message.data === 'string') {
23
+ const jsonString = message.data;
24
+ const parsingData = JSON.parse(jsonString);
25
+ const messageId = parsingData.message_id;
26
+ const orderBookDataList = parsingData.contents;
27
+
28
+ if (orderBookDataList instanceof Array) {
29
+ // common orderBook data;
30
+ [orderBookBidList, orderBookAskList] = updateOrderBook(
31
+ orderBookDataList,
32
+ orderBookBidList,
33
+ orderBookAskList,
34
+ messageId,
35
+ );
36
+
37
+ // sort
38
+ orderBookBidList = sortByNthElementDesc(orderBookBidList, 0);
39
+ orderBookAskList = sortByNthElementAsc(orderBookAskList, 0);
40
+
41
+ // resolving crossed orderBook
42
+ if (
43
+ orderBookBidList.length > 0 &&
44
+ orderBookAskList.length > 0 &&
45
+ orderBookBidList[0][0] >= orderBookAskList[0][0]
46
+ ) {
47
+ [orderBookBidList, orderBookAskList] = resolveCrossedOrderBook(
48
+ orderBookBidList,
49
+ orderBookAskList,
50
+ );
84
51
  }
85
- },
86
- (event) => {
87
- console.error('Encountered error:', event.message);
88
- },
89
- );
90
52
 
91
- mySocket.connect();
53
+ printOrderBook(orderBookBidList, orderBookAskList);
54
+
55
+ if (orderBookBidList.length > 300) {
56
+ orderBookBidList.splice(50);
57
+ }
58
+
59
+ if (orderBookAskList.length > 300) {
60
+ orderBookAskList.splice(50);
61
+ }
62
+ } else if (orderBookDataList !== null && orderBookDataList !== undefined) {
63
+ // initial OrderBook data
64
+ setInitialOrderBook(orderBookDataList, orderBookBidList, orderBookAskList, messageId);
65
+ }
66
+ }
67
+ } catch (e) {
68
+ console.error('Error parsing JSON message:', e);
69
+ }
70
+ },
71
+ (event) => {
72
+ console.error('Encountered error:', event.message);
73
+ },
74
+ );
75
+
76
+ mySocket.connect();
92
77
  }
93
78
 
94
- const sortByNthElementAsc = (arr: [number, number, number][], n: number): [number, number, number][] => {
95
- return arr.sort((a, b) => {
96
- if (a[n] < b[n]) return -1;
97
- if (a[n] > b[n]) return 1;
98
- return 0;
99
- });
79
+ const sortByNthElementAsc = (
80
+ arr: [number, number, number][],
81
+ n: number,
82
+ ): [number, number, number][] => {
83
+ return arr.sort((a, b) => {
84
+ if (a[n] < b[n]) return -1;
85
+ if (a[n] > b[n]) return 1;
86
+ return 0;
87
+ });
100
88
  };
101
- const sortByNthElementDesc = (arr: [number, number, number][], n: number): [number, number, number][] => {
102
- return arr.sort((a, b) => {
103
- if (a[n] > b[n]) return -1;
104
- if (a[n] < b[n]) return 1;
105
- return 0;
106
- });
89
+ const sortByNthElementDesc = (
90
+ arr: [number, number, number][],
91
+ n: number,
92
+ ): [number, number, number][] => {
93
+ return arr.sort((a, b) => {
94
+ if (a[n] > b[n]) return -1;
95
+ if (a[n] < b[n]) return 1;
96
+ return 0;
97
+ });
107
98
  };
108
99
 
109
100
  const printOrderBook = (
110
- orderBookBidList: [number, number, number][],
111
- orderBookAskList: [number, number, number][],
101
+ orderBookBidList: [number, number, number][],
102
+ orderBookAskList: [number, number, number][],
112
103
  ): void => {
113
- // print
114
- console.log(`OrderBook for ETH-USD:`);
115
- console.log(`Price Qty`);
116
- for (let i = 4; i > -1; i--) {
117
- const priceStr = String(orderBookAskList[i][0]);
118
- const spaces = createSpaces(10 - priceStr.length);
119
- console.log(`${priceStr}${spaces}${orderBookAskList[i][1]}`);
120
- }
121
- console.log('---------------------');
122
- for (let i = 0; i < 5; i++) {
123
- const priceStr = String(orderBookBidList[i][0]);
124
- const spaces = createSpaces(10 - priceStr.length);
125
- console.log(`${priceStr}${spaces}${orderBookBidList[i][1]}`);
126
- }
127
- console.log('');
104
+ // print
105
+ console.log(`OrderBook for ETH-USD:`);
106
+ console.log(`Price Qty`);
107
+ for (let i = 4; i > -1; i--) {
108
+ const priceStr = String(orderBookAskList[i][0]);
109
+ const spaces = createSpaces(10 - priceStr.length);
110
+ console.log(`${priceStr}${spaces}${orderBookAskList[i][1]}`);
111
+ }
112
+ console.log('---------------------');
113
+ for (let i = 0; i < 5; i++) {
114
+ const priceStr = String(orderBookBidList[i][0]);
115
+ const spaces = createSpaces(10 - priceStr.length);
116
+ console.log(`${priceStr}${spaces}${orderBookBidList[i][1]}`);
117
+ }
118
+ console.log('');
128
119
  };
129
120
 
130
121
  function createSpaces(count: number): string {
131
- if(count <= 0 ){
132
- return "";
133
- }
134
-
135
- let spaces = "";
136
- for (let i = 0; i < count; i++) {
137
- spaces += " ";
138
- }
139
- return spaces;
122
+ if (count <= 0) {
123
+ return '';
124
+ }
125
+
126
+ let spaces = '';
127
+ for (let i = 0; i < count; i++) {
128
+ spaces += ' ';
129
+ }
130
+ return spaces;
140
131
  }
141
132
 
142
133
  const resolveCrossedOrderBook = (
143
- orderBookBidList: [number, number, number][],
144
- orderBookAskList: [number, number, number][],
134
+ orderBookBidList: [number, number, number][],
135
+ orderBookAskList: [number, number, number][],
145
136
  ): [[number, number, number][], [number, number, number][]] => {
146
- while (orderBookBidList[0][0] >= orderBookAskList[0][0]) {
147
- if (orderBookBidList[0][2] < orderBookAskList[0][2]) {
148
- orderBookBidList.shift();
149
- } else if (orderBookBidList[0][2] > orderBookAskList[0][2]) {
150
- orderBookAskList.shift();
151
- } else {
152
- if (orderBookBidList[0][1] > orderBookAskList[0][1]) {
153
- orderBookBidList[0][1] -= orderBookAskList[0][1];
154
- orderBookAskList.shift();
155
- } else if (orderBookBidList[0][1] < orderBookAskList[0][1]) {
156
- orderBookAskList[0][1] -= orderBookBidList[0][1];
157
- orderBookBidList.shift();
158
- } else {
159
- orderBookAskList.shift();
160
- orderBookBidList.shift();
161
- }
162
- }
137
+ while (orderBookBidList[0][0] >= orderBookAskList[0][0]) {
138
+ if (orderBookBidList[0][2] < orderBookAskList[0][2]) {
139
+ orderBookBidList.shift();
140
+ } else if (orderBookBidList[0][2] > orderBookAskList[0][2]) {
141
+ orderBookAskList.shift();
142
+ } else {
143
+ if (orderBookBidList[0][1] > orderBookAskList[0][1]) {
144
+ orderBookBidList[0][1] -= orderBookAskList[0][1];
145
+ orderBookAskList.shift();
146
+ } else if (orderBookBidList[0][1] < orderBookAskList[0][1]) {
147
+ orderBookAskList[0][1] -= orderBookBidList[0][1];
148
+ orderBookBidList.shift();
149
+ } else {
150
+ orderBookAskList.shift();
151
+ orderBookBidList.shift();
152
+ }
163
153
  }
154
+ }
164
155
 
165
- return [orderBookBidList, orderBookAskList];
156
+ return [orderBookBidList, orderBookAskList];
166
157
  };
167
158
  const setInitialOrderBook = (
168
- orderBookDataList: { bids: []; asks: [] },
169
- orderBookBidList: [number, number, number][],
170
- orderBookAskList: [number, number, number][],
171
- messageId: number,
159
+ orderBookDataList: { bids: []; asks: [] },
160
+ orderBookBidList: [number, number, number][],
161
+ orderBookAskList: [number, number, number][],
162
+ messageId: number,
172
163
  ): void => {
173
- orderBookDataList.bids.forEach((item: { price: string; size: string }) => {
174
- orderBookBidList.push([Number(item.price), Number(item.size), messageId]);
175
- });
164
+ orderBookDataList.bids.forEach((item: { price: string; size: string }) => {
165
+ orderBookBidList.push([Number(item.price), Number(item.size), messageId]);
166
+ });
176
167
 
177
- orderBookDataList.asks.forEach((item: { price: string; size: string }) => {
178
- orderBookAskList.push([Number(item.price), Number(item.size), messageId]);
179
- });
168
+ orderBookDataList.asks.forEach((item: { price: string; size: string }) => {
169
+ orderBookAskList.push([Number(item.price), Number(item.size), messageId]);
170
+ });
180
171
  };
181
172
 
182
173
  const updateOrderBook = (
183
- orderBookDataList: { bids: [[]]; asks: [[]] }[],
184
- orderBookBidList: [number, number, number][],
185
- orderBookAskList: [number, number, number][],
186
- messageId: number,
174
+ orderBookDataList: { bids: [[]]; asks: [[]] }[],
175
+ orderBookBidList: [number, number, number][],
176
+ orderBookAskList: [number, number, number][],
177
+ messageId: number,
187
178
  ): [[number, number, number][], [number, number, number][]] => {
188
- orderBookDataList.forEach((entry: { bids: [[]]; asks: [[]] }) => {
189
- if (entry.bids !== null && entry.bids !== undefined) {
190
- const flattened = entry.bids.reduce((acc: any[], val: any[]) => acc.concat(val), []);
191
- const entryBidPrice = Number(flattened[0]);
192
- const entryBidSize = Number(flattened[1]);
193
-
194
- // remove prices with zero Qty
195
- if (entryBidSize === 0) {
196
- for (let i = orderBookBidList.length - 1; i >= 0; i--) {
197
- if (orderBookBidList[i][0] === entryBidPrice) {
198
- orderBookBidList.splice(i, 1);
199
- }
200
- }
201
- } else {
202
- // The price that already exists in the order book is modified only Qty
203
- if (
204
- orderBookBidList.some((innerArray) => innerArray[0] === entryBidPrice)
205
- ) {
206
- orderBookBidList.forEach((item, index) => {
207
- if (item[0] === entryBidPrice) {
208
- orderBookBidList[index][1] = entryBidSize;
209
- orderBookBidList[index][2] = messageId;
210
- }
211
- });
212
- } else {
213
- // Add new data to order book
214
- orderBookBidList.push([entryBidPrice, entryBidSize, messageId]);
215
- }
179
+ orderBookDataList.forEach((entry: { bids: [[]]; asks: [[]] }) => {
180
+ if (entry.bids !== null && entry.bids !== undefined) {
181
+ const flattened = entry.bids.reduce((acc: any[], val: any[]) => acc.concat(val), []);
182
+ const entryBidPrice = Number(flattened[0]);
183
+ const entryBidSize = Number(flattened[1]);
184
+
185
+ // remove prices with zero Qty
186
+ if (entryBidSize === 0) {
187
+ for (let i = orderBookBidList.length - 1; i >= 0; i--) {
188
+ if (orderBookBidList[i][0] === entryBidPrice) {
189
+ orderBookBidList.splice(i, 1);
190
+ }
191
+ }
192
+ } else {
193
+ // The price that already exists in the order book is modified only Qty
194
+ if (orderBookBidList.some((innerArray) => innerArray[0] === entryBidPrice)) {
195
+ orderBookBidList.forEach((item, index) => {
196
+ if (item[0] === entryBidPrice) {
197
+ orderBookBidList[index][1] = entryBidSize;
198
+ orderBookBidList[index][2] = messageId;
216
199
  }
200
+ });
201
+ } else {
202
+ // Add new data to order book
203
+ orderBookBidList.push([entryBidPrice, entryBidSize, messageId]);
217
204
  }
218
- if (entry.asks !== null && entry.asks !== undefined) {
219
- const flattened = entry.asks.reduce((acc: any[], val: any[]) => acc.concat(val), []);
220
- const entryAskPrice = Number(flattened[0]);
221
- const entryAskSize = Number(flattened[1]);
222
-
223
- if (entryAskSize === 0) {
224
- // remove prices with zero Qty
225
- for (let i = orderBookAskList.length - 1; i >= 0; i--) {
226
- if (orderBookAskList[i][0] === entryAskPrice) {
227
- orderBookAskList.splice(i, 1);
228
- }
229
- }
230
- } else {
231
- // The price that already exists in the order book is modified only Qty
232
- if (
233
- orderBookAskList.some((innerArray) => innerArray[0] === entryAskPrice)
234
- ) {
235
- orderBookAskList.forEach((item, index) => {
236
- if (item[0] === entryAskPrice) {
237
- orderBookAskList[index][1] = entryAskSize;
238
- orderBookAskList[index][2] = messageId;
239
- }
240
- });
241
- } else {
242
- // Add new data to order book
243
- orderBookAskList.push([entryAskPrice, entryAskSize, messageId]);
244
- }
205
+ }
206
+ }
207
+ if (entry.asks !== null && entry.asks !== undefined) {
208
+ const flattened = entry.asks.reduce((acc: any[], val: any[]) => acc.concat(val), []);
209
+ const entryAskPrice = Number(flattened[0]);
210
+ const entryAskSize = Number(flattened[1]);
211
+
212
+ if (entryAskSize === 0) {
213
+ // remove prices with zero Qty
214
+ for (let i = orderBookAskList.length - 1; i >= 0; i--) {
215
+ if (orderBookAskList[i][0] === entryAskPrice) {
216
+ orderBookAskList.splice(i, 1);
217
+ }
218
+ }
219
+ } else {
220
+ // The price that already exists in the order book is modified only Qty
221
+ if (orderBookAskList.some((innerArray) => innerArray[0] === entryAskPrice)) {
222
+ orderBookAskList.forEach((item, index) => {
223
+ if (item[0] === entryAskPrice) {
224
+ orderBookAskList[index][1] = entryAskSize;
225
+ orderBookAskList[index][2] = messageId;
245
226
  }
227
+ });
228
+ } else {
229
+ // Add new data to order book
230
+ orderBookAskList.push([entryAskPrice, entryAskSize, messageId]);
246
231
  }
247
- });
232
+ }
233
+ }
234
+ });
248
235
 
249
- return [orderBookBidList, orderBookAskList];
236
+ return [orderBookBidList, orderBookAskList];
250
237
  };
251
238
 
252
- test();
239
+ test();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dydxprotocol/v4-client-js",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "General client library for the new dYdX system (v4 decentralized)",
5
5
  "main": "build/src/index.js",
6
6
  "scripts": {
@@ -3,7 +3,7 @@ import {
3
3
  AccountData,
4
4
  DirectSecp256k1HdWallet,
5
5
  EncodeObject,
6
- OfflineDirectSigner,
6
+ OfflineSigner,
7
7
  } from '@cosmjs/proto-signing';
8
8
  import { SigningStargateClient } from '@cosmjs/stargate';
9
9
  import Long from 'long';
@@ -22,9 +22,9 @@ export default class LocalWallet {
22
22
  address?: string;
23
23
  pubKey?: Secp256k1Pubkey;
24
24
  signer?: TransactionSigner;
25
- offlineSigner?: OfflineDirectSigner;
25
+ offlineSigner?: OfflineSigner;
26
26
 
27
- static async fromOfflineSigner(signer: OfflineDirectSigner): Promise<LocalWallet> {
27
+ static async fromOfflineSigner(signer: OfflineSigner): Promise<LocalWallet> {
28
28
  const wallet = new LocalWallet();
29
29
  await wallet.setSigner(signer);
30
30
  return wallet;
@@ -36,7 +36,7 @@ export default class LocalWallet {
36
36
  return wallet;
37
37
  }
38
38
 
39
- async setSigner(signer: OfflineDirectSigner): Promise<void> {
39
+ async setSigner(signer: OfflineSigner): Promise<void> {
40
40
  this.offlineSigner = signer;
41
41
  const stargateClient = await SigningStargateClient.offline(signer, {
42
42
  registry: generateRegistry(),
@@ -1,7 +1,14 @@
1
1
  import { Secp256k1Pubkey } from '@cosmjs/amino';
2
2
  import { fromBase64 } from '@cosmjs/encoding';
3
3
  import { Int53 } from '@cosmjs/math';
4
- import { EncodeObject, encodePubkey, makeAuthInfoBytes, makeSignDoc, OfflineDirectSigner } from '@cosmjs/proto-signing';
4
+ import {
5
+ EncodeObject,
6
+ encodePubkey,
7
+ isOfflineDirectSigner,
8
+ makeAuthInfoBytes,
9
+ makeSignDoc,
10
+ OfflineSigner,
11
+ } from '@cosmjs/proto-signing';
5
12
  import { SigningStargateClient, StdFee } from '@cosmjs/stargate';
6
13
  import { TxExtension } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/accountplus/tx';
7
14
  import { TxBody, TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx';
@@ -22,12 +29,12 @@ protobuf.configure();
22
29
  export class TransactionSigner {
23
30
  readonly address: string;
24
31
  readonly stargateSigningClient: SigningStargateClient;
25
- readonly offlineSigner: OfflineDirectSigner;
32
+ readonly offlineSigner: OfflineSigner;
26
33
 
27
34
  constructor(
28
35
  address: string,
29
36
  stargateSigningClient: SigningStargateClient,
30
- offlineSigner: OfflineDirectSigner,
37
+ offlineSigner: OfflineSigner,
31
38
  ) {
32
39
  this.address = address;
33
40
  this.stargateSigningClient = stargateSigningClient;
@@ -105,14 +112,28 @@ export class TransactionSigner {
105
112
 
106
113
  // Use OfflineSigner to sign the transaction
107
114
  const signerAddress = this.address;
108
- const { signed, signature } = await this.offlineSigner.signDirect(signerAddress, signDoc);
109
-
110
- const txRaw = TxRaw.fromPartial({
111
- bodyBytes: signed.bodyBytes,
112
- authInfoBytes: signed.authInfoBytes,
113
- signatures: [fromBase64(signature.signature)],
114
- });
115
-
116
- return Uint8Array.from(TxRaw.encode(txRaw).finish());
115
+ if (isOfflineDirectSigner(this.offlineSigner)) {
116
+ const { signed, signature } = await this.offlineSigner.signDirect(signerAddress, signDoc);
117
+
118
+ const txRaw = TxRaw.fromPartial({
119
+ bodyBytes: signed.bodyBytes,
120
+ authInfoBytes: signed.authInfoBytes,
121
+ signatures: [fromBase64(signature.signature)],
122
+ });
123
+ return Uint8Array.from(TxRaw.encode(txRaw).finish());
124
+ } else {
125
+ const rawTx: TxRaw = await this.stargateSigningClient.sign(
126
+ this.address,
127
+ messages,
128
+ fee,
129
+ memo,
130
+ {
131
+ accountNumber: transactionOptions.accountNumber,
132
+ sequence: transactionOptions.sequence,
133
+ chainId: transactionOptions.chainId,
134
+ },
135
+ );
136
+ return Uint8Array.from(TxRaw.encode(rawTx).finish());
137
+ }
117
138
  }
118
139
  }