@drift-labs/sdk 2.85.0-beta.4 → 2.85.0-beta.5
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.
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/accounts/bulkAccountLoader.d.ts +3 -3
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +10 -2
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +4 -3
- package/lib/accounts/pollingUserAccountSubscriber.js +7 -6
- package/lib/accounts/testBulkAccountLoader.d.ts +4 -0
- package/lib/accounts/testBulkAccountLoader.js +45 -0
- package/lib/bankrun/bankrunConnection.d.ts +71 -0
- package/lib/bankrun/bankrunConnection.js +285 -0
- package/lib/events/eventSubscriber.js +12 -4
- package/lib/idl/drift.json +28 -8
- package/lib/testClient.js +1 -2
- package/lib/tokenFaucet.d.ts +3 -1
- package/lib/tokenFaucet.js +41 -8
- package/lib/user.js +1 -1
- package/package.json +3 -1
- package/src/accounts/bulkAccountLoader.ts +3 -2
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +16 -3
- package/src/accounts/pollingUserAccountSubscriber.ts +13 -12
- package/src/accounts/testBulkAccountLoader.ts +53 -0
- package/src/bankrun/bankrunConnection.ts +466 -0
- package/src/events/eventSubscriber.ts +5 -0
- package/src/idl/drift.json +28 -8
- package/src/testClient.ts +1 -2
- package/src/tokenFaucet.ts +49 -12
- package/src/user.ts +5 -2
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TransactionConfirmationStatus,
|
|
3
|
+
AccountInfo,
|
|
4
|
+
Keypair,
|
|
5
|
+
PublicKey,
|
|
6
|
+
Transaction,
|
|
7
|
+
RpcResponseAndContext,
|
|
8
|
+
Commitment,
|
|
9
|
+
TransactionSignature,
|
|
10
|
+
SignatureStatusConfig,
|
|
11
|
+
SignatureStatus,
|
|
12
|
+
GetVersionedTransactionConfig,
|
|
13
|
+
GetTransactionConfig,
|
|
14
|
+
VersionedTransaction,
|
|
15
|
+
SimulateTransactionConfig,
|
|
16
|
+
SimulatedTransactionResponse,
|
|
17
|
+
TransactionReturnData,
|
|
18
|
+
TransactionError,
|
|
19
|
+
SignatureResultCallback,
|
|
20
|
+
ClientSubscriptionId,
|
|
21
|
+
Connection as SolanaConnection,
|
|
22
|
+
SystemProgram,
|
|
23
|
+
Blockhash,
|
|
24
|
+
LogsFilter,
|
|
25
|
+
LogsCallback,
|
|
26
|
+
AccountChangeCallback,
|
|
27
|
+
LAMPORTS_PER_SOL,
|
|
28
|
+
} from '@solana/web3.js';
|
|
29
|
+
import {
|
|
30
|
+
ProgramTestContext,
|
|
31
|
+
BanksClient,
|
|
32
|
+
BanksTransactionResultWithMeta,
|
|
33
|
+
Clock,
|
|
34
|
+
} from 'solana-bankrun';
|
|
35
|
+
import { BankrunProvider } from 'anchor-bankrun';
|
|
36
|
+
import bs58 from 'bs58';
|
|
37
|
+
import { BN, Wallet } from '@coral-xyz/anchor';
|
|
38
|
+
import { Account, TOKEN_PROGRAM_ID, unpackAccount } from '@solana/spl-token';
|
|
39
|
+
|
|
40
|
+
export type Connection = SolanaConnection | BankrunConnection;
|
|
41
|
+
|
|
42
|
+
type BankrunTransactionMetaNormalized = {
|
|
43
|
+
logMessages: string[];
|
|
44
|
+
err: TransactionError;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type BankrunTransactionRespose = {
|
|
48
|
+
slot: number;
|
|
49
|
+
meta: BankrunTransactionMetaNormalized;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export class BankrunContextWrapper {
|
|
53
|
+
public readonly connection: BankrunConnection;
|
|
54
|
+
public readonly context: ProgramTestContext;
|
|
55
|
+
public readonly provider: BankrunProvider;
|
|
56
|
+
public readonly commitment: Commitment = 'confirmed';
|
|
57
|
+
|
|
58
|
+
constructor(context: ProgramTestContext) {
|
|
59
|
+
this.context = context;
|
|
60
|
+
this.provider = new BankrunProvider(context);
|
|
61
|
+
this.connection = new BankrunConnection(
|
|
62
|
+
this.context.banksClient,
|
|
63
|
+
this.context
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async sendTransaction(
|
|
68
|
+
tx: Transaction,
|
|
69
|
+
additionalSigners?: Keypair[]
|
|
70
|
+
): Promise<TransactionSignature> {
|
|
71
|
+
tx.recentBlockhash = (await this.getLatestBlockhash()).toString();
|
|
72
|
+
tx.feePayer = this.context.payer.publicKey;
|
|
73
|
+
if (!additionalSigners) {
|
|
74
|
+
additionalSigners = [];
|
|
75
|
+
}
|
|
76
|
+
tx.sign(this.context.payer, ...additionalSigners);
|
|
77
|
+
return await this.connection.sendTransaction(tx);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async getMinimumBalanceForRentExemption(_: number): Promise<number> {
|
|
81
|
+
return 10 * LAMPORTS_PER_SOL;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async fundKeypair(
|
|
85
|
+
keypair: Keypair | Wallet,
|
|
86
|
+
lamports: number | bigint
|
|
87
|
+
): Promise<TransactionSignature> {
|
|
88
|
+
const ixs = [
|
|
89
|
+
SystemProgram.transfer({
|
|
90
|
+
fromPubkey: this.context.payer.publicKey,
|
|
91
|
+
toPubkey: keypair.publicKey,
|
|
92
|
+
lamports,
|
|
93
|
+
}),
|
|
94
|
+
];
|
|
95
|
+
const tx = new Transaction().add(...ixs);
|
|
96
|
+
return await this.sendTransaction(tx);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getLatestBlockhash(): Promise<Blockhash> {
|
|
100
|
+
const blockhash = await this.connection.getLatestBlockhash('finalized');
|
|
101
|
+
|
|
102
|
+
return blockhash.blockhash;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
printTxLogs(signature: string): void {
|
|
106
|
+
this.connection.printTxLogs(signature);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async moveTimeForward(increment: number): Promise<void> {
|
|
110
|
+
const currentClock = await this.context.banksClient.getClock();
|
|
111
|
+
const newUnixTimestamp = currentClock.unixTimestamp + BigInt(increment);
|
|
112
|
+
const newClock = new Clock(
|
|
113
|
+
currentClock.slot,
|
|
114
|
+
currentClock.epochStartTimestamp,
|
|
115
|
+
currentClock.epoch,
|
|
116
|
+
currentClock.leaderScheduleEpoch,
|
|
117
|
+
newUnixTimestamp
|
|
118
|
+
);
|
|
119
|
+
await this.context.setClock(newClock);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export class BankrunConnection {
|
|
124
|
+
private readonly _banksClient: BanksClient;
|
|
125
|
+
private readonly context: ProgramTestContext;
|
|
126
|
+
private transactionToMeta: Map<
|
|
127
|
+
TransactionSignature,
|
|
128
|
+
BanksTransactionResultWithMeta
|
|
129
|
+
> = new Map();
|
|
130
|
+
private clock: Clock;
|
|
131
|
+
|
|
132
|
+
private nextClientSubscriptionId = 0;
|
|
133
|
+
private onLogCallbacks = new Map<number, LogsCallback>();
|
|
134
|
+
private onAccountChangeCallbacks = new Map<
|
|
135
|
+
number,
|
|
136
|
+
[PublicKey, AccountChangeCallback]
|
|
137
|
+
>();
|
|
138
|
+
|
|
139
|
+
constructor(banksClient: BanksClient, context: ProgramTestContext) {
|
|
140
|
+
this._banksClient = banksClient;
|
|
141
|
+
this.context = context;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
getSlot(): Promise<bigint> {
|
|
145
|
+
return this._banksClient.getSlot();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
toConnection(): SolanaConnection {
|
|
149
|
+
return this as unknown as SolanaConnection;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async getTokenAccount(publicKey: PublicKey): Promise<Account> {
|
|
153
|
+
const info = await this.getAccountInfo(publicKey);
|
|
154
|
+
return unpackAccount(publicKey, info, TOKEN_PROGRAM_ID);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async getMultipleAccountsInfo(
|
|
158
|
+
publicKeys: PublicKey[],
|
|
159
|
+
_commitmentOrConfig?: Commitment
|
|
160
|
+
): Promise<AccountInfo<Buffer>[]> {
|
|
161
|
+
const accountInfos = [];
|
|
162
|
+
|
|
163
|
+
for (const publicKey of publicKeys) {
|
|
164
|
+
const accountInfo = await this.getAccountInfo(publicKey);
|
|
165
|
+
accountInfos.push(accountInfo);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return accountInfos;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async getAccountInfo(
|
|
172
|
+
publicKey: PublicKey
|
|
173
|
+
): Promise<null | AccountInfo<Buffer>> {
|
|
174
|
+
const parsedAccountInfo = await this.getParsedAccountInfo(publicKey);
|
|
175
|
+
return parsedAccountInfo ? parsedAccountInfo.value : null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async getAccountInfoAndContext(
|
|
179
|
+
publicKey: PublicKey,
|
|
180
|
+
_commitment?: Commitment
|
|
181
|
+
): Promise<RpcResponseAndContext<null | AccountInfo<Buffer>>> {
|
|
182
|
+
return await this.getParsedAccountInfo(publicKey);
|
|
183
|
+
}
|
|
184
|
+
async sendRawTransaction(
|
|
185
|
+
rawTransaction: Buffer | Uint8Array | Array<number>,
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
187
|
+
_options?: any
|
|
188
|
+
): Promise<TransactionSignature> {
|
|
189
|
+
const tx = Transaction.from(rawTransaction);
|
|
190
|
+
const signature = await this.sendTransaction(tx);
|
|
191
|
+
return signature;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async sendTransaction(tx: Transaction): Promise<TransactionSignature> {
|
|
195
|
+
const banksTransactionMeta = await this._banksClient.tryProcessTransaction(
|
|
196
|
+
tx
|
|
197
|
+
);
|
|
198
|
+
if (banksTransactionMeta.result) {
|
|
199
|
+
throw new Error(banksTransactionMeta.result);
|
|
200
|
+
}
|
|
201
|
+
const signature = bs58.encode(tx.signatures[0].signature);
|
|
202
|
+
this.transactionToMeta.set(signature, banksTransactionMeta);
|
|
203
|
+
let finalizedCount = 0;
|
|
204
|
+
while (finalizedCount < 10) {
|
|
205
|
+
const signatureStatus = (await this.getSignatureStatus(signature)).value
|
|
206
|
+
.confirmationStatus;
|
|
207
|
+
if (signatureStatus.toString() == '"finalized"') {
|
|
208
|
+
finalizedCount += 1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// update the clock slot/timestamp
|
|
213
|
+
// sometimes race condition causes failures so we retry
|
|
214
|
+
try {
|
|
215
|
+
await this.updateSlotAndClock();
|
|
216
|
+
} catch (e) {
|
|
217
|
+
await this.updateSlotAndClock();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (this.onLogCallbacks.size > 0) {
|
|
221
|
+
const transaction = await this.getTransaction(signature);
|
|
222
|
+
|
|
223
|
+
const context = { slot: transaction.slot };
|
|
224
|
+
const logs = {
|
|
225
|
+
logs: transaction.meta.logMessages,
|
|
226
|
+
err: transaction.meta.err,
|
|
227
|
+
signature,
|
|
228
|
+
};
|
|
229
|
+
for (const logCallback of this.onLogCallbacks.values()) {
|
|
230
|
+
logCallback(logs, context);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
for (const [
|
|
235
|
+
publicKey,
|
|
236
|
+
callback,
|
|
237
|
+
] of this.onAccountChangeCallbacks.values()) {
|
|
238
|
+
const accountInfo = await this.getParsedAccountInfo(publicKey);
|
|
239
|
+
callback(accountInfo.value, accountInfo.context);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return signature;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private async updateSlotAndClock() {
|
|
246
|
+
const currentSlot = await this.getSlot();
|
|
247
|
+
const nextSlot = currentSlot + BigInt(1);
|
|
248
|
+
this.context.warpToSlot(nextSlot);
|
|
249
|
+
const currentClock = await this._banksClient.getClock();
|
|
250
|
+
const newClock = new Clock(
|
|
251
|
+
nextSlot,
|
|
252
|
+
currentClock.epochStartTimestamp,
|
|
253
|
+
currentClock.epoch,
|
|
254
|
+
currentClock.leaderScheduleEpoch,
|
|
255
|
+
currentClock.unixTimestamp + BigInt(1)
|
|
256
|
+
);
|
|
257
|
+
this.context.setClock(newClock);
|
|
258
|
+
this.clock = newClock;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
getTime(): number {
|
|
262
|
+
return Number(this.clock.unixTimestamp);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async getParsedAccountInfo(
|
|
266
|
+
publicKey: PublicKey
|
|
267
|
+
): Promise<RpcResponseAndContext<AccountInfo<Buffer>>> {
|
|
268
|
+
const accountInfoBytes = await this._banksClient.getAccount(publicKey);
|
|
269
|
+
if (accountInfoBytes === null) {
|
|
270
|
+
return {
|
|
271
|
+
context: { slot: Number(await this._banksClient.getSlot()) },
|
|
272
|
+
value: null,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
accountInfoBytes.data = Buffer.from(accountInfoBytes.data);
|
|
276
|
+
const accountInfoBuffer = accountInfoBytes as AccountInfo<Buffer>;
|
|
277
|
+
return {
|
|
278
|
+
context: { slot: Number(await this._banksClient.getSlot()) },
|
|
279
|
+
value: accountInfoBuffer,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async getLatestBlockhash(commitment?: Commitment): Promise<
|
|
284
|
+
Readonly<{
|
|
285
|
+
blockhash: string;
|
|
286
|
+
lastValidBlockHeight: number;
|
|
287
|
+
}>
|
|
288
|
+
> {
|
|
289
|
+
const blockhashAndBlockheight = await this._banksClient.getLatestBlockhash(
|
|
290
|
+
commitment
|
|
291
|
+
);
|
|
292
|
+
return {
|
|
293
|
+
blockhash: blockhashAndBlockheight[0],
|
|
294
|
+
lastValidBlockHeight: Number(blockhashAndBlockheight[1]),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async getSignatureStatus(
|
|
299
|
+
signature: string,
|
|
300
|
+
_config?: SignatureStatusConfig
|
|
301
|
+
): Promise<RpcResponseAndContext<null | SignatureStatus>> {
|
|
302
|
+
const transactionStatus = await this._banksClient.getTransactionStatus(
|
|
303
|
+
signature
|
|
304
|
+
);
|
|
305
|
+
if (transactionStatus === null) {
|
|
306
|
+
return {
|
|
307
|
+
context: { slot: Number(await this._banksClient.getSlot()) },
|
|
308
|
+
value: null,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
context: { slot: Number(await this._banksClient.getSlot()) },
|
|
313
|
+
value: {
|
|
314
|
+
slot: Number(transactionStatus.slot),
|
|
315
|
+
confirmations: Number(transactionStatus.confirmations),
|
|
316
|
+
err: transactionStatus.err,
|
|
317
|
+
confirmationStatus:
|
|
318
|
+
transactionStatus.confirmationStatus as TransactionConfirmationStatus,
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* There's really no direct equivalent to getTransaction exposed by SolanaProgramTest, so we do the best that we can here - it's a little hacky.
|
|
325
|
+
*/
|
|
326
|
+
async getTransaction(
|
|
327
|
+
signature: string,
|
|
328
|
+
_rawConfig?: GetTransactionConfig | GetVersionedTransactionConfig
|
|
329
|
+
): Promise<BankrunTransactionRespose | null> {
|
|
330
|
+
const txMeta = this.transactionToMeta.get(
|
|
331
|
+
signature as TransactionSignature
|
|
332
|
+
);
|
|
333
|
+
if (txMeta === undefined) {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
const transactionStatus = await this._banksClient.getTransactionStatus(
|
|
337
|
+
signature
|
|
338
|
+
);
|
|
339
|
+
const meta: BankrunTransactionMetaNormalized = {
|
|
340
|
+
logMessages: txMeta.meta.logMessages,
|
|
341
|
+
err: txMeta.result,
|
|
342
|
+
};
|
|
343
|
+
return {
|
|
344
|
+
slot: Number(transactionStatus.slot),
|
|
345
|
+
meta,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
findComputeUnitConsumption(signature: string): bigint {
|
|
350
|
+
const txMeta = this.transactionToMeta.get(
|
|
351
|
+
signature as TransactionSignature
|
|
352
|
+
);
|
|
353
|
+
if (txMeta === undefined) {
|
|
354
|
+
throw new Error('Transaction not found');
|
|
355
|
+
}
|
|
356
|
+
return txMeta.meta.computeUnitsConsumed;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
printTxLogs(signature: string): void {
|
|
360
|
+
const txMeta = this.transactionToMeta.get(
|
|
361
|
+
signature as TransactionSignature
|
|
362
|
+
);
|
|
363
|
+
if (txMeta === undefined) {
|
|
364
|
+
throw new Error('Transaction not found');
|
|
365
|
+
}
|
|
366
|
+
console.log(txMeta.meta.logMessages);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
async simulateTransaction(
|
|
370
|
+
transaction: Transaction | VersionedTransaction,
|
|
371
|
+
_config?: SimulateTransactionConfig
|
|
372
|
+
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
|
|
373
|
+
const simulationResult = await this._banksClient.simulateTransaction(
|
|
374
|
+
transaction
|
|
375
|
+
);
|
|
376
|
+
const returnDataProgramId =
|
|
377
|
+
simulationResult.meta?.returnData?.programId.toBase58();
|
|
378
|
+
const returnDataNormalized = Buffer.from(
|
|
379
|
+
simulationResult.meta?.returnData?.data
|
|
380
|
+
).toString('base64');
|
|
381
|
+
const returnData: TransactionReturnData = {
|
|
382
|
+
programId: returnDataProgramId,
|
|
383
|
+
data: [returnDataNormalized, 'base64'],
|
|
384
|
+
};
|
|
385
|
+
return {
|
|
386
|
+
context: { slot: Number(await this._banksClient.getSlot()) },
|
|
387
|
+
value: {
|
|
388
|
+
err: simulationResult.result,
|
|
389
|
+
logs: simulationResult.meta.logMessages,
|
|
390
|
+
accounts: undefined,
|
|
391
|
+
unitsConsumed: Number(simulationResult.meta.computeUnitsConsumed),
|
|
392
|
+
returnData,
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
onSignature(
|
|
398
|
+
signature: string,
|
|
399
|
+
callback: SignatureResultCallback,
|
|
400
|
+
commitment?: Commitment
|
|
401
|
+
): ClientSubscriptionId {
|
|
402
|
+
const txMeta = this.transactionToMeta.get(
|
|
403
|
+
signature as TransactionSignature
|
|
404
|
+
);
|
|
405
|
+
this._banksClient.getSlot(commitment).then((slot) => {
|
|
406
|
+
if (txMeta) {
|
|
407
|
+
callback({ err: txMeta.result }, { slot: Number(slot) });
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
return 0;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async removeSignatureListener(_clientSubscriptionId: number): Promise<void> {
|
|
414
|
+
// Nothing actually has to happen here! Pretty cool, huh?
|
|
415
|
+
// This function signature only exists to match the web3js interface
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
onLogs(
|
|
419
|
+
filter: LogsFilter,
|
|
420
|
+
callback: LogsCallback,
|
|
421
|
+
_commitment?: Commitment
|
|
422
|
+
): ClientSubscriptionId {
|
|
423
|
+
const subscriptId = this.nextClientSubscriptionId;
|
|
424
|
+
|
|
425
|
+
this.onLogCallbacks.set(subscriptId, callback);
|
|
426
|
+
|
|
427
|
+
this.nextClientSubscriptionId += 1;
|
|
428
|
+
|
|
429
|
+
return subscriptId;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
async removeOnLogsListener(
|
|
433
|
+
clientSubscriptionId: ClientSubscriptionId
|
|
434
|
+
): Promise<void> {
|
|
435
|
+
this.onLogCallbacks.delete(clientSubscriptionId);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
onAccountChange(
|
|
439
|
+
publicKey: PublicKey,
|
|
440
|
+
callback: AccountChangeCallback,
|
|
441
|
+
// @ts-ignore
|
|
442
|
+
_commitment?: Commitment
|
|
443
|
+
): ClientSubscriptionId {
|
|
444
|
+
const subscriptId = this.nextClientSubscriptionId;
|
|
445
|
+
|
|
446
|
+
this.onAccountChangeCallbacks.set(subscriptId, [publicKey, callback]);
|
|
447
|
+
|
|
448
|
+
this.nextClientSubscriptionId += 1;
|
|
449
|
+
|
|
450
|
+
return subscriptId;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async removeAccountChangeListener(
|
|
454
|
+
clientSubscriptionId: ClientSubscriptionId
|
|
455
|
+
): Promise<void> {
|
|
456
|
+
this.onAccountChangeCallbacks.delete(clientSubscriptionId);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async getMinimumBalanceForRentExemption(_: number): Promise<number> {
|
|
460
|
+
return 10 * LAMPORTS_PER_SOL;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export function asBN(value: number | bigint): BN {
|
|
465
|
+
return new BN(Number(value));
|
|
466
|
+
}
|
|
@@ -45,6 +45,7 @@ export class EventSubscriber {
|
|
|
45
45
|
|
|
46
46
|
if (this.options.logProviderConfig.type === 'websocket') {
|
|
47
47
|
this.logProvider = new WebSocketLogProvider(
|
|
48
|
+
// @ts-ignore
|
|
48
49
|
this.connection,
|
|
49
50
|
this.address,
|
|
50
51
|
this.options.commitment,
|
|
@@ -52,6 +53,7 @@ export class EventSubscriber {
|
|
|
52
53
|
);
|
|
53
54
|
} else {
|
|
54
55
|
this.logProvider = new PollingLogProvider(
|
|
56
|
+
// @ts-ignore
|
|
55
57
|
this.connection,
|
|
56
58
|
this.address,
|
|
57
59
|
options.commitment,
|
|
@@ -101,6 +103,7 @@ export class EventSubscriber {
|
|
|
101
103
|
this.logProvider.eventEmitter.removeAllListeners('reconnect');
|
|
102
104
|
this.unsubscribe().then(() => {
|
|
103
105
|
this.logProvider = new PollingLogProvider(
|
|
106
|
+
// @ts-ignore
|
|
104
107
|
this.connection,
|
|
105
108
|
this.address,
|
|
106
109
|
this.options.commitment,
|
|
@@ -148,6 +151,7 @@ export class EventSubscriber {
|
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
const wrappedEvents = this.parseEventsFromLogs(txSig, slot, logs);
|
|
154
|
+
|
|
151
155
|
for (const wrappedEvent of wrappedEvents) {
|
|
152
156
|
this.eventListMap.get(wrappedEvent.eventType).insert(wrappedEvent);
|
|
153
157
|
}
|
|
@@ -188,6 +192,7 @@ export class EventSubscriber {
|
|
|
188
192
|
const untilTx: TransactionSignature = this.options.untilTx;
|
|
189
193
|
while (txFetched < this.options.maxTx) {
|
|
190
194
|
const response = await fetchLogs(
|
|
195
|
+
// @ts-ignore
|
|
191
196
|
this.connection,
|
|
192
197
|
this.address,
|
|
193
198
|
this.options.commitment === 'finalized' ? 'finalized' : 'confirmed',
|
package/src/idl/drift.json
CHANGED
|
@@ -3934,6 +3934,12 @@
|
|
|
3934
3934
|
{
|
|
3935
3935
|
"name": "maxBorrowRate",
|
|
3936
3936
|
"type": "u32"
|
|
3937
|
+
},
|
|
3938
|
+
{
|
|
3939
|
+
"name": "minBorrowRate",
|
|
3940
|
+
"type": {
|
|
3941
|
+
"option": "u8"
|
|
3942
|
+
}
|
|
3937
3943
|
}
|
|
3938
3944
|
]
|
|
3939
3945
|
},
|
|
@@ -6198,13 +6204,13 @@
|
|
|
6198
6204
|
"type": "i16"
|
|
6199
6205
|
},
|
|
6200
6206
|
{
|
|
6201
|
-
"name": "
|
|
6202
|
-
"
|
|
6203
|
-
"
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6207
|
+
"name": "maxTokenBorrowsFraction",
|
|
6208
|
+
"docs": [
|
|
6209
|
+
"What fraction of max_token_deposits",
|
|
6210
|
+
"disabled when 0, 1 => 1/10000 => .01% of max_token_deposits",
|
|
6211
|
+
"precision: X/10000"
|
|
6212
|
+
],
|
|
6213
|
+
"type": "u16"
|
|
6208
6214
|
},
|
|
6209
6215
|
{
|
|
6210
6216
|
"name": "flashLoanAmount",
|
|
@@ -6240,12 +6246,21 @@
|
|
|
6240
6246
|
],
|
|
6241
6247
|
"type": "u64"
|
|
6242
6248
|
},
|
|
6249
|
+
{
|
|
6250
|
+
"name": "minBorrowRate",
|
|
6251
|
+
"docs": [
|
|
6252
|
+
"The min borrow rate for this market when the market regardless of utilization",
|
|
6253
|
+
"1 => 1/200 => .5%",
|
|
6254
|
+
"precision: X/200"
|
|
6255
|
+
],
|
|
6256
|
+
"type": "u8"
|
|
6257
|
+
},
|
|
6243
6258
|
{
|
|
6244
6259
|
"name": "padding",
|
|
6245
6260
|
"type": {
|
|
6246
6261
|
"array": [
|
|
6247
6262
|
"u8",
|
|
6248
|
-
|
|
6263
|
+
47
|
|
6249
6264
|
]
|
|
6250
6265
|
}
|
|
6251
6266
|
}
|
|
@@ -12009,6 +12024,11 @@
|
|
|
12009
12024
|
"code": 6267,
|
|
12010
12025
|
"name": "UnableToParsePullOracleMessage",
|
|
12011
12026
|
"msg": "Unable to parse pull oracle message"
|
|
12027
|
+
},
|
|
12028
|
+
{
|
|
12029
|
+
"code": 6268,
|
|
12030
|
+
"name": "MaxBorrows",
|
|
12031
|
+
"msg": "Can not borow more than max borrows"
|
|
12012
12032
|
}
|
|
12013
12033
|
]
|
|
12014
12034
|
}
|
package/src/testClient.ts
CHANGED
|
@@ -10,8 +10,6 @@ export class TestClient extends AdminClient {
|
|
|
10
10
|
throw new Error('Test client must be polling');
|
|
11
11
|
}
|
|
12
12
|
super(config);
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
this.txHandler.blockhashCommitment = 'recent';
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
async sendTransaction(
|
|
@@ -30,6 +28,7 @@ export class TestClient extends AdminClient {
|
|
|
30
28
|
let lastFetchedSlot = (
|
|
31
29
|
this.accountSubscriber as PollingDriftClientAccountSubscriber
|
|
32
30
|
).accountLoader.mostRecentSlot;
|
|
31
|
+
await this.fetchAccounts();
|
|
33
32
|
while (lastFetchedSlot < slot) {
|
|
34
33
|
await this.fetchAccounts();
|
|
35
34
|
lastFetchedSlot = (
|