@drift-labs/sdk 2.96.0-beta.8 → 2.97.0-beta.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.
- package/README.md +3 -0
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/accounts/pollingDriftClientAccountSubscriber.d.ts +5 -3
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +24 -1
- package/lib/accounts/types.d.ts +5 -0
- package/lib/accounts/types.js +7 -1
- package/lib/accounts/utils.d.ts +7 -0
- package/lib/accounts/utils.js +33 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +5 -4
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +24 -1
- package/lib/config.d.ts +6 -1
- package/lib/config.js +10 -1
- package/lib/constants/perpMarkets.js +33 -1
- package/lib/constants/spotMarkets.js +10 -0
- package/lib/constants/txConstants.d.ts +1 -0
- package/lib/constants/txConstants.js +4 -0
- package/lib/driftClient.d.ts +45 -9
- package/lib/driftClient.js +191 -49
- package/lib/driftClientConfig.d.ts +3 -0
- package/lib/events/types.js +1 -5
- package/lib/idl/drift.json +170 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/margin.d.ts +16 -1
- package/lib/math/margin.js +67 -1
- package/lib/orderParams.js +8 -8
- package/lib/orderSubscriber/OrderSubscriber.js +1 -6
- package/lib/tokenFaucet.js +2 -1
- package/lib/tx/baseTxSender.d.ts +0 -1
- package/lib/tx/baseTxSender.js +8 -26
- package/lib/tx/fastSingleTxSender.js +2 -2
- package/lib/tx/forwardOnlyTxSender.js +2 -2
- package/lib/tx/reportTransactionError.d.ts +20 -0
- package/lib/tx/reportTransactionError.js +103 -0
- package/lib/tx/retryTxSender.js +2 -2
- package/lib/tx/txHandler.js +10 -7
- package/lib/tx/whileValidTxSender.d.ts +4 -5
- package/lib/tx/whileValidTxSender.js +16 -17
- package/lib/types.d.ts +22 -1
- package/lib/types.js +6 -1
- package/lib/user.d.ts +4 -1
- package/lib/user.js +9 -2
- package/lib/util/TransactionConfirmationManager.d.ts +16 -0
- package/lib/util/TransactionConfirmationManager.js +174 -0
- package/package.json +4 -3
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +41 -5
- package/src/accounts/types.ts +6 -0
- package/src/accounts/utils.ts +42 -0
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +40 -5
- package/src/config.ts +17 -1
- package/src/constants/perpMarkets.ts +35 -1
- package/src/constants/spotMarkets.ts +11 -0
- package/src/constants/txConstants.ts +1 -0
- package/src/driftClient.ts +426 -64
- package/src/driftClientConfig.ts +3 -0
- package/src/events/types.ts +1 -5
- package/src/idl/drift.json +170 -2
- package/src/index.ts +1 -0
- package/src/math/margin.ts +137 -1
- package/src/orderParams.ts +20 -12
- package/src/orderSubscriber/OrderSubscriber.ts +2 -5
- package/src/tokenFaucet.ts +2 -2
- package/src/tx/baseTxSender.ts +10 -32
- package/src/tx/fastSingleTxSender.ts +2 -2
- package/src/tx/forwardOnlyTxSender.ts +2 -2
- package/src/tx/reportTransactionError.ts +159 -0
- package/src/tx/retryTxSender.ts +2 -2
- package/src/tx/txHandler.ts +8 -2
- package/src/tx/whileValidTxSender.ts +18 -27
- package/src/types.ts +31 -1
- package/src/user.ts +35 -2
- package/src/util/TransactionConfirmationManager.ts +292 -0
- package/tests/ci/idl.ts +12 -3
- package/tests/ci/verifyConstants.ts +13 -0
- package/tests/tx/TransactionConfirmationManager.test.ts +305 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Commitment,
|
|
3
|
+
Connection,
|
|
4
|
+
Finality,
|
|
5
|
+
SendTransactionError,
|
|
6
|
+
VersionedTransactionResponse,
|
|
7
|
+
} from '@solana/web3.js';
|
|
8
|
+
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The new getTransaction method expects a Finality type instead of a Commitment type. The only options for Finality are 'confirmed' and 'finalized'.
|
|
12
|
+
* @param commitment
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
const commitmentToFinality = (commitment: Commitment): Finality => {
|
|
16
|
+
switch (commitment) {
|
|
17
|
+
case 'confirmed':
|
|
18
|
+
return 'confirmed';
|
|
19
|
+
case 'finalized':
|
|
20
|
+
return 'finalized';
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Invalid commitment when reporting transaction error. The commitment must be 'confirmed' or 'finalized' but was given '${commitment}'. If you're using this commitment for a specific reason, you may need to roll your own logic here.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const getTransactionResult = async (
|
|
29
|
+
txSig: string,
|
|
30
|
+
connection: Connection,
|
|
31
|
+
commitment?: Commitment
|
|
32
|
+
): Promise<VersionedTransactionResponse> => {
|
|
33
|
+
const finality = commitmentToFinality(
|
|
34
|
+
commitment || connection.commitment || DEFAULT_CONFIRMATION_OPTS.commitment
|
|
35
|
+
);
|
|
36
|
+
return await connection.getTransaction(txSig, {
|
|
37
|
+
maxSupportedTransactionVersion: 0,
|
|
38
|
+
commitment: finality,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const getTransactionResultWithRetry = async (
|
|
43
|
+
txSig: string,
|
|
44
|
+
connection: Connection,
|
|
45
|
+
commitment?: Commitment
|
|
46
|
+
): Promise<VersionedTransactionResponse> => {
|
|
47
|
+
const start = Date.now();
|
|
48
|
+
|
|
49
|
+
const retryTimeout = 3_000; // Timeout after 3 seconds
|
|
50
|
+
const retryInterval = 800; // Retry with 800ms interval
|
|
51
|
+
const retryCount = 3; // Retry 3 times
|
|
52
|
+
|
|
53
|
+
let currentCount = 0;
|
|
54
|
+
let transactionResult = await getTransactionResult(
|
|
55
|
+
txSig,
|
|
56
|
+
connection,
|
|
57
|
+
commitment
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Retry 3 times or until timeout as long as we don't have a result yet
|
|
61
|
+
while (
|
|
62
|
+
!transactionResult &&
|
|
63
|
+
Date.now() - start < retryTimeout &&
|
|
64
|
+
currentCount < retryCount
|
|
65
|
+
) {
|
|
66
|
+
// Sleep for 1 second :: Do this first so that we don't run the first loop immediately after the initial fetch above
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, retryInterval));
|
|
68
|
+
|
|
69
|
+
transactionResult = await getTransactionResult(
|
|
70
|
+
txSig,
|
|
71
|
+
connection,
|
|
72
|
+
commitment
|
|
73
|
+
);
|
|
74
|
+
currentCount++;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return transactionResult;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* THROWS if there is an error
|
|
82
|
+
*
|
|
83
|
+
* Should only be used for a txSig that is confirmed has an error. There is a race-condition where sometimes the transaction is not instantly available to fetch after the confirmation has already failed with an error, so this method has retry logic which we don't want to do wastefully. This method will throw a generic error if it can't get the transaction result after a retry period.
|
|
84
|
+
* @param txSig
|
|
85
|
+
* @param connection
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
export const throwTransactionError = async (
|
|
89
|
+
txSig: string,
|
|
90
|
+
connection: Connection,
|
|
91
|
+
commitment?: Commitment
|
|
92
|
+
): Promise<void> => {
|
|
93
|
+
const err = await getTransactionErrorFromTxSig(txSig, connection, commitment);
|
|
94
|
+
|
|
95
|
+
if (err) {
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* RETURNS an error if there is one
|
|
104
|
+
*
|
|
105
|
+
* Should only be used for a txSig that is confirmed has an error. There is a race-condition where sometimes the transaction is not instantly available to fetch after the confirmation has already failed with an error, so this method has retry logic which we don't want to do wastefully. This method will throw a generic error if it can't get the transaction result after a retry period.
|
|
106
|
+
* @param txSig
|
|
107
|
+
* @param connection
|
|
108
|
+
* @returns
|
|
109
|
+
*/
|
|
110
|
+
export const getTransactionErrorFromTxSig = async (
|
|
111
|
+
txSig: string,
|
|
112
|
+
connection: Connection,
|
|
113
|
+
commitment?: Commitment
|
|
114
|
+
): Promise<SendTransactionError> => {
|
|
115
|
+
const transactionResult = await getTransactionResultWithRetry(
|
|
116
|
+
txSig,
|
|
117
|
+
connection,
|
|
118
|
+
commitment
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (!transactionResult) {
|
|
122
|
+
// Throw a generic error because we couldn't get the transaction result for the given txSig
|
|
123
|
+
return new SendTransactionError({
|
|
124
|
+
action: 'send',
|
|
125
|
+
signature: txSig,
|
|
126
|
+
transactionMessage: `Transaction Failed`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!transactionResult?.meta?.err) {
|
|
131
|
+
// Assume that the transaction was successful and we are here erroneously because we have a result with no error
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return getTransactionError(transactionResult);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const getTransactionError = (
|
|
139
|
+
transactionResult: VersionedTransactionResponse
|
|
140
|
+
): SendTransactionError => {
|
|
141
|
+
if (!transactionResult?.meta?.err) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const logs = transactionResult?.meta?.logMessages ?? ['No logs'];
|
|
146
|
+
|
|
147
|
+
const lastLog = logs[logs.length - 1];
|
|
148
|
+
|
|
149
|
+
const friendlyMessage = lastLog?.match(/(failed:) (.+)/)?.[2];
|
|
150
|
+
|
|
151
|
+
return new SendTransactionError({
|
|
152
|
+
action: 'send',
|
|
153
|
+
signature: transactionResult?.transaction?.signatures?.[0],
|
|
154
|
+
transactionMessage: `Transaction Failed${
|
|
155
|
+
friendlyMessage ? `: ${friendlyMessage}` : ''
|
|
156
|
+
}`,
|
|
157
|
+
logs,
|
|
158
|
+
});
|
|
159
|
+
};
|
package/src/tx/retryTxSender.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ConfirmationStrategy, TxSigAndSlot } from './types';
|
|
2
2
|
import { ConfirmOptions, Connection } from '@solana/web3.js';
|
|
3
|
-
import { AnchorProvider } from '@coral-xyz/anchor';
|
|
4
3
|
import { BaseTxSender } from './baseTxSender';
|
|
5
4
|
import { TxHandler } from './txHandler';
|
|
6
5
|
import { IWallet } from '../types';
|
|
6
|
+
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUT = 35000;
|
|
9
9
|
const DEFAULT_RETRY = 2000;
|
|
@@ -24,7 +24,7 @@ export class RetryTxSender extends BaseTxSender {
|
|
|
24
24
|
public constructor({
|
|
25
25
|
connection,
|
|
26
26
|
wallet,
|
|
27
|
-
opts = { ...
|
|
27
|
+
opts = { ...DEFAULT_CONFIRMATION_OPTS, maxRetries: 0 },
|
|
28
28
|
timeout = DEFAULT_TIMEOUT,
|
|
29
29
|
retrySleep = DEFAULT_RETRY,
|
|
30
30
|
additionalConnections = new Array<Connection>(),
|
package/src/tx/txHandler.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { CachedBlockhashFetcher } from './blockhashFetcher/cachedBlockhashFetche
|
|
|
29
29
|
import { BaseBlockhashFetcher } from './blockhashFetcher/baseBlockhashFetcher';
|
|
30
30
|
import { BlockhashFetcher } from './blockhashFetcher/types';
|
|
31
31
|
import { isVersionedTransaction } from './utils';
|
|
32
|
+
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Explanation for SIGNATURE_BLOCK_AND_EXPIRY:
|
|
@@ -81,7 +82,8 @@ export class TxHandler {
|
|
|
81
82
|
private preSignedCb?: () => void;
|
|
82
83
|
private onSignedCb?: (txSigs: DriftClientMetricsEvents['txSigned']) => void;
|
|
83
84
|
|
|
84
|
-
private blockhashCommitment: Commitment =
|
|
85
|
+
private blockhashCommitment: Commitment =
|
|
86
|
+
DEFAULT_CONFIRMATION_OPTS.commitment;
|
|
85
87
|
private blockHashFetcher: BlockhashFetcher;
|
|
86
88
|
|
|
87
89
|
constructor(props: {
|
|
@@ -98,6 +100,11 @@ export class TxHandler {
|
|
|
98
100
|
this.connection = props.connection;
|
|
99
101
|
this.wallet = props.wallet;
|
|
100
102
|
this.confirmationOptions = props.confirmationOptions;
|
|
103
|
+
this.blockhashCommitment =
|
|
104
|
+
props.confirmationOptions?.preflightCommitment ??
|
|
105
|
+
props?.connection?.commitment ??
|
|
106
|
+
this.blockhashCommitment ??
|
|
107
|
+
'confirmed';
|
|
101
108
|
|
|
102
109
|
this.blockHashFetcher = props?.config?.blockhashCachingEnabled
|
|
103
110
|
? new CachedBlockhashFetcher(
|
|
@@ -536,7 +543,6 @@ export class TxHandler {
|
|
|
536
543
|
}
|
|
537
544
|
} else {
|
|
538
545
|
const marketLookupTable = await fetchMarketLookupTableAccount();
|
|
539
|
-
|
|
540
546
|
lookupTables = lookupTables
|
|
541
547
|
? [...lookupTables, marketLookupTable]
|
|
542
548
|
: [marketLookupTable];
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { TxSigAndSlot } from './types';
|
|
1
|
+
import { ConfirmationStrategy, TxSigAndSlot } from './types';
|
|
2
2
|
import {
|
|
3
|
-
Commitment,
|
|
4
3
|
ConfirmOptions,
|
|
5
4
|
Connection,
|
|
5
|
+
SendTransactionError,
|
|
6
6
|
Signer,
|
|
7
7
|
Transaction,
|
|
8
8
|
VersionedTransaction,
|
|
9
9
|
} from '@solana/web3.js';
|
|
10
|
-
import { AnchorProvider } from '@coral-xyz/anchor';
|
|
11
10
|
import { BaseTxSender } from './baseTxSender';
|
|
12
11
|
import bs58 from 'bs58';
|
|
13
12
|
import { TxHandler } from './txHandler';
|
|
14
13
|
import { IWallet } from '../types';
|
|
14
|
+
import { DEFAULT_CONFIRMATION_OPTS } from '../config';
|
|
15
15
|
|
|
16
16
|
const DEFAULT_RETRY = 2000;
|
|
17
17
|
|
|
18
|
-
const VALID_BLOCK_HEIGHT_OFFSET = -150; // This is a bit of weirdness but the lastValidBlockHeight value returned from connection.getLatestBlockhash is always 300 blocks ahead of the current block, even though the transaction actually expires after 150 blocks. This accounts for that so that we can at least accuractely estimate the transaction expiry.
|
|
19
|
-
|
|
20
18
|
type ResolveReference = {
|
|
21
19
|
resolve?: () => void;
|
|
22
20
|
};
|
|
@@ -33,7 +31,6 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
33
31
|
string,
|
|
34
32
|
{ blockhash: string; lastValidBlockHeight: number }
|
|
35
33
|
>();
|
|
36
|
-
blockhashCommitment: Commitment;
|
|
37
34
|
|
|
38
35
|
useBlockHeightOffset = true;
|
|
39
36
|
|
|
@@ -62,11 +59,11 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
62
59
|
public constructor({
|
|
63
60
|
connection,
|
|
64
61
|
wallet,
|
|
65
|
-
opts = { ...
|
|
62
|
+
opts = { ...DEFAULT_CONFIRMATION_OPTS, maxRetries: 0 },
|
|
66
63
|
retrySleep = DEFAULT_RETRY,
|
|
67
64
|
additionalConnections = new Array<Connection>(),
|
|
65
|
+
confirmationStrategy = ConfirmationStrategy.Combo,
|
|
68
66
|
additionalTxSenderCallbacks = [],
|
|
69
|
-
blockhashCommitment = 'finalized',
|
|
70
67
|
txHandler,
|
|
71
68
|
trackTxLandRate,
|
|
72
69
|
txLandRateLookbackWindowMinutes,
|
|
@@ -78,7 +75,7 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
78
75
|
retrySleep?: number;
|
|
79
76
|
additionalConnections?;
|
|
80
77
|
additionalTxSenderCallbacks?: ((base58EncodedTx: string) => void)[];
|
|
81
|
-
|
|
78
|
+
confirmationStrategy?: ConfirmationStrategy;
|
|
82
79
|
txHandler?: TxHandler;
|
|
83
80
|
trackTxLandRate?: boolean;
|
|
84
81
|
txLandRateLookbackWindowMinutes?: number;
|
|
@@ -93,10 +90,10 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
93
90
|
txHandler,
|
|
94
91
|
trackTxLandRate,
|
|
95
92
|
txLandRateLookbackWindowMinutes,
|
|
93
|
+
confirmationStrategy,
|
|
96
94
|
landRateToFeeFunc,
|
|
97
95
|
});
|
|
98
96
|
this.retrySleep = retrySleep;
|
|
99
|
-
this.blockhashCommitment = blockhashCommitment;
|
|
100
97
|
|
|
101
98
|
this.checkAndSetUseBlockHeightOffset();
|
|
102
99
|
}
|
|
@@ -139,7 +136,7 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
139
136
|
|
|
140
137
|
// handle subclass-specific side effects
|
|
141
138
|
const txSig = bs58.encode(
|
|
142
|
-
signedTx
|
|
139
|
+
signedTx?.signature || signedTx.signatures[0]?.signature
|
|
143
140
|
);
|
|
144
141
|
this.untilValid.set(txSig, latestBlockhash);
|
|
145
142
|
|
|
@@ -234,27 +231,21 @@ export class WhileValidTxSender extends BaseTxSender {
|
|
|
234
231
|
|
|
235
232
|
let slot: number;
|
|
236
233
|
try {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
const result = await this.connection.confirmTransaction(
|
|
240
|
-
{
|
|
241
|
-
signature: txid,
|
|
242
|
-
blockhash,
|
|
243
|
-
lastValidBlockHeight: this.useBlockHeightOffset
|
|
244
|
-
? lastValidBlockHeight + VALID_BLOCK_HEIGHT_OFFSET
|
|
245
|
-
: lastValidBlockHeight,
|
|
246
|
-
},
|
|
247
|
-
opts?.commitment
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
if (!result) {
|
|
251
|
-
throw new Error(`Couldn't get signature status for txid: ${txid}`);
|
|
252
|
-
}
|
|
234
|
+
const result = await this.confirmTransaction(txid, opts.commitment);
|
|
253
235
|
|
|
254
236
|
this.txSigCache?.set(txid, true);
|
|
255
237
|
|
|
256
238
|
await this.checkConfirmationResultForError(txid, result.value);
|
|
257
239
|
|
|
240
|
+
if (result?.value?.err) {
|
|
241
|
+
// Fallback error handling if there's a problem reporting the error in checkConfirmationResultForError
|
|
242
|
+
throw new SendTransactionError({
|
|
243
|
+
action: 'send',
|
|
244
|
+
signature: txid,
|
|
245
|
+
transactionMessage: `Transaction Failed`,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
258
249
|
slot = result.context.slot;
|
|
259
250
|
// eslint-disable-next-line no-useless-catch
|
|
260
251
|
} catch (e) {
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Keypair,
|
|
3
|
+
PublicKey,
|
|
4
|
+
Transaction,
|
|
5
|
+
VersionedTransaction,
|
|
6
|
+
} from '@solana/web3.js';
|
|
2
7
|
import { BN, ZERO } from '.';
|
|
3
8
|
|
|
4
9
|
// Utility type which lets you denote record with values of type A mapped to a record with the same keys but values of type B
|
|
@@ -1051,6 +1056,24 @@ export const DefaultOrderParams: OrderParams = {
|
|
|
1051
1056
|
auctionEndPrice: null,
|
|
1052
1057
|
};
|
|
1053
1058
|
|
|
1059
|
+
export type SwiftServerMessage = {
|
|
1060
|
+
slot: BN;
|
|
1061
|
+
swiftOrderSignature: Uint8Array;
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
export type SwiftOrderParamsMessage = {
|
|
1065
|
+
swiftOrderParams: OptionalOrderParams;
|
|
1066
|
+
expectedOrderId: number;
|
|
1067
|
+
subAccountId: number;
|
|
1068
|
+
takeProfitOrderParams: SwiftTriggerOrderParams | null;
|
|
1069
|
+
stopLossOrderParams: SwiftTriggerOrderParams | null;
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
export type SwiftTriggerOrderParams = {
|
|
1073
|
+
triggerPrice: BN;
|
|
1074
|
+
baseAssetAmount: BN;
|
|
1075
|
+
};
|
|
1076
|
+
|
|
1054
1077
|
export type MakerInfo = {
|
|
1055
1078
|
maker: PublicKey;
|
|
1056
1079
|
makerStats: PublicKey;
|
|
@@ -1070,6 +1093,11 @@ export type ReferrerInfo = {
|
|
|
1070
1093
|
referrerStats: PublicKey;
|
|
1071
1094
|
};
|
|
1072
1095
|
|
|
1096
|
+
export enum PlaceAndTakeOrderSuccessCondition {
|
|
1097
|
+
PartialFill = 1,
|
|
1098
|
+
FullFill = 2,
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1073
1101
|
type ExactType<T> = Pick<T, keyof T>;
|
|
1074
1102
|
|
|
1075
1103
|
export type BaseTxParams = ExactType<{
|
|
@@ -1097,6 +1125,7 @@ export interface IWallet {
|
|
|
1097
1125
|
signTransaction(tx: Transaction): Promise<Transaction>;
|
|
1098
1126
|
signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
|
|
1099
1127
|
publicKey: PublicKey;
|
|
1128
|
+
payer?: Keypair;
|
|
1100
1129
|
}
|
|
1101
1130
|
export interface IVersionedWallet {
|
|
1102
1131
|
signVersionedTransaction(
|
|
@@ -1106,6 +1135,7 @@ export interface IVersionedWallet {
|
|
|
1106
1135
|
txs: VersionedTransaction[]
|
|
1107
1136
|
): Promise<VersionedTransaction[]>;
|
|
1108
1137
|
publicKey: PublicKey;
|
|
1138
|
+
payer?: Keypair;
|
|
1109
1139
|
}
|
|
1110
1140
|
|
|
1111
1141
|
export type FeeStructure = {
|
package/src/user.ts
CHANGED
|
@@ -78,6 +78,8 @@ import {
|
|
|
78
78
|
import { calculateMarketOpenBidAsk } from './math/amm';
|
|
79
79
|
import {
|
|
80
80
|
calculateBaseAssetValueWithOracle,
|
|
81
|
+
calculateCollateralDepositRequiredForTrade,
|
|
82
|
+
calculateMarginUSDCRequiredForTrade,
|
|
81
83
|
calculateWorstCaseBaseAssetAmount,
|
|
82
84
|
} from './math/margin';
|
|
83
85
|
import { OraclePriceData } from './oracles/types';
|
|
@@ -2274,6 +2276,7 @@ export class User {
|
|
|
2274
2276
|
* @param estimatedEntryPrice
|
|
2275
2277
|
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
2276
2278
|
* @param includeOpenOrders
|
|
2279
|
+
* @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
|
|
2277
2280
|
* @returns Precision : PRICE_PRECISION
|
|
2278
2281
|
*/
|
|
2279
2282
|
public liquidationPrice(
|
|
@@ -2281,7 +2284,8 @@ export class User {
|
|
|
2281
2284
|
positionBaseSizeChange: BN = ZERO,
|
|
2282
2285
|
estimatedEntryPrice: BN = ZERO,
|
|
2283
2286
|
marginCategory: MarginCategory = 'Maintenance',
|
|
2284
|
-
includeOpenOrders = false
|
|
2287
|
+
includeOpenOrders = false,
|
|
2288
|
+
offsetCollateral = ZERO
|
|
2285
2289
|
): BN {
|
|
2286
2290
|
const totalCollateral = this.getTotalCollateral(marginCategory);
|
|
2287
2291
|
const marginRequirement = this.getMarginRequirement(
|
|
@@ -2290,7 +2294,10 @@ export class User {
|
|
|
2290
2294
|
false,
|
|
2291
2295
|
includeOpenOrders
|
|
2292
2296
|
);
|
|
2293
|
-
let freeCollateral = BN.max(
|
|
2297
|
+
let freeCollateral = BN.max(
|
|
2298
|
+
ZERO,
|
|
2299
|
+
totalCollateral.sub(marginRequirement)
|
|
2300
|
+
).add(offsetCollateral);
|
|
2294
2301
|
|
|
2295
2302
|
const oracle =
|
|
2296
2303
|
this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
@@ -2593,6 +2600,32 @@ export class User {
|
|
|
2593
2600
|
);
|
|
2594
2601
|
}
|
|
2595
2602
|
|
|
2603
|
+
public getMarginUSDCRequiredForTrade(
|
|
2604
|
+
targetMarketIndex: number,
|
|
2605
|
+
baseSize: BN
|
|
2606
|
+
): BN {
|
|
2607
|
+
return calculateMarginUSDCRequiredForTrade(
|
|
2608
|
+
this.driftClient,
|
|
2609
|
+
targetMarketIndex,
|
|
2610
|
+
baseSize,
|
|
2611
|
+
this.getUserAccount().maxMarginRatio
|
|
2612
|
+
);
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
public getCollateralDepositRequiredForTrade(
|
|
2616
|
+
targetMarketIndex: number,
|
|
2617
|
+
baseSize: BN,
|
|
2618
|
+
collateralIndex: number
|
|
2619
|
+
): BN {
|
|
2620
|
+
return calculateCollateralDepositRequiredForTrade(
|
|
2621
|
+
this.driftClient,
|
|
2622
|
+
targetMarketIndex,
|
|
2623
|
+
baseSize,
|
|
2624
|
+
collateralIndex,
|
|
2625
|
+
this.getUserAccount().maxMarginRatio
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2596
2629
|
/**
|
|
2597
2630
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
2598
2631
|
*
|