@dydxprotocol/v4-client-js 1.0.14 → 1.0.16

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.
Files changed (33) hide show
  1. package/__native__/__ios__/v4-native-client.js +2 -2
  2. package/build/examples/gov_add_new_market.d.ts +1 -0
  3. package/build/examples/gov_add_new_market.js +75 -0
  4. package/build/src/clients/composite-client.d.ts +13 -1
  5. package/build/src/clients/composite-client.js +44 -1
  6. package/build/src/clients/constants.d.ts +14 -0
  7. package/build/src/clients/constants.js +28 -2
  8. package/build/src/clients/lib/registry.js +19 -7
  9. package/build/src/clients/modules/composer.d.ts +11 -1
  10. package/build/src/clients/modules/composer.js +131 -7
  11. package/build/src/clients/modules/get.d.ts +11 -1
  12. package/build/src/clients/modules/get.js +23 -1
  13. package/build/src/clients/modules/proto-includes.d.ts +3 -1
  14. package/build/src/clients/modules/proto-includes.js +5 -3
  15. package/build/src/clients/native.js +2 -2
  16. package/build/src/clients/types.d.ts +14 -0
  17. package/build/src/clients/types.js +1 -1
  18. package/build/src/lib/helpers.js +2 -2
  19. package/build/src/lib/utils.d.ts +15 -0
  20. package/build/src/lib/utils.js +23 -2
  21. package/examples/gov_add_new_market.json +64 -0
  22. package/examples/gov_add_new_market.ts +93 -0
  23. package/package.json +1 -1
  24. package/src/clients/composite-client.ts +97 -2
  25. package/src/clients/constants.ts +42 -8
  26. package/src/clients/lib/registry.ts +34 -7
  27. package/src/clients/modules/composer.ts +218 -7
  28. package/src/clients/modules/get.ts +36 -3
  29. package/src/clients/modules/proto-includes.ts +5 -3
  30. package/src/clients/native.ts +1 -1
  31. package/src/clients/types.ts +26 -0
  32. package/src/lib/helpers.ts +1 -1
  33. package/src/lib/utils.ts +24 -0
@@ -1,9 +1,40 @@
1
- import { EncodeObject } from '@cosmjs/proto-signing';
1
+ import { EncodeObject, Registry } from '@cosmjs/proto-signing';
2
+ import {
3
+ MsgSubmitProposal,
4
+ } from '@dydxprotocol/v4-proto/src/codegen/cosmos/gov/v1/tx';
5
+ import {
6
+ ClobPair_Status,
7
+ } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/clob_pair';
8
+ import {
9
+ MsgCreateClobPair,
10
+ MsgUpdateClobPair,
11
+ } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/tx';
12
+ import { MsgDelayMessage } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/delaymsg/tx';
13
+ import { MsgCreatePerpetual } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/perpetuals/tx';
14
+ import { MsgCreateOracleMarket } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/prices/tx';
2
15
  import { MsgSend } from 'cosmjs-types/cosmos/bank/v1beta1/tx';
3
16
  import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin';
17
+ import { Any } from 'cosmjs-types/google/protobuf/any';
4
18
  import Long from 'long';
5
19
  import protobuf from 'protobufjs';
6
20
 
