@drift-labs/sdk 2.142.0-beta.8 → 2.142.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.
Files changed (58) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
  3. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +245 -44
  4. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +7 -4
  5. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +115 -19
  6. package/lib/browser/adminClient.d.ts +4 -0
  7. package/lib/browser/adminClient.js +34 -0
  8. package/lib/browser/constants/perpMarkets.js +35 -0
  9. package/lib/browser/constants/spotMarkets.js +4 -4
  10. package/lib/browser/driftClient.d.ts +35 -5
  11. package/lib/browser/driftClient.js +41 -14
  12. package/lib/browser/events/parse.d.ts +2 -0
  13. package/lib/browser/events/parse.js +94 -1
  14. package/lib/browser/events/types.d.ts +22 -3
  15. package/lib/browser/idl/drift.json +105 -6
  16. package/lib/browser/math/amm.d.ts +1 -0
  17. package/lib/browser/math/amm.js +28 -4
  18. package/lib/browser/types.d.ts +20 -0
  19. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
  20. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -1
  21. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +245 -44
  22. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +7 -4
  23. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
  24. package/lib/node/accounts/grpcMultiAccountSubscriber.js +115 -19
  25. package/lib/node/adminClient.d.ts +4 -0
  26. package/lib/node/adminClient.d.ts.map +1 -1
  27. package/lib/node/adminClient.js +34 -0
  28. package/lib/node/constants/perpMarkets.d.ts.map +1 -1
  29. package/lib/node/constants/perpMarkets.js +35 -0
  30. package/lib/node/constants/spotMarkets.js +4 -4
  31. package/lib/node/driftClient.d.ts +35 -5
  32. package/lib/node/driftClient.d.ts.map +1 -1
  33. package/lib/node/driftClient.js +41 -14
  34. package/lib/node/events/parse.d.ts +2 -0
  35. package/lib/node/events/parse.d.ts.map +1 -1
  36. package/lib/node/events/parse.js +94 -1
  37. package/lib/node/events/types.d.ts +22 -3
  38. package/lib/node/events/types.d.ts.map +1 -1
  39. package/lib/node/idl/drift.json +105 -6
  40. package/lib/node/math/amm.d.ts +1 -0
  41. package/lib/node/math/amm.d.ts.map +1 -1
  42. package/lib/node/math/amm.js +28 -4
  43. package/lib/node/types.d.ts +20 -0
  44. package/lib/node/types.d.ts.map +1 -1
  45. package/package.json +2 -1
  46. package/scripts/client-test.ts +294 -126
  47. package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +401 -75
  48. package/src/accounts/grpcMultiAccountSubscriber.ts +167 -34
  49. package/src/adminClient.ts +74 -0
  50. package/src/constants/perpMarkets.ts +37 -0
  51. package/src/constants/spotMarkets.ts +4 -4
  52. package/src/driftClient.ts +65 -14
  53. package/src/events/parse.ts +115 -0
  54. package/src/events/types.ts +26 -2
  55. package/src/idl/drift.json +105 -6
  56. package/src/math/amm.ts +52 -8
  57. package/src/types.ts +22 -0
  58. package/tests/events/parseLogsForCuUsage.ts +139 -0
@@ -1,5 +1,5 @@
1
1
  import { Program } from '@coral-xyz/anchor';
2
- import { Context, PublicKey } from '@solana/web3.js';
2
+ import { Commitment, Context, PublicKey } from '@solana/web3.js';
3
3
  import * as Buffer from 'buffer';
4
4
  import bs58 from 'bs58';
5
5
 
@@ -11,7 +11,7 @@ import {
11
11
  SubscribeUpdate,
12
12
  createClient,
13
13
  } from '../isomorphic/grpc';
14
- import { DataAndSlot, GrpcConfigs, ResubOpts } from './types';
14
+ import { BufferAndSlot, DataAndSlot, GrpcConfigs, ResubOpts } from './types';
15
15
 
