@drift-labs/sdk 2.54.0-beta.0 → 2.54.0-beta.10

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 (52) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.js +0 -1
  3. package/lib/constants/perpMarkets.js +20 -0
  4. package/lib/driftClient.d.ts +8 -2
  5. package/lib/driftClient.js +95 -20
  6. package/lib/events/webSocketLogProvider.js +3 -0
  7. package/lib/idl/drift.json +7 -1
  8. package/lib/jupiter/jupiterClient.d.ts +6 -0
  9. package/lib/jupiter/jupiterClient.js +2 -2
  10. package/lib/math/funding.js +24 -1
  11. package/lib/math/oracles.js +2 -2
  12. package/lib/math/superStake.d.ts +51 -0
  13. package/lib/math/superStake.js +10 -2
  14. package/lib/priorityFee/averageOverSlotsStrategy.d.ts +0 -5
  15. package/lib/priorityFee/averageOverSlotsStrategy.js +1 -13
  16. package/lib/priorityFee/maxOverSlotsStrategy.d.ts +0 -5
  17. package/lib/priorityFee/maxOverSlotsStrategy.js +1 -13
  18. package/lib/priorityFee/priorityFeeSubscriber.d.ts +5 -4
  19. package/lib/priorityFee/priorityFeeSubscriber.js +15 -21
  20. package/lib/tx/baseTxSender.d.ts +6 -2
  21. package/lib/tx/baseTxSender.js +47 -2
  22. package/lib/tx/fastSingleTxSender.d.ts +3 -2
  23. package/lib/tx/fastSingleTxSender.js +10 -2
  24. package/lib/tx/retryTxSender.d.ts +3 -2
  25. package/lib/tx/retryTxSender.js +14 -23
  26. package/lib/tx/types.d.ts +5 -0
  27. package/lib/tx/types.js +7 -0
  28. package/lib/tx/utils.d.ts +5 -1
  29. package/lib/tx/utils.js +20 -1
  30. package/lib/userMap/userMap.js +4 -0
  31. package/package.json +1 -1
  32. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -1
  33. package/src/constants/perpMarkets.ts +20 -0
  34. package/src/driftClient.ts +197 -39
  35. package/src/events/webSocketLogProvider.ts +11 -2
  36. package/src/idl/drift.json +7 -1
  37. package/src/jupiter/jupiterClient.ts +8 -2
  38. package/src/math/funding.ts +28 -1
  39. package/src/math/oracles.ts +2 -2
  40. package/src/math/superStake.ts +60 -1
  41. package/src/priorityFee/averageOverSlotsStrategy.ts +1 -16
  42. package/src/priorityFee/maxOverSlotsStrategy.ts +1 -16
  43. package/src/priorityFee/priorityFeeSubscriber.ts +22 -26
  44. package/src/tx/baseTxSender.ts +64 -2
  45. package/src/tx/fastSingleTxSender.ts +11 -2
  46. package/src/tx/retryTxSender.ts +16 -25
  47. package/src/tx/types.ts +6 -0
  48. package/src/tx/utils.ts +32 -0
  49. package/src/userMap/userMap.ts +3 -0
  50. package/tests/amm/test.ts +275 -2
  51. package/tests/dlob/test.ts +2 -2
  52. package/tests/tx/priorityFeeStrategy.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { TxSender, TxSigAndSlot } from './types';
2
+ import { ConfirmationStrategy, TxSender, TxSigAndSlot } from './types';
3
3
  import { Commitment, ConfirmOptions, RpcResponseAndContext, Signer, SignatureResult, Transaction, TransactionSignature, Connection, VersionedTransaction, TransactionInstruction, AddressLookupTableAccount } from '@solana/web3.js';
4
4
  import { IWallet } from '../types';