21
+ import {
22
+ GOV_MODULE_ADDRESS,
23
+ DELAYMSG_MODULE_ADDRESS,
24
+ TYPE_URL_MSG_SEND,
25
+ TYPE_URL_MSG_SUBMIT_PROPOSAL,
26
+ TYPE_URL_MSG_PLACE_ORDER,
27
+ TYPE_URL_MSG_CANCEL_ORDER,
28
+ TYPE_URL_MSG_CREATE_CLOB_PAIR,
29
+ TYPE_URL_MSG_UPDATE_CLOB_PAIR,
30
+ TYPE_URL_MSG_DELAY_MESSAGE,
31
+ TYPE_URL_MSG_CREATE_PERPETUAL,
32
+ TYPE_URL_MSG_CREATE_ORACLE_MARKET,
33
+ TYPE_URL_MSG_CREATE_TRANSFER,
34
+ TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT,
35
+ TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT,
36
+ } from '../constants';
37
+ import { DenomConfig } from '../types';
7
38
  import {
8
39
  OrderId,
9
40
  Order,
@@ -23,6 +54,8 @@ protobuf.util.Long = Long;
23
54
  protobuf.configure();
24
55
 
25
56
  export class Composer {
57
+
58
+ // ------------ x/clob ------------
26
59
  public composeMsgPlaceOrder(
27
60
  address: string,
28
61
  subaccountNumber: number,
@@ -70,7 +103,7 @@ export class Composer {
70
103
  order,
71
104
  };
72
105
  return {
73
- typeUrl: '/dydxprotocol.clob.MsgPlaceOrder',
106
+ typeUrl: TYPE_URL_MSG_PLACE_ORDER,
74
107
  value: msg,
75
108
  };
76
109
  }
@@ -105,11 +138,68 @@ export class Composer {
105
138
  };
106
139
 
107
140
  return {
108
- typeUrl: '/dydxprotocol.clob.MsgCancelOrder',
141
+ typeUrl: TYPE_URL_MSG_CANCEL_ORDER,
109
142
  value: msg,
110
143
  };
111
144
  }
112
145
 
146
+ public composeMsgCreateClobPair(
147
+ clobId: number,
148
+ perpetualId: number,
149
+ quantumConversionExponent: number,
150
+ stepBaseQuantums: Long,
151
+ subticksPerTick: number,
152
+ ): EncodeObject {
153
+ const msg: MsgCreateClobPair = {
154
+ // uses x/gov module account since creating the clob pair is a governance action.
155
+ authority: GOV_MODULE_ADDRESS,
156
+ clobPair: {
157
+ id: clobId,
158
+ perpetualClobMetadata: {
159
+ perpetualId,
160
+ },
161
+ quantumConversionExponent,
162
+ stepBaseQuantums,
163
+ subticksPerTick,
164
+ status: ClobPair_Status.STATUS_INITIALIZING,
165
+ },
166
+ };
167
+
168
+ return {
169
+ typeUrl: TYPE_URL_MSG_CREATE_CLOB_PAIR,
170
+ value: msg,
171
+ };
172
+ }
173
+
174
+ public composeMsgUpdateClobPair(
175
+ clobId: number,
176
+ perpetualId: number,
177
+ quantumConversionExponent: number,
178
+ stepBaseQuantums: Long,
179
+ subticksPerTick: number,
180
+ ): EncodeObject {
181
+ const msg: MsgUpdateClobPair = {
182
+ // uses x/delaymsg module account since updating the clob pair is a delayedmsg action.
183
+ authority: DELAYMSG_MODULE_ADDRESS,
184
+ clobPair: {
185
+ id: clobId,
186
+ perpetualClobMetadata: {
187
+ perpetualId,
188
+ },
189
+ quantumConversionExponent,
190
+ stepBaseQuantums,
191
+ subticksPerTick,
192
+ status: ClobPair_Status.STATUS_ACTIVE,
193
+ },
194
+ };
195
+
196
+ return {
197
+ typeUrl: TYPE_URL_MSG_UPDATE_CLOB_PAIR,
198
+ value: msg,
199
+ };
200
+ }
201
+
202
+ // ------------ x/sending ------------
113
203
  public composeMsgTransfer(
114
204
  address: string,
115
205
  subaccountNumber: number,
@@ -139,7 +229,7 @@ export class Composer {
139
229
  };
140
230
 
141
231
  return {
142
- typeUrl: '/dydxprotocol.sending.MsgCreateTransfer',
232
+ typeUrl: TYPE_URL_MSG_CREATE_TRANSFER,
143
233
  value: msg,
144
234
  };
145
235
  }
@@ -163,7 +253,7 @@ export class Composer {
163
253
  };
164
254
 
165
255
  return {
166
- typeUrl: '/dydxprotocol.sending.MsgDepositToSubaccount',
256
+ typeUrl: TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT,
167
257
  value: msg,
168
258
  };
169
259
  }
@@ -188,11 +278,12 @@ export class Composer {
188
278
  };
189
279
 
190
280
  return {
191
- typeUrl: '/dydxprotocol.sending.MsgWithdrawFromSubaccount',
281
+ typeUrl: TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT,
192
282
  value: msg,
193
283
  };