16
16
  interface AccountInfoLike {
17
17
  owner: PublicKey;
@@ -21,13 +21,32 @@ interface AccountInfoLike {
21
21
  rentEpoch: number;
22
22
  }
23
23
 
24
- export class grpcMultiAccountSubscriber<T> {
24
+ function commitmentLevelToCommitment(
25
+ commitmentLevel: CommitmentLevel
26
+ ): Commitment {
27
+ switch (commitmentLevel) {
28
+ case CommitmentLevel.PROCESSED:
29
+ return 'processed';
30
+ case CommitmentLevel.CONFIRMED:
31
+ return 'confirmed';
32
+ case CommitmentLevel.FINALIZED:
33
+ return 'finalized';
34
+ default:
35
+ return 'confirmed';
36
+ }
37
+ }
38
+
39
+ export class grpcMultiAccountSubscriber<T, U = undefined> {
25
40
  private client: Client;
26
41
  private stream: ClientDuplexStream<SubscribeRequest, SubscribeUpdate>;
27
42
  private commitmentLevel: CommitmentLevel;
28
43
  private program: Program;
29
44
  private accountName: string;
30
- private decodeBufferFn?: (buffer: Buffer, pubkey?: string) => T;
45
+ private decodeBufferFn?: (
46
+ buffer: Buffer,
47
+ pubkey?: string,
48
+ accountProps?: U
49
+ ) => T;
31
50
  private resubOpts?: ResubOpts;
32
51
  private onUnsubscribe?: () => Promise<void>;
33
52
 
@@ -39,10 +58,12 @@ export class grpcMultiAccountSubscriber<T> {
39
58
  private subscribedAccounts = new Set<string>();
40
59
  private onChangeMap = new Map<
41
60
  string,
42
- (data: T, context: Context, buffer: Buffer) => void
61
+ (data: T, context: Context, buffer: Buffer, accountProps: U) => void
43
62
  >();
44
63
 
45
64
  private dataMap = new Map<string, DataAndSlot<T>>();
65
+ private accountPropsMap = new Map<string, U | Array<U>>();
66
+ private bufferMap = new Map<string, BufferAndSlot>();
46
67
 
47
68
  private constructor(
48
69
  client: Client,
@@ -51,7 +72,8 @@ export class grpcMultiAccountSubscriber<T> {
51
72
  program: Program,
52
73
  decodeBuffer?: (buffer: Buffer, pubkey?: string) => T,
53
74
  resubOpts?: ResubOpts,
54
- onUnsubscribe?: () => Promise<void>
75
+ onUnsubscribe?: () => Promise<void>,
76
+ accountPropsMap?: Map<string, U | Array<U>>
55
77
  ) {
56
78
  this.client = client;
57
79
  this.commitmentLevel = commitmentLevel;
@@ -60,17 +82,19 @@ export class grpcMultiAccountSubscriber<T> {
60
82
  this.decodeBufferFn = decodeBuffer;
61
83
  this.resubOpts = resubOpts;
62
84
  this.onUnsubscribe = onUnsubscribe;
85
+ this.accountPropsMap = accountPropsMap;
63
86
  }
64
87
 
65
- public static async create<U>(
88
+ public static async create<T, U = undefined>(
66
89
  grpcConfigs: GrpcConfigs,
67
90
  accountName: string,
68
91
  program: Program,
69
- decodeBuffer?: (buffer: Buffer, pubkey?: string) => U,
92
+ decodeBuffer?: (buffer: Buffer, pubkey?: string, accountProps?: U) => T,
70
93
  resubOpts?: ResubOpts,
71
94
  clientProp?: Client,
72
- onUnsubscribe?: () => Promise<void>
73
- ): Promise<grpcMultiAccountSubscriber<U>> {
95
+ onUnsubscribe?: () => Promise<void>,
96
+ accountPropsMap?: Map<string, U | Array<U>>
97
+ ): Promise<grpcMultiAccountSubscriber<T, U>> {
74
98
  const client = clientProp
75
99
  ? clientProp
76
100
  : await createClient(
@@ -89,12 +113,13 @@ export class grpcMultiAccountSubscriber<T> {
89
113
  program,
90
114
  decodeBuffer,
91
115
  resubOpts,
92
- onUnsubscribe
116
+ onUnsubscribe,
117
+ accountPropsMap
93
118
  );
94
119
  }
95
120
 
96
- setAccountData(accountPubkey: PublicKey, data: T, slot?: number): void {
97
- this.dataMap.set(accountPubkey.toBase58(), { data, slot });
121
+ setAccountData(accountPubkey: string, data: T, slot?: number): void {
122
+ this.dataMap.set(accountPubkey, { data, slot });
98
123
  }
99
124
 
100
125
  getAccountData(accountPubkey: string): DataAndSlot<T> | undefined {
@@ -105,15 +130,87 @@ export class grpcMultiAccountSubscriber<T> {
105
130
  return this.dataMap;
106
131
  }
107
132
 
133
+ async fetch(): Promise<void> {
134
+ try {
135
+ // Chunk account IDs into groups of 100 (getMultipleAccounts limit)
136
+ const chunkSize = 100;
137
+ const chunks: string[][] = [];
138
+ const accountIds = Array.from(this.subscribedAccounts.values());
139
+ for (let i = 0; i < accountIds.length; i += chunkSize) {
140
+ chunks.push(accountIds.slice(i, i + chunkSize));
141
+ }
142
+
143
+ // Process all chunks concurrently
144
+ await Promise.all(
145
+ chunks.map(async (chunk) => {
146
+ const accountAddresses = chunk.map(
147
+ (accountId) => new PublicKey(accountId)
148
+ );
149
+ const rpcResponseAndContext =
150
+ await this.program.provider.connection.getMultipleAccountsInfoAndContext(
151
+ accountAddresses,
152
+ {
153
+ commitment: commitmentLevelToCommitment(this.commitmentLevel),
154
+ }
155
+ );
156
+
157
+ const rpcResponse = rpcResponseAndContext.value;
158
+ const currentSlot = rpcResponseAndContext.context.slot;
159
+
160
+ for (let i = 0; i < chunk.length; i++) {
161
+ const accountId = chunk[i];
162
+ const accountInfo = rpcResponse[i];
163
+ if (accountInfo) {
164
+ const prev = this.bufferMap.get(accountId);
165
+ const newBuffer = accountInfo.data as Buffer;
166
+ if (prev && currentSlot < prev.slot) {
167
+ continue;
168
+ }
169
+ if (
170
+ prev &&
171
+ prev.buffer &&
172
+ newBuffer &&
173
+ newBuffer.equals(prev.buffer)
174
+ ) {
175
+ continue;
176
+ }
177
+ this.bufferMap.set(accountId, {
178
+ buffer: newBuffer,
179
+ slot: currentSlot,
180
+ });
181
+
182
+ const accountDecoded = this.program.coder.accounts.decode(
183
+ this.capitalize(this.accountName),
184
+ newBuffer
185
+ );
186
+ this.setAccountData(accountId, accountDecoded, currentSlot);
187
+ }
188
+ }
189
+ })
190
+ );
191
+ } catch (error) {
192
+ if (this.resubOpts?.logResubMessages) {
193
+ console.log(
194
+ `[${this.accountName}] grpcMultiAccountSubscriber error fetching accounts:`,
195
+ error
196
+ );
197
+ }
198
+ }
199
+ }
200
+
108
201
  async subscribe(
109
202
  accounts: PublicKey[],
110
203
  onChange: (
111
204
  accountId: PublicKey,
112
205
  data: T,
113
206
  context: Context,
114
- buffer: Buffer
207
+ buffer: Buffer,
208
+ accountProps: U
115
209
  ) => void
116
210
  ): Promise<void> {
211
+ if (this.resubOpts?.logResubMessages) {
212
+ console.log(`[${this.accountName}] grpcMultiAccountSubscriber subscribe`);
213
+ }
117
214
  if (this.listenerId != null || this.isUnsubscribing) {
118
215
  return;
119
216
  }
@@ -122,9 +219,10 @@ export class grpcMultiAccountSubscriber<T> {
122
219
  for (const pk of accounts) {
123
220
  const key = pk.toBase58();
124
221
  this.subscribedAccounts.add(key);
125
- this.onChangeMap.set(key, (data, ctx, buffer) =>
126
- onChange(new PublicKey(key), data, ctx, buffer)
127
- );
222
+ this.onChangeMap.set(key, (data, ctx, buffer, accountProps) => {
223
+ this.setAccountData(key, data, ctx.slot);
224
+ onChange(new PublicKey(key), data, ctx, buffer, accountProps);
225
+ });
128
226
  }
129
227
 
130
228
  this.stream =
@@ -159,6 +257,19 @@ export class grpcMultiAccountSubscriber<T> {
159
257
  if (!accountPubkey || !this.subscribedAccounts.has(accountPubkey)) {
160
258
  return;
161
259
  }
260
+
261
+ // Touch resub timer on any incoming account update for subscribed keys
262
+ if (this.resubOpts?.resubTimeoutMs) {
263
+ this.receivingData = true;
264
+ clearTimeout(this.timeoutId);
265
+ this.setTimeout();
266
+ }
267
+
268
+ // Skip processing if we already have data for this account at a newer slot
269
+ const existing = this.dataMap.get(accountPubkey);
270
+ if (existing?.slot !== undefined && existing.slot > slot) {
271
+ return;
272
+ }
162
273
  const accountInfo: AccountInfoLike = {
163
274
  owner: new PublicKey(chunk.account.account.owner),
164
275
  lamports: Number(chunk.account.account.lamports),
@@ -169,23 +280,46 @@ export class grpcMultiAccountSubscriber<T> {
169
280
 
170
281
  const context = { slot } as Context;
171
282
  const buffer = accountInfo.data;
172
- const data = this.decodeBufferFn
173
- ? this.decodeBufferFn(buffer, accountPubkey)
174
- : this.program.account[this.accountName].coder.accounts.decode(
175
- this.capitalize(this.accountName),
176
- buffer
177
- );
178
-
179
- const handler = this.onChangeMap.get(accountPubkey);
180
- if (handler) {
181
- if (this.resubOpts?.resubTimeoutMs) {
182
- this.receivingData = true;
183
- clearTimeout(this.timeoutId);
184
- handler(data, context, buffer);
185
- this.setTimeout();
186
- } else {
187
- handler(data, context, buffer);
283
+
284
+ // Check existing buffer for this account and skip if unchanged or slot regressed
285
+ const prevBuffer = this.bufferMap.get(accountPubkey);
286
+ if (prevBuffer && slot < prevBuffer.slot) {
287
+ return;
288
+ }
289
+ if (
290
+ prevBuffer &&
291
+ prevBuffer.buffer &&
292
+ buffer &&
293
+ buffer.equals(prevBuffer.buffer)
294
+ ) {
295
+ return;
296
+ }
297
+ this.bufferMap.set(accountPubkey, { buffer, slot });
298
+ const accountProps = this.accountPropsMap?.get(accountPubkey);
299
+
300
+ const handleDataBuffer = (
301
+ context: Context,
302
+ buffer: Buffer,
303
+ accountProps: U
304
+ ) => {
305
+ const data = this.decodeBufferFn
306
+ ? this.decodeBufferFn(buffer, accountPubkey, accountProps)
307
+ : this.program.account[this.accountName].coder.accounts.decode(
308
+ this.capitalize(this.accountName),
309
+ buffer
310
+ );
311
+ const handler = this.onChangeMap.get(accountPubkey);
312
+ if (handler) {
313
+ handler(data, context, buffer, accountProps);
314
+ }
315
+ };
316
+
317
+ if (Array.isArray(accountProps)) {
318
+ for (const props of accountProps) {
319
+ handleDataBuffer(context, buffer, props);
188
320
  }
321
+ } else {
322
+ handleDataBuffer(context, buffer, accountProps);
189
323
  }
190
324
  });
191
325
 
@@ -195,7 +329,6 @@ export class grpcMultiAccountSubscriber<T> {
195
329
  this.listenerId = 1;
196
330
  if (this.resubOpts?.resubTimeoutMs) {
197
331
  this.receivingData = true;
198
- this.setTimeout();
199
332
  }
200
333
  resolve();
201
334
  } else {
@@ -1232,6 +1232,46 @@ export class AdminClient extends DriftClient {
1232
1232
  );
1233
1233
  }
1234
1234
 
1235
+ public async updatePerpMarketReferencePriceOffsetDeadbandPct(
1236
+ perpMarketIndex: number,
1237
+ referencePriceOffsetDeadbandPct: number
1238
+ ): Promise<TransactionSignature> {
1239
+ const updatePerpMarketReferencePriceOffsetDeadbandPctIx =
1240
+ await this.getUpdatePerpMarketReferencePriceOffsetDeadbandPctIx(
1241
+ perpMarketIndex,
1242
+ referencePriceOffsetDeadbandPct
1243
+ );
1244
+
1245
+ const tx = await this.buildTransaction(
1246
+ updatePerpMarketReferencePriceOffsetDeadbandPctIx
1247
+ );
1248
+
1249
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1250
+
1251
+ return txSig;
1252
+ }
1253
+
1254
+ public async getUpdatePerpMarketReferencePriceOffsetDeadbandPctIx(
1255
+ perpMarketIndex: number,
1256
+ referencePriceOffsetDeadbandPct: number
1257
+ ): Promise<TransactionInstruction> {
1258
+ return await this.program.instruction.updatePerpMarketReferencePriceOffsetDeadbandPct(
1259
+ referencePriceOffsetDeadbandPct,
1260
+ {
1261
+ accounts: {
1262
+ admin: this.useHotWalletAdmin
1263
+ ? this.wallet.publicKey
1264
+ : this.getStateAccount().admin,
1265
+ state: await this.getStatePublicKey(),
1266
+ perpMarket: await getPerpMarketPublicKey(
1267
+ this.program.programId,
1268
+ perpMarketIndex
1269
+ ),
1270
+ },
1271
+ }
1272
+ );
1273
+ }
1274
+
1235
1275
  public async updatePerpMarketTargetBaseAssetAmountPerLp(
1236
1276
  perpMarketIndex: number,
1237
1277
  targetBaseAssetAmountPerLP: number
@@ -4835,4 +4875,38 @@ export class AdminClient extends DriftClient {
4835
4875
  }
4836
4876
  );
4837
4877
  }
4878
+
4879
+ public async adminDisableUpdatePerpBidAskTwap(
4880
+ authority: PublicKey,
4881
+ disable: boolean
4882
+ ): Promise<TransactionSignature> {
4883
+ const disableBidAskTwapUpdateIx =
4884
+ await this.getAdminDisableUpdatePerpBidAskTwapIx(authority, disable);
4885
+
4886
+ const tx = await this.buildTransaction(disableBidAskTwapUpdateIx);
4887
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
4888
+
4889
+ return txSig;
4890
+ }
4891
+
4892
+ public async getAdminDisableUpdatePerpBidAskTwapIx(
4893
+ authority: PublicKey,
4894
+ disable: boolean
4895
+ ): Promise<TransactionInstruction> {
4896
+ return await this.program.instruction.adminDisableUpdatePerpBidAskTwap(
4897
+ disable,
4898
+ {
4899
+ accounts: {
4900
+ admin: this.useHotWalletAdmin
4901
+ ? this.wallet.publicKey
4902
+ : this.getStateAccount().admin,
4903
+ state: await this.getStatePublicKey(),
4904
+ userStats: getUserStatsAccountPublicKey(
4905
+ this.program.programId,
4906
+ authority
4907
+ ),
4908
+ },
4909
+ }
4910
+ );
4911
+ }
4838
4912
  }
@@ -1351,6 +1351,43 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
1351
1351
  '0xf2b3ab1c49e35e881003c3c0482d18b181a1560b697b844c24c8f85aba1cab95',
1352
1352
  pythLazerId: 2316,
1353
1353
  },
1354
+ {
1355
+ fullName: 'ZCash',
1356
+ category: ['Privacy'],
1357
+ symbol: 'ZEC-PERP',
1358
+ baseAssetSymbol: 'ZEC',
1359
+ marketIndex: 79,
1360
+ oracle: new PublicKey('BXunfRSyiQWJHv88qMvE42mpMpksWEC8Bf13p2msnRms'),
1361
+ launchTs: 1760366017000,
1362
+ oracleSource: OracleSource.PYTH_LAZER,
1363
+ pythFeedId:
1364
+ '0xbe9b59d178f0d6a97ab4c343bff2aa69caa1eaae3e9048a65788c529b125bb24',
1365
+ pythLazerId: 66,
1366
+ },
1367
+ {
1368
+ fullName: 'Mantle',
1369
+ category: ['L1'],
1370
+ symbol: 'MNT-PERP',
1371
+ baseAssetSymbol: 'MNT',
1372
+ marketIndex: 80,
1373
+ oracle: new PublicKey('Gy7cJ4U1nxMA44XXC3hwqkpcxEB1mZTYiwJVkaqZfU7u'),
1374
+ launchTs: 1760366017000,
1375
+ oracleSource: OracleSource.PYTH_LAZER,
1376
+ pythFeedId:
1377
+ '0x4e3037c822d852d79af3ac80e35eb420ee3b870dca49f9344a38ef4773fb0585',
1378
+ pythLazerId: 199,
1379
+ },
1380
+ {
1381
+ fullName: '1KPUMP',
1382
+ category: ['Launchpad'],
1383
+ symbol: '1KPUMP-PERP',
1384
+ baseAssetSymbol: '1KPUMP',
1385
+ marketIndex: 81,
1386
+ oracle: new PublicKey('5r8RWTaRiMgr9Lph3FTUE3sGb1vymhpCrm83Bovjfcps'),
1387
+ launchTs: 1760366017000,
1388
+ oracleSource: OracleSource.PYTH_LAZER_1K,
1389
+ pythLazerId: 1578,
1390
+ },
1354
1391
  ];
1355
1392
 
1356
1393
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -39,8 +39,8 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
39
39
  symbol: 'USDC',
40
40
  marketIndex: 0,
41
41
  poolId: 0,
42
- oracle: new PublicKey('En8hkHLkRe9d9DraYmBTrus518BvmVH448YcvmrFM6Ce'),
43
- oracleSource: OracleSource.PYTH_STABLE_COIN_PULL,
42
+ oracle: new PublicKey('9VCioxmni2gDLv11qufWzT3RDERhQE4iY5Gf7NTfYyAV'),
43
+ oracleSource: OracleSource.PYTH_LAZER_STABLE_COIN,
44
44
  mint: new PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
45
45
  precision: new BN(10).pow(SIX),
46
46
  precisionExp: SIX,
@@ -52,8 +52,8 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
52
52
  symbol: 'SOL',
53
53
  marketIndex: 1,
54
54
  poolId: 0,
55
- oracle: new PublicKey('BAtFj4kQttZRVep3UZS2aZRDixkGYgWsbqTBVDbnSsPF'),
56
- oracleSource: OracleSource.PYTH_PULL,
55
+ oracle: new PublicKey('3m6i4RFWEDw2Ft4tFHPJtYgmpPe21k56M3FHeWYrgGBz'),
56
+ oracleSource: OracleSource.PYTH_LAZER,
57
57
  mint: new PublicKey(WRAPPED_SOL_MINT),
58
58
  precision: LAMPORTS_PRECISION,
59
59
  precisionExp: LAMPORTS_EXP,
@@ -1373,6 +1373,16 @@ export class DriftClient {
1373
1373
  });
1374
1374
  }
1375
1375
 
1376
+ /**
1377
+ * Creates the transaction to add or update an approved builder.
1378
+ * This allows the builder to receive revenue share from referrals.
1379
+ *
1380
+ * @param builder - The public key of the builder to add or update.
1381
+ * @param maxFeeTenthBps - The maximum fee tenth bps to set for the builder.
1382
+ * @param add - Whether to add or update the builder. If the builder already exists, `add = true` will update the `maxFeeTenthBps`, otherwise it will add the builder. If `add = false`, the builder's `maxFeeTenthBps` will be set to 0.
1383
+ * @param txParams - The transaction parameters to use for the transaction.
1384
+ * @returns The transaction to add or update an approved builder.
1385
+ */
1376
1386
  public async changeApprovedBuilder(
1377
1387
  builder: PublicKey,
1378
1388
  maxFeeTenthBps: number,
@@ -1389,6 +1399,15 @@ export class DriftClient {
1389
1399
  return txSig;
1390
1400
  }
1391
1401
 
1402
+ /**
1403
+ * Creates the transaction instruction to add or update an approved builder.
1404
+ * This allows the builder to receive revenue share from referrals.
1405
+ *
1406
+ * @param builder - The public key of the builder to add or update.
1407
+ * @param maxFeeTenthBps - The maximum fee tenth bps to set for the builder.
1408
+ * @param add - Whether to add or update the builder. If the builder already exists, `add = true` will update the `maxFeeTenthBps`, otherwise it will add the builder. If `add = false`, the builder's `maxFeeTenthBps` will be set to 0.
1409
+ * @returns The transaction instruction to add or update an approved builder.
1410
+ */
1392
1411
  public async getChangeApprovedBuilderIx(
1393
1412
  builder: PublicKey,
1394
1413
  maxFeeTenthBps: number,
@@ -4742,11 +4761,19 @@ export class DriftClient {
4742
4761
  orderIds?: number[],
4743
4762
  txParams?: TxParams,
4744
4763
  subAccountId?: number,
4745
- user?: User
4764
+ user?: User,
4765
+ overrides?: {
4766
+ authority?: PublicKey;
4767
+ }
4746
4768
  ): Promise<TransactionSignature> {
4747
4769
  const { txSig } = await this.sendTransaction(
4748
4770
  await this.buildTransaction(
4749
- await this.getCancelOrdersByIdsIx(orderIds, subAccountId, user),
4771
+ await this.getCancelOrdersByIdsIx(
4772
+ orderIds,
4773
+ subAccountId,
4774
+ user,
4775
+ overrides
4776
+ ),
4750
4777
  txParams
4751
4778
  ),
4752
4779
  [],
@@ -4766,7 +4793,10 @@ export class DriftClient {
4766
4793
  public async getCancelOrdersByIdsIx(
4767
4794
  orderIds?: number[],
4768
4795
  subAccountId?: number,
4769
- user?: User
4796
+ user?: User,
4797
+ overrides?: {
4798
+ authority?: PublicKey;
4799
+ }
4770
4800
  ): Promise<TransactionInstruction> {
4771
4801
  const userAccountPubKey =
4772
4802
  user?.userAccountPublicKey ??
@@ -4779,11 +4809,13 @@ export class DriftClient {
4779
4809
  useMarketLastSlotCache: true,
4780
4810
  });
4781
4811
 
4812
+ const authority = overrides?.authority ?? this.wallet.publicKey;
4813
+
4782
4814
  return await this.program.instruction.cancelOrdersByIds(orderIds, {
4783
4815
  accounts: {
4784
4816
  state: await this.getStatePublicKey(),
4785
4817
  user: userAccountPubKey,
4786
- authority: this.wallet.publicKey,
4818
+ authority,
4787
4819
  },
4788
4820
  remainingAccounts,
4789
4821
  });
@@ -4924,7 +4956,10 @@ export class DriftClient {
4924
4956
 
4925
4957
  public async getPlaceOrdersIx(
4926
4958
  params: OptionalOrderParams[],
4927
- subAccountId?: number
4959
+ subAccountId?: number,
4960
+ overrides?: {
4961
+ authority?: PublicKey;
4962
+ }
4928
4963
  ): Promise<TransactionInstruction> {
4929
4964
  const user = await this.getUserAccountPublicKey(subAccountId);
4930
4965
 
@@ -4959,13 +4994,14 @@ export class DriftClient {
4959
4994
  }
4960
4995
 
4961
4996
  const formattedParams = params.map((item) => getOrderParams(item));
4997
+ const authority = overrides?.authority ?? this.wallet.publicKey;
4962
4998
 
4963
4999
  return await this.program.instruction.placeOrders(formattedParams, {
4964
5000
  accounts: {
4965
5001
  state: await this.getStatePublicKey(),
4966
5002
  user,
4967
5003
  userStats: this.getUserStatsAccountPublicKey(),
4968
- authority: this.wallet.publicKey,
5004
+ authority,
4969
5005
  },
4970
5006
  remainingAccounts,
4971
5007
  });
@@ -6669,7 +6705,10 @@ export class DriftClient {
6669
6705
  referrerInfo?: ReferrerInfo,
6670
6706
  successCondition?: PlaceAndTakeOrderSuccessCondition,
6671
6707
  auctionDurationPercentage?: number,
6672
- subAccountId?: number
6708
+ subAccountId?: number,
6709
+ overrides?: {
6710
+ authority?: PublicKey;
6711
+ }
6673
6712
  ): Promise<TransactionInstruction> {
6674
6713
  orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
6675
6714
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
@@ -6737,6 +6776,8 @@ export class DriftClient {
6737
6776
  ((auctionDurationPercentage ?? 100) << 8) | (successCondition ?? 0);
6738
6777
  }
6739
6778
 
6779
+ const authority = overrides?.authority ?? this.wallet.publicKey;
6780
+
6740
6781
  return await this.program.instruction.placeAndTakePerpOrder(
6741
6782
  orderParams,
6742
6783
  optionalParams,
@@ -6745,7 +6786,7 @@ export class DriftClient {
6745
6786
  state: await this.getStatePublicKey(),
6746
6787
  user,
6747
6788
  userStats: userStatsPublicKey,
6748
- authority: this.wallet.publicKey,
6789
+ authority,
6749
6790
  },
6750
6791
  remainingAccounts,
6751
6792
  }
@@ -7608,13 +7649,19 @@ export class DriftClient {
7608
7649
  policy?: number;
7609
7650
  },
7610
7651
  subAccountId?: number,
7611
- userPublicKey?: PublicKey
7652
+ overrides?: {
7653
+ user?: User;
7654
+ authority?: PublicKey;
7655
+ }
7612
7656
  ): Promise<TransactionInstruction> {
7613
- const user =
7614
- userPublicKey ?? (await this.getUserAccountPublicKey(subAccountId));
7657
+ const userPubKey =
7658
+ overrides?.user?.getUserAccountPublicKey() ??
7659
+ (await this.getUserAccountPublicKey(subAccountId));
7660
+ const userAccount =
7661
+ overrides?.user?.getUserAccount() ?? this.getUserAccount(subAccountId);
7615
7662
 
7616
7663
  const remainingAccounts = this.getRemainingAccounts({
7617
- userAccounts: [this.getUserAccount(subAccountId)],
7664
+ userAccounts: [userAccount],
7618
7665
  useMarketLastSlotCache: true,
7619
7666
  });
7620
7667
 
@@ -7635,12 +7682,16 @@ export class DriftClient {
7635
7682
  maxTs: maxTs || null,
7636
7683
  };
7637
7684
 
7685
+ const authority =
7686
+ overrides?.authority ??
7687
+ overrides?.user?.getUserAccount().authority ??
7688
+ this.wallet.publicKey;
7638
7689
  return await this.program.instruction.modifyOrder(orderId, orderParams, {
7639
7690
  accounts: {
7640
7691
  state: await this.getStatePublicKey(),
7641
- user,
7692
+ user: userPubKey,
7642
7693
  userStats: this.getUserStatsAccountPublicKey(),
7643
- authority: this.wallet.publicKey,
7694
+ authority,
7644
7695
  },
7645
7696
  remainingAccounts,
7646
7697
  });