@drift-labs/sdk 2.75.0-beta.1 → 2.75.0-beta.2
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/lib/adminClient.d.ts +72 -0
- package/lib/adminClient.js +414 -184
- package/lib/driftClient.d.ts +2 -2
- package/lib/driftClient.js +11 -7
- package/lib/idl/drift.json +5 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/tx/baseTxSender.d.ts +1 -1
- package/lib/tx/baseTxSender.js +5 -4
- package/lib/tx/fastSingleTxSender.d.ts +1 -1
- package/lib/tx/fastSingleTxSender.js +2 -13
- package/lib/tx/whileValidTxSender.d.ts +35 -0
- package/lib/tx/whileValidTxSender.js +138 -0
- package/package.json +1 -1
- package/src/adminClient.ts +1509 -826
- package/src/driftClient.ts +14 -9
- package/src/idl/drift.json +5 -1
- package/src/index.ts +1 -0
- package/src/tx/baseTxSender.ts +12 -4
- package/src/tx/fastSingleTxSender.ts +3 -17
- package/src/tx/whileValidTxSender.ts +215 -0
package/src/driftClient.ts
CHANGED
|
@@ -3483,7 +3483,7 @@ export class DriftClient {
|
|
|
3483
3483
|
fulfillmentConfig?:
|
|
3484
3484
|
| SerumV3FulfillmentConfigAccount
|
|
3485
3485
|
| PhoenixV1FulfillmentConfigAccount,
|
|
3486
|
-
makerInfo?: MakerInfo,
|
|
3486
|
+
makerInfo?: MakerInfo | MakerInfo[],
|
|
3487
3487
|
referrerInfo?: ReferrerInfo,
|
|
3488
3488
|
txParams?: TxParams
|
|
3489
3489
|
): Promise<TransactionSignature> {
|
|
@@ -3512,7 +3512,7 @@ export class DriftClient {
|
|
|
3512
3512
|
fulfillmentConfig?:
|
|
3513
3513
|
| SerumV3FulfillmentConfigAccount
|
|
3514
3514
|
| PhoenixV1FulfillmentConfigAccount,
|
|
3515
|
-
makerInfo?: MakerInfo,
|
|
3515
|
+
makerInfo?: MakerInfo | MakerInfo[],
|
|
3516
3516
|
referrerInfo?: ReferrerInfo,
|
|
3517
3517
|
fillerPublicKey?: PublicKey
|
|
3518
3518
|
): Promise<TransactionInstruction> {
|
|
@@ -3530,23 +3530,29 @@ export class DriftClient {
|
|
|
3530
3530
|
(order) => order.orderId === userAccount.nextOrderId - 1
|
|
3531
3531
|
).marketIndex;
|
|
3532
3532
|
|
|
3533
|
+
makerInfo = Array.isArray(makerInfo)
|
|
3534
|
+
? makerInfo
|
|
3535
|
+
: makerInfo
|
|
3536
|
+
? [makerInfo]
|
|
3537
|
+
: [];
|
|
3538
|
+
|
|
3533
3539
|
const userAccounts = [userAccount];
|
|
3534
|
-
|
|
3535
|
-
userAccounts.push(
|
|
3540
|
+
for (const maker of makerInfo) {
|
|
3541
|
+
userAccounts.push(maker.makerUserAccount);
|
|
3536
3542
|
}
|
|
3537
3543
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3538
3544
|
userAccounts,
|
|
3539
3545
|
writableSpotMarketIndexes: [marketIndex, QUOTE_SPOT_MARKET_INDEX],
|
|
3540
3546
|
});
|
|
3541
3547
|
|
|
3542
|
-
|
|
3548
|
+
for (const maker of makerInfo) {
|
|
3543
3549
|
remainingAccounts.push({
|
|
3544
|
-
pubkey:
|
|
3550
|
+
pubkey: maker.maker,
|
|
3545
3551
|
isWritable: true,
|
|
3546
3552
|
isSigner: false,
|
|
3547
3553
|
});
|
|
3548
3554
|
remainingAccounts.push({
|
|
3549
|
-
pubkey:
|
|
3555
|
+
pubkey: maker.makerStats,
|
|
3550
3556
|
isWritable: true,
|
|
3551
3557
|
isSigner: false,
|
|
3552
3558
|
});
|
|
@@ -3566,7 +3572,6 @@ export class DriftClient {
|
|
|
3566
3572
|
}
|
|
3567
3573
|
|
|
3568
3574
|
const orderId = order.orderId;
|
|
3569
|
-
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
3570
3575
|
|
|
3571
3576
|
this.addSpotFulfillmentAccounts(
|
|
3572
3577
|
marketIndex,
|
|
@@ -3577,7 +3582,7 @@ export class DriftClient {
|
|
|
3577
3582
|
return await this.program.instruction.fillSpotOrder(
|
|
3578
3583
|
orderId,
|
|
3579
3584
|
fulfillmentConfig ? fulfillmentConfig.fulfillmentType : null,
|
|
3580
|
-
|
|
3585
|
+
null,
|
|
3581
3586
|
{
|
|
3582
3587
|
accounts: {
|
|
3583
3588
|
state: await this.getStatePublicKey(),
|
package/src/idl/drift.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * from './priorityFee';
|
|
|
74
74
|
export * from './phoenix/phoenixFulfillmentConfigMap';
|
|
75
75
|
export * from './tx/fastSingleTxSender';
|
|
76
76
|
export * from './tx/retryTxSender';
|
|
77
|
+
export * from './tx/whileValidTxSender';
|
|
77
78
|
export * from './tx/priorityFeeCalculator';
|
|
78
79
|
export * from './tx/types';
|
|
79
80
|
export * from './util/computeUnits';
|
package/src/tx/baseTxSender.ts
CHANGED
|
@@ -76,9 +76,12 @@ export abstract class BaseTxSender implements TxSender {
|
|
|
76
76
|
opts = this.opts;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const signedTx =
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
const signedTx = await this.prepareTx(
|
|
80
|
+
tx,
|
|
81
|
+
additionalSigners,
|
|
82
|
+
opts,
|
|
83
|
+
preSigned
|
|
84
|
+
);
|
|
82
85
|
|
|
83
86
|
if (extraConfirmationOptions?.onSignedCb) {
|
|
84
87
|
extraConfirmationOptions.onSignedCb();
|
|
@@ -90,8 +93,13 @@ export abstract class BaseTxSender implements TxSender {
|
|
|
90
93
|
async prepareTx(
|
|
91
94
|
tx: Transaction,
|
|
92
95
|
additionalSigners: Array<Signer>,
|
|
93
|
-
opts: ConfirmOptions
|
|
96
|
+
opts: ConfirmOptions,
|
|
97
|
+
preSigned?: boolean
|
|
94
98
|
): Promise<Transaction> {
|
|
99
|
+
if (preSigned) {
|
|
100
|
+
return tx;
|
|
101
|
+
}
|
|
102
|
+
|
|
95
103
|
tx.feePayer = this.wallet.publicKey;
|
|
96
104
|
tx.recentBlockhash = (
|
|
97
105
|
await this.connection.getLatestBlockhash(opts.preflightCommitment)
|
|
@@ -85,24 +85,10 @@ export class FastSingleTxSender extends BaseTxSender {
|
|
|
85
85
|
async prepareTx(
|
|
86
86
|
tx: Transaction,
|
|
87
87
|
additionalSigners: Array<Signer>,
|
|
88
|
-
_opts: ConfirmOptions
|
|
88
|
+
_opts: ConfirmOptions,
|
|
89
|
+
preSigned?: boolean
|
|
89
90
|
): Promise<Transaction> {
|
|
90
|
-
tx
|
|
91
|
-
|
|
92
|
-
tx.recentBlockhash =
|
|
93
|
-
this.recentBlockhash ??
|
|
94
|
-
(await this.connection.getLatestBlockhash(this.blockhashCommitment))
|
|
95
|
-
.blockhash;
|
|
96
|
-
|
|
97
|
-
additionalSigners
|
|
98
|
-
.filter((s): s is Signer => s !== undefined)
|
|
99
|
-
.forEach((kp) => {
|
|
100
|
-
tx.partialSign(kp);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const signedTx = await this.wallet.signTransaction(tx);
|
|
104
|
-
|
|
105
|
-
return signedTx;
|
|
91
|
+
return super.prepareTx(tx, additionalSigners, _opts, preSigned);
|
|
106
92
|
}
|
|
107
93
|
|
|
108
94
|
async getVersionedTransaction(
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { ExtraConfirmationOptions, TxSigAndSlot } from './types';
|
|
2
|
+
import {
|
|
3
|
+
AddressLookupTableAccount,
|
|
4
|
+
ConfirmOptions,
|
|
5
|
+
Connection,
|
|
6
|
+
Signer,
|
|
7
|
+
Transaction,
|
|
8
|
+
TransactionInstruction,
|
|
9
|
+
TransactionMessage,
|
|
10
|
+
VersionedTransaction,
|
|
11
|
+
} from '@solana/web3.js';
|
|
12
|
+
import { AnchorProvider } from '@coral-xyz/anchor';
|
|
13
|
+
import { IWallet } from '../types';
|
|
14
|
+
import { BaseTxSender } from './baseTxSender';
|
|
15
|
+
import bs58 from 'bs58';
|
|
16
|
+
|
|
17
|
+
const DEFAULT_RETRY = 8000;
|
|
18
|
+
|
|
19
|
+
type ResolveReference = {
|
|
20
|
+
resolve?: () => void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export class WhileValidTxSender extends BaseTxSender {
|
|
24
|
+
connection: Connection;
|
|
25
|
+
wallet: IWallet;
|
|
26
|
+
opts: ConfirmOptions;
|
|
27
|
+
timeout: number;
|
|
28
|
+
retrySleep: number;
|
|
29
|
+
additionalConnections: Connection[];
|
|
30
|
+
timoutCount = 0;
|
|
31
|
+
untilValid = new Map<
|
|
32
|
+
string,
|
|
33
|
+
{ blockhash: string; lastValidBlockHeight: number }
|
|
34
|
+
>();
|
|
35
|
+
|
|
36
|
+
public constructor({
|
|
37
|
+
connection,
|
|
38
|
+
wallet,
|
|
39
|
+
opts = AnchorProvider.defaultOptions(),
|
|
40
|
+
retrySleep = DEFAULT_RETRY,
|
|
41
|
+
additionalConnections = new Array<Connection>(),
|
|
42
|
+
additionalTxSenderCallbacks = [],
|
|
43
|
+
}: {
|
|
44
|
+
connection: Connection;
|
|
45
|
+
wallet: IWallet;
|
|
46
|
+
opts?: ConfirmOptions;
|
|
47
|
+
retrySleep?: number;
|
|
48
|
+
additionalConnections?;
|
|
49
|
+
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
50
|
+
}) {
|
|
51
|
+
super({
|
|
52
|
+
connection,
|
|
53
|
+
wallet,
|
|
54
|
+
opts,
|
|
55
|
+
additionalConnections,
|
|
56
|
+
additionalTxSenderCallbacks,
|
|
57
|
+
});
|
|
58
|
+
this.retrySleep = retrySleep;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async sleep(reference: ResolveReference): Promise<void> {
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
reference.resolve = resolve;
|
|
64
|
+
setTimeout(resolve, this.retrySleep);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async prepareTx(
|
|
69
|
+
tx: Transaction,
|
|
70
|
+
additionalSigners: Array<Signer>,
|
|
71
|
+
opts: ConfirmOptions,
|
|
72
|
+
preSigned?: boolean
|
|
73
|
+
): Promise<Transaction> {
|
|
74
|
+
const latestBlockhash = await this.connection.getLatestBlockhash(
|
|
75
|
+
opts.preflightCommitment
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// handle tx
|
|
79
|
+
let signedTx = tx;
|
|
80
|
+
if (!preSigned) {
|
|
81
|
+
tx.feePayer = this.wallet.publicKey;
|
|
82
|
+
tx.recentBlockhash = latestBlockhash.blockhash;
|
|
83
|
+
|
|
84
|
+
additionalSigners
|
|
85
|
+
.filter((s): s is Signer => s !== undefined)
|
|
86
|
+
.forEach((kp) => {
|
|
87
|
+
tx.partialSign(kp);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
signedTx = await this.wallet.signTransaction(tx);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// handle subclass-specific side effects
|
|
94
|
+
const txSig = bs58.encode(tx.signatures[0]?.signature || tx.signatures[0]);
|
|
95
|
+
this.untilValid.set(txSig, latestBlockhash);
|
|
96
|
+
|
|
97
|
+
return signedTx;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async getVersionedTransaction(
|
|
101
|
+
ixs: TransactionInstruction[],
|
|
102
|
+
lookupTableAccounts: AddressLookupTableAccount[],
|
|
103
|
+
_additionalSigners?: Array<Signer>,
|
|
104
|
+
_opts?: ConfirmOptions
|
|
105
|
+
): Promise<VersionedTransaction> {
|
|
106
|
+
const message = new TransactionMessage({
|
|
107
|
+
payerKey: this.wallet.publicKey,
|
|
108
|
+
recentBlockhash: '', // set blank and reset in sendVersionTransaction
|
|
109
|
+
instructions: ixs,
|
|
110
|
+
}).compileToV0Message(lookupTableAccounts);
|
|
111
|
+
|
|
112
|
+
const tx = new VersionedTransaction(message);
|
|
113
|
+
|
|
114
|
+
return tx;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async sendVersionedTransaction(
|
|
118
|
+
tx: VersionedTransaction,
|
|
119
|
+
additionalSigners?: Array<Signer>,
|
|
120
|
+
opts?: ConfirmOptions,
|
|
121
|
+
preSigned?: boolean,
|
|
122
|
+
extraConfirmationOptions?: ExtraConfirmationOptions
|
|
123
|
+
): Promise<TxSigAndSlot> {
|
|
124
|
+
const latestBlockhash = await this.connection.getLatestBlockhash();
|
|
125
|
+
tx.message.recentBlockhash = latestBlockhash.blockhash;
|
|
126
|
+
|
|
127
|
+
let signedTx;
|
|
128
|
+
if (preSigned) {
|
|
129
|
+
signedTx = tx;
|
|
130
|
+
// @ts-ignore
|
|
131
|
+
} else if (this.wallet.payer) {
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
tx.sign((additionalSigners ?? []).concat(this.wallet.payer));
|
|
134
|
+
signedTx = tx;
|
|
135
|
+
} else {
|
|
136
|
+
additionalSigners
|
|
137
|
+
?.filter((s): s is Signer => s !== undefined)
|
|
138
|
+
.forEach((kp) => {
|
|
139
|
+
tx.sign([kp]);
|
|
140
|
+
});
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
signedTx = await this.wallet.signTransaction(tx);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (extraConfirmationOptions?.onSignedCb) {
|
|
146
|
+
extraConfirmationOptions.onSignedCb();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (opts === undefined) {
|
|
150
|
+
opts = this.opts;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const txSig = bs58.encode(signedTx.signatures[0]);
|
|
154
|
+
this.untilValid.set(txSig, latestBlockhash);
|
|
155
|
+
|
|
156
|
+
return this.sendRawTransaction(signedTx.serialize(), opts);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async sendRawTransaction(
|
|
160
|
+
rawTransaction: Buffer | Uint8Array,
|
|
161
|
+
opts: ConfirmOptions
|
|
162
|
+
): Promise<TxSigAndSlot> {
|
|
163
|
+
const startTime = this.getTimestamp();
|
|
164
|
+
|
|
165
|
+
const txid = await this.connection.sendRawTransaction(rawTransaction, opts);
|
|
166
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
167
|
+
|
|
168
|
+
let done = false;
|
|
169
|
+
const resolveReference: ResolveReference = {
|
|
170
|
+
resolve: undefined,
|
|
171
|
+
};
|
|
172
|
+
const stopWaiting = () => {
|
|
173
|
+
done = true;
|
|
174
|
+
if (resolveReference.resolve) {
|
|
175
|
+
resolveReference.resolve();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
(async () => {
|
|
180
|
+
while (!done && this.getTimestamp() - startTime < this.timeout) {
|
|
181
|
+
await this.sleep(resolveReference);
|
|
182
|
+
if (!done) {
|
|
183
|
+
this.connection
|
|
184
|
+
.sendRawTransaction(rawTransaction, opts)
|
|
185
|
+
.catch((e) => {
|
|
186
|
+
console.error(e);
|
|
187
|
+
stopWaiting();
|
|
188
|
+
});
|
|
189
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
|
|
194
|
+
let slot: number;
|
|
195
|
+
try {
|
|
196
|
+
const { blockhash, lastValidBlockHeight } = this.untilValid.get(txid);
|
|
197
|
+
const result = await this.connection.confirmTransaction(
|
|
198
|
+
{
|
|
199
|
+
signature: txid,
|
|
200
|
+
lastValidBlockHeight,
|
|
201
|
+
blockhash,
|
|
202
|
+
},
|
|
203
|
+
opts.commitment
|
|
204
|
+
);
|
|
205
|
+
slot = result.context.slot;
|
|
206
|
+
// eslint-disable-next-line no-useless-catch
|
|
207
|
+
} catch (e) {
|
|
208
|
+
throw e;
|
|
209
|
+
} finally {
|
|
210
|
+
stopWaiting();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return { txSig: txid, slot };
|
|
214
|
+
}
|
|
215
|
+
}
|