194
284
  }
195
285
 
286
+ // ------------ x/bank ------------
196
287
  public composeMsgSendToken(
197
288
  address: string,
198
289
  recipient: string,
@@ -211,11 +302,117 @@ export class Composer {
211
302
  };
212
303
 
213
304
  return {
214
- typeUrl: '/cosmos.bank.v1beta1.MsgSend',
305
+ typeUrl: TYPE_URL_MSG_SEND,
306
+ value: msg,
307
+ };
308
+ }
309
+
310
+ // ------------ x/prices ------------
311
+ public composeMsgCreateOracleMarket(
312
+ marketId: number,
313
+ pair: string,
314
+ exponent: number,
315
+ minExchanges: number,
316
+ minPriceChangePpm: number,
317
+ exchangeConfigJson: string,
318
+ ): EncodeObject {
319
+ const msg: MsgCreateOracleMarket = {
320
+ // uses x/gov module account since creating the oracle market is a governance action.
321
+ authority: GOV_MODULE_ADDRESS,
322
+ params: {
323
+ id: marketId,
324
+ pair,
325
+ exponent,
326
+ minExchanges,
327
+ minPriceChangePpm,
328
+ exchangeConfigJson,
329
+ },
330
+ };
331
+
332
+ return {
333
+ typeUrl: TYPE_URL_MSG_CREATE_ORACLE_MARKET,
215
334
  value: msg,
216
335
  };
217
336
  }
218
337
 
338
+ // ------------ x/perpetuals ------------
339
+ public composeMsgCreatePerpetual(
340
+ perpetualId: number,
341
+ marketId: number,
342
+ ticker: string,
343
+ atomicResolution: number,
344
+ liquidityTier: number,
345
+ ): EncodeObject {
346
+ const msg: MsgCreatePerpetual = {
347
+ // uses x/gov module account since creating the perpetual is a governance action.
348
+ authority: GOV_MODULE_ADDRESS,
349
+ params: {
350
+ id: perpetualId,
351
+ marketId,
352
+ ticker,
353
+ atomicResolution,
354
+ defaultFundingPpm: 0, // default funding should be 0 to start.
355
+ liquidityTier,
356
+ },
357
+ };
358
+
359
+ return {
360
+ typeUrl: TYPE_URL_MSG_CREATE_PERPETUAL,
361
+ value: msg,
362
+ };
363
+ }
364
+
365
+ // ------------ x/delaymsg ------------
366
+ public composeMsgDelayMessage(
367
+ embeddedMsg: EncodeObject,
368
+ delayBlocks: number,
369
+ ): EncodeObject {
370
+ const msg: MsgDelayMessage = {
371
+ // all msgs sent to x/delay must be from x/gov module account.
372
+ authority: GOV_MODULE_ADDRESS,
373
+ msg: embeddedMsg,
374
+ delayBlocks,
375
+ };
376
+
377
+ return {
378
+ typeUrl: TYPE_URL_MSG_DELAY_MESSAGE,
379
+ value: msg,
380
+ };
381
+ }
382
+
383
+ // ------------ x/gov ------------
384
+ public composeMsgSubmitProposal(
385
+ title: string,
386
+ initialDepositAmount: number,
387
+ initialDepositDenomConfig: DenomConfig,
388
+ summary: string,
389
+ messages: EncodeObject[],
390
+ proposer: string,
391
+ metadata: string = '',
392
+ expedited: boolean = false,
393
+ ): EncodeObject {
394
+ const initialDeposit: Coin[] = [{
395
+ amount: initialDepositAmount.toString(),
396
+ denom: initialDepositDenomConfig.CHAINTOKEN_DENOM,
397
+ }];
398
+
399
+ const msg: MsgSubmitProposal = {
400
+ title,
401
+ initialDeposit,
402
+ summary,
403
+ messages,
404
+ proposer,
405
+ metadata,
406
+ expedited,
407
+ };
408
+
409
+ return {
410
+ typeUrl: TYPE_URL_MSG_SUBMIT_PROPOSAL,
411
+ value: msg,
412
+ };
413
+ }
414
+
415
+ // ------------ util ------------
219
416
  public validateGoodTilBlockAndTime(
220
417
  orderFlags: number,
221
418
  goodTilBlock: number,
@@ -227,4 +424,18 @@ export class Composer {
227
424
  throw new Error('goodTilBlockTime must be set if orderFlags is not 0');
228
425
  }
229
426
  }
427
+
428
+ public wrapMessageAsAny(registry: Registry, message: EncodeObject): Any {
429
+ return registry.encodeAsAny(message);
430
+ }
431
+
432
+ public wrapMessageArrAsAny(
433
+ registry: Registry,
434
+ messages: EncodeObject[],
435
+ ): Any[] {
436
+ const encodedMessages: Any[] = messages.map(
437
+ (message: EncodeObject) => this.wrapMessageAsAny(registry, message),
438
+ );
439
+ return encodedMessages;
440
+ }
230
441
  }
@@ -19,8 +19,10 @@ import {
19
19
  BridgeModule,
20
20
  ClobModule,
21
21
  FeeTierModule,
22
+ GovV1Module,
22
23
  PerpetualsModule,
23
24
  PricesModule,
25
+ ProposalStatus,
24
26
  RewardsModule,
25
27
  StakingModule,
26
28
  StatsModule,
@@ -365,7 +367,7 @@ export class Get {
365
367
  */
366
368
  async getEquityTierLimitConfiguration(): Promise<
367
369
  ClobModule.QueryEquityTierLimitConfigurationResponse
368
- > {
370
+ > {
369
371
  const requestData: Uint8Array = Uint8Array.from(
370
372
  ClobModule.QueryEquityTierLimitConfigurationRequest.encode({})
371
373
  .finish(),
@@ -470,9 +472,40 @@ export class Get {
470
472
  return StakingModule.QueryValidatorsResponse.decode(data);
471
473
  }
472
474
 
475
+ /**
476
+ * @description Get all gov proposals.
477
+ *
478
+ * @param proposalStatus Status of the proposal to filter by.
479
+ * @param voter Voter to filter by.
480
+ * @param depositor Depositor to filter by.
481
+ *
482
+ * @returns All gov proposals that match the filters above.
483
+ */
484
+ async getAllGovProposals(
485
+ proposalStatus: ProposalStatus = ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD,
486
+ voter: string = '',
487
+ depositor: string = '',
488
+ ): Promise<GovV1Module.QueryProposalsResponse> {
489
+ const requestData = Uint8Array.from(
490
+ GovV1Module.QueryProposalsRequest
491
+ .encode({
492
+ proposalStatus,
493
+ voter,
494
+ depositor,
495
+ pagination: PAGE_REQUEST,
496
+ })
497
+ .finish(),
498
+ );
499
+ const data: Uint8Array = await this.sendQuery(
500
+ '/cosmos.gov.v1.Query/Proposals',
501
+ requestData,
502
+ );
503
+ return GovV1Module.QueryProposalsResponse.decode(data);
504
+ }
505
+
473
506
  private async sendQuery(requestUrl: string, requestData: Uint8Array): Promise<Uint8Array> {
474
- const resp: QueryAbciResponse = await
475
- this.stargateQueryClient.queryAbci(requestUrl, requestData);
507
+ // eslint-disable-next-line max-len
508
+ const resp: QueryAbciResponse = await this.stargateQueryClient.queryAbci(requestUrl, requestData);
476
509
  return resp.value;
477
510
  }
478
511
  }
@@ -1,15 +1,17 @@
1
+ export * as GovV1Module from '@dydxprotocol/v4-proto/src/codegen/cosmos/gov/v1/query';
2
+ export * as StatsModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/stats/query';
3
+
1
4
  export * as ClobModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/query';
2
5
  export * as PerpetualsModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/perpetuals/query';
3
6
  export * as PricesModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/prices/query';
4
- export * as SubaccountsModule
5
- from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/subaccounts/query';
7
+ export * as SubaccountsModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/subaccounts/query';
6
8
  export * as FeeTierModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/feetiers/query';
7
- export * as StatsModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/stats/query';
8
9
  export * as RewardsModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/rewards/query';
9
10
  export * as StakingModule from '@dydxprotocol/v4-proto/src/codegen/cosmos/staking/v1beta1/query';
10
11
  export * as BridgeModule from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/bridge/query';
11
12
 
12
13
  export * from '@dydxprotocol/v4-proto/src/codegen/cosmos/base/abci/v1beta1/abci';
14
+ export * from '@dydxprotocol/v4-proto/src/codegen/cosmos/gov/v1/gov';
13
15
  export * from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/order';
14
16
  export * from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/tx';
15
17
  export * from '@dydxprotocol/v4-proto/src/codegen/google/protobuf/any';
@@ -1112,7 +1112,7 @@ export async function withdrawToNobleIBC(payload: string): Promise<String> {
1112
1112
  ...parsedIbcPayload.msg,
1113
1113
  // Squid returns timeoutTimestamp as Long, but the signer expects BigInt
1114
1114
  timeoutTimestamp: parsedIbcPayload.msg.timeoutTimestamp
1115
- ? BigInt(Long.fromValue(json.msg.timeoutTimestamp).toString())
1115
+ ? BigInt(Long.fromValue(parsedIbcPayload.msg.timeoutTimestamp).toString())
1116
1116
  : undefined,
1117
1117
  },
1118
1118
  };
@@ -96,6 +96,7 @@ export interface ComplianceResponse {
96
96
  restricted: boolean;
97
97
  }
98
98
 
99
+ // ------------ Squid ------------ //
99
100
  export type SquidIBCPayload = {
100
101
  msgTypeUrl: '/ibc.applications.transfer.v1.MsgTransfer';
101
102
  msg: Partial<{
@@ -109,4 +110,29 @@ export type SquidIBCPayload = {
109
110
  }>;
110
111
  };
111
112
 
113
+ // ------------ x/gov: Add New Market ------------ //
114
+ export type GovAddNewMarketParams = {
115
+ // common
116
+ id: number;
117
+ ticker: string;
118
+
119
+ // x/prices
120
+ priceExponent: number;
121
+ minPriceChange: number;
122
+ minExchanges: number;
123
+ exchangeConfigJson: string;
124
+
125
+ // x/perpetuals
126
+ liquidityTier: number;
127
+ atomicResolution: number;
128
+
129
+ // x/clob
130
+ quantumConversionExponent: number;
131
+ stepBaseQuantums: Long;
132
+ subticksPerTick: number;
133
+
134
+ // x/delaymsg
135
+ delayBlocks: number;
136
+ };
137
+
112
138
  export * from './modules/proto-includes';
@@ -65,7 +65,7 @@ export function encodeJson(
65
65
  if (value instanceof BigNumber) {
66
66
  return value.toString();
67
67
  }
68
- if (value instanceof BigInt) {
68
+ if (typeof value === 'bigint') {
69
69
  return value.toString();
70
70
  }
71
71
  if (value instanceof Long) {
package/src/lib/utils.ts CHANGED
@@ -43,3 +43,27 @@ export function clientIdFromString(
43
43
  export async function sleep(ms: number): Promise<void> {
44
44
  return new Promise((resolve) => setTimeout(resolve, ms));
45
45
  }
46
+
47
+ /**
48
+ * Returns a title to use for a gov proposal that adds a new market.
49
+ *
50
+ * @param ticker ticker symbol for the new market.
51
+ * @returns title for the gov proposal.
52
+ */
53
+ export function getGovAddNewMarketTitle(ticker: string): string {
54
+ return `Add ${ticker} perpetual market`;
55
+ }
56
+
57
+ /**
58
+ * Returns a summary to use for a gov proposal that adds a new market.
59
+ *
60
+ * @param ticker ticker symbol for the new market.
61
+ * @param delayBlocks number of blocks to wait before activating the market.
62
+ * @returns summary for the gov proposal.
63
+ */
64
+ export function getGovAddNewMarketSummary(
65
+ ticker: string,
66
+ delayBlocks: number,
67
+ ): string {
68
+ return `Add the x/prices, x/perpetuals and x/clob parameters needed for a ${ticker} perpetual market. Create the market in INITIALIZING status and transition it to ACTIVE status after ${delayBlocks} blocks.`;
69
+ }