5
5
  export declare abstract class BaseTxSender implements TxSender {
@@ -9,18 +9,22 @@ export declare abstract class BaseTxSender implements TxSender {
9
9
  timeout: number;
10
10
  additionalConnections: Connection[];
11
11
  timeoutCount: number;
12
- constructor({ connection, wallet, opts, timeout, additionalConnections, }: {
12
+ confirmationStrategy: ConfirmationStrategy;
13
+ constructor({ connection, wallet, opts, timeout, additionalConnections, confirmationStrategy, }: {
13
14
  connection: Connection;
14
15
  wallet: IWallet;
15
16
  opts?: ConfirmOptions;
16
17
  timeout?: number;
17
18
  additionalConnections?: any;
19
+ confirmationStrategy?: ConfirmationStrategy;
18
20
  });
19
21
  send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
20
22
  prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
21
23
  getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
22
24
  sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean): Promise<TxSigAndSlot>;
23
25
  sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
26
+ confirmTransactionWebSocket(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
27
+ confirmTransactionPolling(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult> | undefined>;
24
28
  confirmTransaction(signature: TransactionSignature, commitment?: Commitment): Promise<RpcResponseAndContext<SignatureResult>>;
25
29
  getTimestamp(): number;
26
30
  promiseTimeout<T>(promises: Promise<T>[], timeoutMs: number): Promise<T | null>;
@@ -4,19 +4,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.BaseTxSender = void 0;
7
+ const types_1 = require("./types");
7
8
  const web3_js_1 = require("@solana/web3.js");
8
9
  const anchor_1 = require("@coral-xyz/anchor");
9
10
  const assert_1 = __importDefault(require("assert"));
10
11
  const bs58_1 = __importDefault(require("bs58"));
11
12
  const DEFAULT_TIMEOUT = 35000;
12
13
  class BaseTxSender {
13
- constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, additionalConnections = new Array(), }) {
14
+ constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, }) {
14
15
  this.timeoutCount = 0;
15
16
  this.connection = connection;
16
17
  this.wallet = wallet;
17
18
  this.opts = opts;
18
19
  this.timeout = timeout;
19
20
  this.additionalConnections = additionalConnections;
21
+ this.confirmationStrategy = confirmationStrategy;
20
22
  }
21
23
  async send(tx, additionalSigners, opts, preSigned) {
22
24
  if (additionalSigners === undefined) {
@@ -86,7 +88,8 @@ class BaseTxSender {
86
88
  opts) {
87
89
  throw new Error('Must be implemented by subclass');
88
90
  }
89
- async confirmTransaction(signature, commitment) {
91
+ async confirmTransactionWebSocket(signature, commitment) {
92
+ var _a;
90
93
  let decodedSignature;
91
94
  try {
92
95
  decodedSignature = bs58_1.default.decode(signature);
@@ -131,12 +134,54 @@ class BaseTxSender {
131
134
  }
132
135
  }
133
136
  if (response === null) {
137
+ if (this.confirmationStrategy === types_1.ConfirmationStrategy.Combo) {
138
+ try {
139
+ const rpcResponse = await this.connection.getSignatureStatus(signature);
140
+ if ((_a = rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value) === null || _a === void 0 ? void 0 : _a.confirmationStatus) {
141
+ response = {
142
+ context: rpcResponse.context,
143
+ value: { err: rpcResponse.value.err },
144
+ };
145
+ return response;
146
+ }
147
+ }
148
+ catch (error) {
149
+ // Ignore error to pass through to timeout error
150
+ }
151
+ }
134
152
  this.timeoutCount += 1;
135
153
  const duration = (Date.now() - start) / 1000;
136
154
  throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
137
155
  }
138
156
  return response;
139
157
  }
158
+ async confirmTransactionPolling(signature, commitment = 'finalized') {
159
+ var _a;
160
+ let totalTime = 0;
161
+ let backoffTime = 400; // approx block time
162
+ while (totalTime < this.timeout) {
163
+ await new Promise((resolve) => setTimeout(resolve, backoffTime));
164
+ const response = await this.connection.getSignatureStatus(signature);
165
+ const result = response && ((_a = response.value) === null || _a === void 0 ? void 0 : _a[0]);
166
+ if (result && result.confirmationStatus === commitment) {
167
+ return { context: result.context, value: { err: null } };
168
+ }
169
+ totalTime += backoffTime;
170
+ backoffTime = Math.min(backoffTime * 2, 5000);
171
+ }
172
+ // Transaction not confirmed within 30 seconds
173
+ this.timeoutCount += 1;
174
+ throw new Error(`Transaction was not confirmed in 30 seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
175
+ }
176
+ async confirmTransaction(signature, commitment) {
177
+ if (this.confirmationStrategy === types_1.ConfirmationStrategy.WebSocket ||
178
+ this.confirmationStrategy === types_1.ConfirmationStrategy.Combo) {
179
+ return await this.confirmTransactionWebSocket(signature, commitment);
180
+ }
181
+ else if (this.confirmationStrategy === types_1.ConfirmationStrategy.Polling) {
182
+ return await this.confirmTransactionPolling(signature, commitment);
183
+ }
184
+ }
140
185
  getTimestamp() {
141
186
  return new Date().getTime();
142
187
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { TxSigAndSlot } from './types';
2
+ import { ConfirmationStrategy, TxSigAndSlot } from './types';
3
3
  import { ConfirmOptions, Signer, Transaction, Connection, VersionedTransaction, TransactionInstruction, AddressLookupTableAccount, Commitment } from '@solana/web3.js';
4
4
  import { IWallet } from '../types';
5
5
  import { BaseTxSender } from './baseTxSender';
@@ -14,7 +14,7 @@ export declare class FastSingleTxSender extends BaseTxSender {
14
14
  recentBlockhash: string;
15
15
  skipConfirmation: boolean;
16
16
  blockhashCommitment: Commitment;
17
- constructor({ connection, wallet, opts, timeout, blockhashRefreshInterval, additionalConnections, skipConfirmation, blockhashCommitment, }: {
17
+ constructor({ connection, wallet, opts, timeout, blockhashRefreshInterval, additionalConnections, skipConfirmation, blockhashCommitment, confirmationStrategy, }: {
18
18
  connection: Connection;
19
19
  wallet: IWallet;
20
20
  opts?: ConfirmOptions;
@@ -23,6 +23,7 @@ export declare class FastSingleTxSender extends BaseTxSender {
23
23
  additionalConnections?: any;
24
24
  skipConfirmation?: boolean;
25
25
  blockhashCommitment?: Commitment;
26
+ confirmationStrategy?: ConfirmationStrategy;
26
27
  });
27
28
  startBlockhashRefreshLoop(): void;
28
29
  prepareTx(tx: Transaction, additionalSigners: Array<Signer>, _opts: ConfirmOptions): Promise<Transaction>;
@@ -1,14 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FastSingleTxSender = void 0;
4
+ const types_1 = require("./types");
4
5
  const web3_js_1 = require("@solana/web3.js");
5
6
  const anchor_1 = require("@coral-xyz/anchor");
6
7
  const baseTxSender_1 = require("./baseTxSender");
7
8
  const DEFAULT_TIMEOUT = 35000;
8
9
  const DEFAULT_BLOCKHASH_REFRESH = 10000;
9
10
  class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
10
- constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, blockhashRefreshInterval = DEFAULT_BLOCKHASH_REFRESH, additionalConnections = new Array(), skipConfirmation = false, blockhashCommitment = 'finalized', }) {
11
- super({ connection, wallet, opts, timeout, additionalConnections });
11
+ constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, blockhashRefreshInterval = DEFAULT_BLOCKHASH_REFRESH, additionalConnections = new Array(), skipConfirmation = false, blockhashCommitment = 'finalized', confirmationStrategy = types_1.ConfirmationStrategy.Combo, }) {
12
+ super({
13
+ connection,
14
+ wallet,
15
+ opts,
16
+ timeout,
17
+ additionalConnections,
18
+ confirmationStrategy,
19
+ });
12
20
  this.timoutCount = 0;
13
21
  this.connection = connection;
14
22
  this.wallet = wallet;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { TxSigAndSlot } from './types';
2
+ import { ConfirmationStrategy, TxSigAndSlot } from './types';
3
3
  import { ConfirmOptions, Connection } from '@solana/web3.js';
4
4
  import { IWallet } from '../types';
5
5
  import { BaseTxSender } from './baseTxSender';
@@ -14,13 +14,14 @@ export declare class RetryTxSender extends BaseTxSender {
14
14
  retrySleep: number;
15
15
  additionalConnections: Connection[];
16
16
  timoutCount: number;
17
- constructor({ connection, wallet, opts, timeout, retrySleep, additionalConnections, }: {
17
+ constructor({ connection, wallet, opts, timeout, retrySleep, additionalConnections, confirmationStrategy, }: {
18
18
  connection: Connection;
19
19
  wallet: IWallet;
20
20
  opts?: ConfirmOptions;
21
21
  timeout?: number;
22
22
  retrySleep?: number;
23
23
  additionalConnections?: any;
24
+ confirmationStrategy?: ConfirmationStrategy;
24
25
  });
25
26
  sleep(reference: ResolveReference): Promise<void>;
26
27
  sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
@@ -1,13 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RetryTxSender = void 0;
4
+ const types_1 = require("./types");
4
5
  const anchor_1 = require("@coral-xyz/anchor");
5
6
  const baseTxSender_1 = require("./baseTxSender");
6
7
  const DEFAULT_TIMEOUT = 35000;
7
8
  const DEFAULT_RETRY = 8000;
8
9
  class RetryTxSender extends baseTxSender_1.BaseTxSender {
9
- constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, additionalConnections = new Array(), }) {
10
- super({ connection, wallet, opts, timeout, additionalConnections });
10
+ constructor({ connection, wallet, opts = anchor_1.AnchorProvider.defaultOptions(), timeout = DEFAULT_TIMEOUT, retrySleep = DEFAULT_RETRY, additionalConnections = new Array(), confirmationStrategy = types_1.ConfirmationStrategy.Combo, }) {
11
+ super({
12
+ connection,
13
+ wallet,
14
+ opts,
15
+ timeout,
16
+ additionalConnections,
17
+ confirmationStrategy,
18
+ });
11
19
  this.timoutCount = 0;
12
20
  this.connection = connection;
13
21
  this.wallet = wallet;
@@ -24,15 +32,8 @@ class RetryTxSender extends baseTxSender_1.BaseTxSender {
24
32
  }
25
33
  async sendRawTransaction(rawTransaction, opts) {
26
34
  const startTime = this.getTimestamp();
27
- let txid;
28
- try {
29
- txid = await this.connection.sendRawTransaction(rawTransaction, opts);
30
- this.sendToAdditionalConnections(rawTransaction, opts);
31
- }
32
- catch (e) {
33
- console.error(e);
34
- throw e;
35
- }
35
+ const txid = await this.connection.sendRawTransaction(rawTransaction, opts);
36
+ this.sendToAdditionalConnections(rawTransaction, opts);
36
37
  let done = false;
37
38
  const resolveReference = {
38
39
  resolve: undefined,
@@ -57,18 +58,8 @@ class RetryTxSender extends baseTxSender_1.BaseTxSender {
57
58
  }
58
59
  }
59
60
  })();
60
- let slot;
61
- try {
62
- const result = await this.confirmTransaction(txid, opts.commitment);
63
- slot = result.context.slot;
64
- }
65
- catch (e) {
66
- console.error(e);
67
- throw e;
68
- }
69
- finally {
70
- stopWaiting();
71
- }
61
+ const result = await this.confirmTransaction(txid, opts.commitment);
62
+ const slot = result.context.slot;
72
63
  return { txSig: txid, slot };
73
64
  }
74
65
  }
package/lib/tx/types.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  /// <reference types="node" />
2
2
  import { AddressLookupTableAccount, ConfirmOptions, Signer, Transaction, TransactionInstruction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';
3
3
  import { IWallet } from '../types';
4
+ export declare enum ConfirmationStrategy {
5
+ WebSocket = "websocket",
6
+ Polling = "polling",
7
+ Combo = "combo"
8
+ }
4
9
  export type TxSigAndSlot = {
5
10
  txSig: TransactionSignature;
6
11
  slot: number;
package/lib/tx/types.js CHANGED
@@ -1,2 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfirmationStrategy = void 0;
4
+ var ConfirmationStrategy;
5
+ (function (ConfirmationStrategy) {
6
+ ConfirmationStrategy["WebSocket"] = "websocket";
7
+ ConfirmationStrategy["Polling"] = "polling";
8
+ ConfirmationStrategy["Combo"] = "combo";
9
+ })(ConfirmationStrategy = exports.ConfirmationStrategy || (exports.ConfirmationStrategy = {}));
package/lib/tx/utils.d.ts CHANGED
@@ -1,2 +1,6 @@
1
- import { Transaction, TransactionInstruction } from '@solana/web3.js';
1
+ import { Wallet } from '@coral-xyz/anchor';
2
+ import { Transaction, TransactionInstruction, VersionedTransaction } from '@solana/web3.js';
2
3
  export declare function wrapInTx(instruction: TransactionInstruction, computeUnits?: number, computeUnitsPrice?: number): Transaction;
4
+ export declare function getSignedTransactionMap(wallet: Wallet, txsToSign: (Transaction | VersionedTransaction | undefined)[], keys: string[]): Promise<{
5
+ [key: string]: Transaction | VersionedTransaction | undefined;
6
+ }>;
package/lib/tx/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wrapInTx = void 0;
3
+ exports.getSignedTransactionMap = exports.wrapInTx = void 0;
4
4
  const web3_js_1 = require("@solana/web3.js");
5
5
  const COMPUTE_UNITS_DEFAULT = 200000;
6
6
  function wrapInTx(instruction, computeUnits = 600000, computeUnitsPrice = 0) {
@@ -18,3 +18,22 @@ function wrapInTx(instruction, computeUnits = 600000, computeUnitsPrice = 0) {
18
18
  return tx.add(instruction);
19
19
  }
20
20
  exports.wrapInTx = wrapInTx;
21
+ /* Helper function for signing multiple transactions where some may be undefined and mapping the output */
22
+ async function getSignedTransactionMap(wallet, txsToSign, keys) {
23
+ const signedTxMap = {};
24
+ const keysWithTx = [];
25
+ txsToSign.forEach((tx, index) => {
26
+ if (tx == undefined) {
27
+ signedTxMap[keys[index]] = undefined;
28
+ }
29
+ else {
30
+ keysWithTx.push(keys[index]);
31
+ }
32
+ });
33
+ const signedTxs = await wallet.signAllTransactions(txsToSign.filter((tx) => tx !== undefined));
34
+ signedTxs.forEach((signedTx, index) => {
35
+ signedTxMap[keysWithTx[index]] = signedTx;
36
+ });
37
+ return signedTxMap;
38
+ }
39
+ exports.getSignedTransactionMap = getSignedTransactionMap;
@@ -236,6 +236,10 @@ class UserMap {
236
236
  await this.addPubkey(new web3_js_1.PublicKey(key), userAccount);
237
237
  this.userMap.get(key).accountSubscriber.updateData(userAccount, slot);
238
238
  }
239
+ else {
240
+ const userAccount = this.decode('User', buffer);
241
+ this.userMap.get(key).accountSubscriber.updateData(userAccount, slot);
242
+ }
239
243
  // give event loop a chance to breathe
240
244
  await new Promise((resolve) => setTimeout(resolve, 0));
241
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.54.0-beta.0",
3
+ "version": "2.54.0-beta.10",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -54,7 +54,6 @@ export class PollingInsuranceFundStakeAccountSubscriber
54
54
 
55
55
  await this.addToAccountLoader();
56
56
 
57
- await this.fetchIfUnloaded();
58
57
  if (this.doesAccountExist()) {
59
58
  this.eventEmitter.emit('update');
60
59
  }
@@ -234,6 +234,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
234
234
  launchTs: 1703173331000,
235
235
  oracleSource: OracleSource.PYTH,
236
236
  },
237
+ {
238
+ fullName: 'AVAX',
239
+ category: ['Rollup', 'Infra'],
240
+ symbol: 'AVAX-PERP',
241
+ baseAssetSymbol: 'AVAX',
242
+ marketIndex: 22,
243
+ oracle: new PublicKey('FVb5h1VmHPfVb1RfqZckchq18GxRv4iKt8T4eVTQAqdz'),
244
+ launchTs: 1704209558000,
245
+ oracleSource: OracleSource.PYTH,
246
+ },
237
247
  ];
238
248
 
239
249
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -457,6 +467,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
457
467
  launchTs: 1703173331000,
458
468
  oracleSource: OracleSource.PYTH,
459
469
  },
470
+ {
471
+ fullName: 'AVAX',
472
+ category: ['Rollup', 'Infra'],
473
+ symbol: 'AVAX-PERP',
474
+ baseAssetSymbol: 'AVAX',
475
+ marketIndex: 22,
476
+ oracle: new PublicKey('Ax9ujW5B9oqcv59N8m6f1BpTBq2rGeGaBcpKjC5UYsXU'),
477
+ launchTs: 1704209558000,
478
+ oracleSource: OracleSource.PYTH,
479
+ },
460
480
  ];
461
481
 
462
482
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {