@drift-labs/sdk 2.30.0-beta.1 → 2.31.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/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +5 -2
- package/lib/accounts/types.d.ts +3 -3
- package/lib/adminClient.d.ts +1 -0
- package/lib/adminClient.js +9 -0
- package/lib/constants/spotMarkets.js +10 -0
- package/lib/dlob/DLOB.d.ts +20 -1
- package/lib/dlob/DLOB.js +39 -0
- package/lib/driftClient.d.ts +13 -8
- package/lib/driftClient.js +32 -27
- package/lib/examples/makeTradeExample.js +1 -1
- package/lib/idl/drift.json +106 -15
- package/lib/jupiter/jupiterClient.d.ts +1 -1
- package/lib/jupiter/jupiterClient.js +7 -2
- package/lib/math/spotBalance.d.ts +41 -0
- package/lib/math/spotBalance.js +41 -0
- package/lib/token/index.d.ts +3 -2
- package/lib/token/index.js +9 -32
- package/lib/tokenFaucet.d.ts +3 -3
- package/lib/tokenFaucet.js +4 -9
- package/lib/tx/retryTxSender.js +3 -0
- package/lib/types.d.ts +22 -2
- package/lib/types.js +12 -1
- package/lib/wallet.d.ts +5 -3
- package/lib/wallet.js +19 -7
- package/package.json +2 -2
- package/src/accounts/pollingTokenAccountSubscriber.ts +8 -5
- package/src/accounts/types.ts +3 -3
- package/src/adminClient.ts +19 -0
- package/src/constants/spotMarkets.ts +11 -0
- package/src/dlob/DLOB.ts +75 -0
- package/src/driftClient.ts +57 -53
- package/src/examples/makeTradeExample.ts +2 -4
- package/src/idl/drift.json +106 -15
- package/src/jupiter/jupiterClient.ts +10 -2
- package/src/math/spotBalance.ts +41 -0
- package/src/token/index.ts +12 -36
- package/src/tokenFaucet.ts +15 -34
- package/src/tx/retryTxSender.ts +4 -0
- package/src/types.ts +23 -2
- package/src/wallet.ts +34 -12
- package/tests/dlob/helpers.ts +1 -0
- package/tests/dlob/test.ts +218 -40
- package/lib/util/getTokenAddress.d.ts +0 -2
- package/lib/util/getTokenAddress.js +0 -9
- package/src/util/getTokenAddress.ts +0 -18
package/lib/wallet.js
CHANGED
|
@@ -15,12 +15,22 @@ class Wallet {
|
|
|
15
15
|
tx.partialSign(this.payer);
|
|
16
16
|
return tx;
|
|
17
17
|
}
|
|
18
|
+
async signVersionedTransaction(tx) {
|
|
19
|
+
tx.sign([this.payer]);
|
|
20
|
+
return tx;
|
|
21
|
+
}
|
|
18
22
|
async signAllTransactions(txs) {
|
|
19
23
|
return txs.map((t) => {
|
|
20
24
|
t.partialSign(this.payer);
|
|
21
25
|
return t;
|
|
22
26
|
});
|
|
23
27
|
}
|
|
28
|
+
async signAllVersionedTransactions(txs) {
|
|
29
|
+
return txs.map((t) => {
|
|
30
|
+
t.sign([this.payer]);
|
|
31
|
+
return t;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
24
34
|
get publicKey() {
|
|
25
35
|
return this.payer.publicKey;
|
|
26
36
|
}
|
|
@@ -30,15 +40,17 @@ function loadKeypair(privateKey) {
|
|
|
30
40
|
// try to load privateKey as a filepath
|
|
31
41
|
let loadedKey;
|
|
32
42
|
if (fs_1.default.existsSync(privateKey)) {
|
|
33
|
-
|
|
43
|
+
privateKey = fs_1.default.readFileSync(privateKey).toString();
|
|
44
|
+
}
|
|
45
|
+
if (privateKey.includes('[') && privateKey.includes(']')) {
|
|
46
|
+
loadedKey = Uint8Array.from(JSON.parse(privateKey));
|
|
47
|
+
}
|
|
48
|
+
else if (privateKey.includes(',')) {
|
|
49
|
+
loadedKey = Uint8Array.from(privateKey.split(',').map((val) => Number(val)));
|
|
34
50
|
}
|
|
35
51
|
else {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
loadedKey = new Uint8Array(bs58_1.default.decode(privateKey));
|
|
41
|
-
}
|
|
52
|
+
privateKey = privateKey.replace(/\s/g, '');
|
|
53
|
+
loadedKey = new Uint8Array(bs58_1.default.decode(privateKey));
|
|
42
54
|
}
|
|
43
55
|
return web3_js_1.Keypair.fromSecretKey(Uint8Array.from(loadedKey));
|
|
44
56
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.0-beta.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@ellipsis-labs/phoenix-sdk": "^1.4.2",
|
|
38
38
|
"@project-serum/serum": "^0.13.38",
|
|
39
39
|
"@pythnetwork/client": "2.5.3",
|
|
40
|
-
"@solana/spl-token": "^0.
|
|
40
|
+
"@solana/spl-token": "^0.3.7",
|
|
41
41
|
"@solana/web3.js": "1.73.2",
|
|
42
42
|
"strict-event-emitter-types": "^2.0.0",
|
|
43
43
|
"uuid": "^8.3.2"
|
|
@@ -9,7 +9,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
|
|
|
9
9
|
import { EventEmitter } from 'events';
|
|
10
10
|
import { PublicKey } from '@solana/web3.js';
|
|
11
11
|
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
12
|
-
import {
|
|
12
|
+
import { Account } from '@solana/spl-token';
|
|
13
13
|
import { parseTokenAccount } from '../token';
|
|
14
14
|
|
|
15
15
|
export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
@@ -22,7 +22,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
22
22
|
callbackId?: string;
|
|
23
23
|
errorCallbackId?: string;
|
|
24
24
|
|
|
25
|
-
tokenAccountAndSlot?: DataAndSlot<
|
|
25
|
+
tokenAccountAndSlot?: DataAndSlot<Account>;
|
|
26
26
|
|
|
27
27
|
public constructor(publicKey: PublicKey, accountLoader: BulkAccountLoader) {
|
|
28
28
|
this.isSubscribed = false;
|
|
@@ -61,7 +61,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
61
61
|
this.callbackId = await this.accountLoader.addAccount(
|
|
62
62
|
this.publicKey,
|
|
63
63
|
(buffer, slot: number) => {
|
|
64
|
-
const tokenAccount = parseTokenAccount(buffer);
|
|
64
|
+
const tokenAccount = parseTokenAccount(buffer, this.publicKey);
|
|
65
65
|
this.tokenAccountAndSlot = { data: tokenAccount, slot };
|
|
66
66
|
// @ts-ignore
|
|
67
67
|
this.eventEmitter.emit('tokenAccountUpdate', tokenAccount);
|
|
@@ -79,7 +79,10 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
79
79
|
const { buffer, slot } = this.accountLoader.getBufferAndSlot(
|
|
80
80
|
this.publicKey
|
|
81
81
|
);
|
|
82
|
-
this.tokenAccountAndSlot = {
|
|
82
|
+
this.tokenAccountAndSlot = {
|
|
83
|
+
data: parseTokenAccount(buffer, this.publicKey),
|
|
84
|
+
slot,
|
|
85
|
+
};
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
async unsubscribe(): Promise<void> {
|
|
@@ -104,7 +107,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
109
|
|
|
107
|
-
public getTokenAccountAndSlot(): DataAndSlot<
|
|
110
|
+
public getTokenAccountAndSlot(): DataAndSlot<Account> {
|
|
108
111
|
this.assertIsSubscribed();
|
|
109
112
|
return this.tokenAccountAndSlot;
|
|
110
113
|
}
|
package/src/accounts/types.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
10
10
|
import { EventEmitter } from 'events';
|
|
11
11
|
import { PublicKey } from '@solana/web3.js';
|
|
12
|
-
import {
|
|
12
|
+
import { Account } from '@solana/spl-token';
|
|
13
13
|
import { OracleInfo, OraclePriceData } from '..';
|
|
14
14
|
|
|
15
15
|
export interface AccountSubscriber<T> {
|
|
@@ -82,7 +82,7 @@ export interface UserAccountSubscriber {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
export interface TokenAccountEvents {
|
|
85
|
-
tokenAccountUpdate: (payload:
|
|
85
|
+
tokenAccountUpdate: (payload: Account) => void;
|
|
86
86
|
update: void;
|
|
87
87
|
error: (e: Error) => void;
|
|
88
88
|
}
|
|
@@ -95,7 +95,7 @@ export interface TokenAccountSubscriber {
|
|
|
95
95
|
fetch(): Promise<void>;
|
|
96
96
|
unsubscribe(): Promise<void>;
|
|
97
97
|
|
|
98
|
-
getTokenAccountAndSlot(): DataAndSlot<
|
|
98
|
+
getTokenAccountAndSlot(): DataAndSlot<Account>;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
export interface OracleEvents {
|
package/src/adminClient.ts
CHANGED
|
@@ -544,6 +544,25 @@ export class AdminClient extends DriftClient {
|
|
|
544
544
|
);
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
+
public async updatePerpMarketTargetBaseAssetAmountPerLp(
|
|
548
|
+
perpMarketIndex: number,
|
|
549
|
+
targetBaseAssetAmountPerLP: number
|
|
550
|
+
): Promise<TransactionSignature> {
|
|
551
|
+
return await this.program.rpc.updatePerpMarketTargetBaseAssetAmountPerLp(
|
|
552
|
+
targetBaseAssetAmountPerLP,
|
|
553
|
+
{
|
|
554
|
+
accounts: {
|
|
555
|
+
admin: this.wallet.publicKey,
|
|
556
|
+
state: await this.getStatePublicKey(),
|
|
557
|
+
perpMarket: await getPerpMarketPublicKey(
|
|
558
|
+
this.program.programId,
|
|
559
|
+
perpMarketIndex
|
|
560
|
+
),
|
|
561
|
+
},
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
|
|
547
566
|
public async updatePerpMarketMarginRatio(
|
|
548
567
|
perpMarketIndex: number,
|
|
549
568
|
marginRatioInitial: number,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
LAMPORTS_EXP,
|
|
7
7
|
LAMPORTS_PRECISION,
|
|
8
8
|
SIX,
|
|
9
|
+
NINE,
|
|
9
10
|
} from './numericConstants';
|
|
10
11
|
|
|
11
12
|
export type SpotMarketConfig = {
|
|
@@ -82,6 +83,16 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
82
83
|
'4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg'
|
|
83
84
|
),
|
|
84
85
|
},
|
|
86
|
+
{
|
|
87
|
+
symbol: 'mSOL',
|
|
88
|
+
marketIndex: 2,
|
|
89
|
+
oracle: new PublicKey('E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9'),
|
|
90
|
+
oracleSource: OracleSource.PYTH,
|
|
91
|
+
mint: new PublicKey('mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So'),
|
|
92
|
+
precision: new BN(10).pow(NINE),
|
|
93
|
+
precisionExp: NINE,
|
|
94
|
+
serumMarket: new PublicKey('9Lyhks5bQQxb9EyyX55NtgKQzpM4WK7JCmeaWuQ5MoXD'),
|
|
95
|
+
},
|
|
85
96
|
];
|
|
86
97
|
|
|
87
98
|
export const SpotMarkets: { [key in DriftEnv]: SpotMarketConfig[] } = {
|
package/src/dlob/DLOB.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getOrderSignature, getVammNodeGenerator, NodeList } from './NodeList';
|
|
2
2
|
import {
|
|
3
|
+
BASE_PRECISION,
|
|
3
4
|
BN,
|
|
4
5
|
calculateAskPrice,
|
|
5
6
|
calculateBidPrice,
|
|
@@ -24,12 +25,15 @@ import {
|
|
|
24
25
|
OrderActionRecord,
|
|
25
26
|
OrderRecord,
|
|
26
27
|
PerpMarketAccount,
|
|
28
|
+
PositionDirection,
|
|
27
29
|
PRICE_PRECISION,
|
|
30
|
+
QUOTE_PRECISION,
|
|
28
31
|
SlotSubscriber,
|
|
29
32
|
SpotMarketAccount,
|
|
30
33
|
StateAccount,
|
|
31
34
|
TriggerOrderNode,
|
|
32
35
|
UserMap,
|
|
36
|
+
ZERO,
|
|
33
37
|
} from '..';
|
|
34
38
|
import { PublicKey } from '@solana/web3.js';
|
|
35
39
|
import { ammPaused, exchangePaused, fillPaused } from '../math/exchangeStatus';
|
|
@@ -1849,4 +1853,75 @@ export class DLOB {
|
|
|
1849
1853
|
asks,
|
|
1850
1854
|
};
|
|
1851
1855
|
}
|
|
1856
|
+
|
|
1857
|
+
private estimateFillExactBaseAmountInForSide(
|
|
1858
|
+
baseAmountIn: BN,
|
|
1859
|
+
oraclePriceData: OraclePriceData,
|
|
1860
|
+
slot: number,
|
|
1861
|
+
dlobSide: Generator<DLOBNode>
|
|
1862
|
+
): BN {
|
|
1863
|
+
let runningSumQuote = ZERO;
|
|
1864
|
+
let runningSumBase = ZERO;
|
|
1865
|
+
for (const side of dlobSide) {
|
|
1866
|
+
const price = side.getPrice(oraclePriceData, slot); //side.order.quoteAssetAmount.div(side.order.baseAssetAmount);
|
|
1867
|
+
const baseAmountRemaining = side.order.baseAssetAmount.sub(
|
|
1868
|
+
side.order.baseAssetAmountFilled
|
|
1869
|
+
);
|
|
1870
|
+
if (runningSumBase.add(baseAmountRemaining).gt(baseAmountIn)) {
|
|
1871
|
+
const remainingBase = baseAmountIn.sub(runningSumBase);
|
|
1872
|
+
runningSumBase = runningSumBase.add(remainingBase);
|
|
1873
|
+
runningSumQuote = runningSumQuote.add(remainingBase.mul(price));
|
|
1874
|
+
break;
|
|
1875
|
+
} else {
|
|
1876
|
+
runningSumBase = runningSumBase.add(baseAmountRemaining);
|
|
1877
|
+
runningSumQuote = runningSumQuote.add(baseAmountRemaining.mul(price));
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
return runningSumQuote
|
|
1882
|
+
.mul(QUOTE_PRECISION)
|
|
1883
|
+
.div(BASE_PRECISION.mul(PRICE_PRECISION));
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
/**
|
|
1887
|
+
*
|
|
1888
|
+
* @param param.marketIndex the index of the market
|
|
1889
|
+
* @param param.marketType the type of the market
|
|
1890
|
+
* @param param.baseAmount the base amount in to estimate
|
|
1891
|
+
* @param param.orderDirection the direction of the trade
|
|
1892
|
+
* @param param.slot current slot for estimating dlob node price
|
|
1893
|
+
* @param param.oraclePriceData the oracle price data
|
|
1894
|
+
* @returns the estimated quote amount filled: QUOTE_PRECISION
|
|
1895
|
+
*/
|
|
1896
|
+
public estimateFillWithExactBaseAmount({
|
|
1897
|
+
marketIndex,
|
|
1898
|
+
marketType,
|
|
1899
|
+
baseAmount,
|
|
1900
|
+
orderDirection,
|
|
1901
|
+
slot,
|
|
1902
|
+
oraclePriceData,
|
|
1903
|
+
}: {
|
|
1904
|
+
marketIndex: number;
|
|
1905
|
+
marketType: MarketType;
|
|
1906
|
+
baseAmount: BN;
|
|
1907
|
+
orderDirection: PositionDirection;
|
|
1908
|
+
slot: number;
|
|
1909
|
+
oraclePriceData: OraclePriceData;
|
|
1910
|
+
}): BN {
|
|
1911
|
+
if (isVariant(orderDirection, 'long')) {
|
|
1912
|
+
return this.estimateFillExactBaseAmountInForSide(
|
|
1913
|
+
baseAmount,
|
|
1914
|
+
oraclePriceData,
|
|
1915
|
+
slot,
|
|
1916
|
+
this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData)
|
|
1917
|
+
);
|
|
1918
|
+
} else if (isVariant(orderDirection, 'short')) {
|
|
1919
|
+
return this.estimateFillExactBaseAmountInForSide(
|
|
1920
|
+
baseAmount,
|
|
1921
|
+
oraclePriceData,
|
|
1922
|
+
slot,
|
|
1923
|
+
this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData)
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1852
1927
|
}
|
package/src/driftClient.ts
CHANGED
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
import bs58 from 'bs58';
|
|
9
9
|
import {
|
|
10
10
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
11
|
-
|
|
11
|
+
createAssociatedTokenAccountInstruction,
|
|
12
|
+
createCloseAccountInstruction,
|
|
13
|
+
createInitializeAccountInstruction,
|
|
14
|
+
getAssociatedTokenAddress,
|
|
12
15
|
TOKEN_PROGRAM_ID,
|
|
13
16
|
} from '@solana/spl-token';
|
|
14
17
|
import {
|
|
@@ -39,6 +42,7 @@ import {
|
|
|
39
42
|
ModifyOrderParams,
|
|
40
43
|
PhoenixV1FulfillmentConfigAccount,
|
|
41
44
|
ModifyOrderPolicy,
|
|
45
|
+
SwapReduceOnly,
|
|
42
46
|
} from './types';
|
|
43
47
|
import * as anchor from '@coral-xyz/anchor';
|
|
44
48
|
import driftIDL from './idl/drift.json';
|
|
@@ -113,7 +117,7 @@ import { isSpotPositionAvailable } from './math/spotPosition';
|
|
|
113
117
|
import { calculateMarketMaxAvailableInsurance } from './math/market';
|
|
114
118
|
import { fetchUserStatsAccount } from './accounts/fetch';
|
|
115
119
|
import { castNumberToSpotPrecision } from './math/spotMarket';
|
|
116
|
-
import { JupiterClient } from './jupiter/jupiterClient';
|
|
120
|
+
import { JupiterClient, Route, SwapMode } from './jupiter/jupiterClient';
|
|
117
121
|
|
|
118
122
|
type RemainingAccountParams = {
|
|
119
123
|
userAccounts: UserAccount[];
|
|
@@ -720,9 +724,7 @@ export class DriftClient {
|
|
|
720
724
|
|
|
721
725
|
const state = this.getStateAccount();
|
|
722
726
|
if (!state.whitelistMint.equals(PublicKey.default)) {
|
|
723
|
-
const associatedTokenPublicKey = await
|
|
724
|
-
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
725
|
-
TOKEN_PROGRAM_ID,
|
|
727
|
+
const associatedTokenPublicKey = await getAssociatedTokenAddress(
|
|
726
728
|
state.whitelistMint,
|
|
727
729
|
this.wallet.publicKey
|
|
728
730
|
);
|
|
@@ -1489,20 +1491,15 @@ export class DriftClient {
|
|
|
1489
1491
|
return this.wallet.publicKey;
|
|
1490
1492
|
}
|
|
1491
1493
|
const mint = spotMarket.mint;
|
|
1492
|
-
return await
|
|
1493
|
-
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
1494
|
-
TOKEN_PROGRAM_ID,
|
|
1495
|
-
mint,
|
|
1496
|
-
this.wallet.publicKey
|
|
1497
|
-
);
|
|
1494
|
+
return await getAssociatedTokenAddress(mint, this.wallet.publicKey);
|
|
1498
1495
|
}
|
|
1499
1496
|
|
|
1500
|
-
public
|
|
1497
|
+
public createAssociatedTokenAccountIdempotentInstruction(
|
|
1501
1498
|
account: PublicKey,
|
|
1502
1499
|
payer: PublicKey,
|
|
1503
1500
|
owner: PublicKey,
|
|
1504
1501
|
mint: PublicKey
|
|
1505
|
-
):
|
|
1502
|
+
): TransactionInstruction {
|
|
1506
1503
|
return new TransactionInstruction({
|
|
1507
1504
|
keys: [
|
|
1508
1505
|
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
@@ -1510,7 +1507,7 @@ export class DriftClient {
|
|
|
1510
1507
|
{ pubkey: owner, isSigner: false, isWritable: false },
|
|
1511
1508
|
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
1512
1509
|
{
|
|
1513
|
-
pubkey: SystemProgram.programId,
|
|
1510
|
+
pubkey: anchor.web3.SystemProgram.programId,
|
|
1514
1511
|
isSigner: false,
|
|
1515
1512
|
isWritable: false,
|
|
1516
1513
|
},
|
|
@@ -1582,8 +1579,7 @@ export class DriftClient {
|
|
|
1582
1579
|
// Close the wrapped sol account at the end of the transaction
|
|
1583
1580
|
if (createWSOLTokenAccount) {
|
|
1584
1581
|
tx.add(
|
|
1585
|
-
|
|
1586
|
-
TOKEN_PROGRAM_ID,
|
|
1582
|
+
createCloseAccountInstruction(
|
|
1587
1583
|
associatedTokenAccount,
|
|
1588
1584
|
signerAuthority,
|
|
1589
1585
|
signerAuthority,
|
|
@@ -1696,10 +1692,9 @@ export class DriftClient {
|
|
|
1696
1692
|
);
|
|
1697
1693
|
|
|
1698
1694
|
result.ixs.push(
|
|
1699
|
-
|
|
1700
|
-
TOKEN_PROGRAM_ID,
|
|
1701
|
-
WRAPPED_SOL_MINT,
|
|
1695
|
+
createInitializeAccountInstruction(
|
|
1702
1696
|
wrappedSolAccount.publicKey,
|
|
1697
|
+
WRAPPED_SOL_MINT,
|
|
1703
1698
|
authority
|
|
1704
1699
|
)
|
|
1705
1700
|
);
|
|
@@ -1713,17 +1708,12 @@ export class DriftClient {
|
|
|
1713
1708
|
tokenMintAddress: PublicKey,
|
|
1714
1709
|
associatedTokenAddress: PublicKey
|
|
1715
1710
|
): anchor.web3.TransactionInstruction {
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
this.wallet.publicKey,
|
|
1723
|
-
this.wallet.publicKey
|
|
1724
|
-
);
|
|
1725
|
-
|
|
1726
|
-
return createAssociatedAccountIx;
|
|
1711
|
+
return createAssociatedTokenAccountInstruction(
|
|
1712
|
+
this.wallet.publicKey,
|
|
1713
|
+
associatedTokenAddress,
|
|
1714
|
+
this.wallet.publicKey,
|
|
1715
|
+
tokenMintAddress
|
|
1716
|
+
);
|
|
1727
1717
|
}
|
|
1728
1718
|
|
|
1729
1719
|
/**
|
|
@@ -1825,8 +1815,7 @@ export class DriftClient {
|
|
|
1825
1815
|
// Close the wrapped sol account at the end of the transaction
|
|
1826
1816
|
if (createWSOLTokenAccount) {
|
|
1827
1817
|
tx.add(
|
|
1828
|
-
|
|
1829
|
-
TOKEN_PROGRAM_ID,
|
|
1818
|
+
createCloseAccountInstruction(
|
|
1830
1819
|
userTokenAccount,
|
|
1831
1820
|
authority,
|
|
1832
1821
|
authority,
|
|
@@ -1965,8 +1954,7 @@ export class DriftClient {
|
|
|
1965
1954
|
// Close the wrapped sol account at the end of the transaction
|
|
1966
1955
|
if (createWSOLTokenAccount) {
|
|
1967
1956
|
tx.add(
|
|
1968
|
-
|
|
1969
|
-
TOKEN_PROGRAM_ID,
|
|
1957
|
+
createCloseAccountInstruction(
|
|
1970
1958
|
associatedTokenAddress,
|
|
1971
1959
|
authority,
|
|
1972
1960
|
authority,
|
|
@@ -3300,6 +3288,7 @@ export class DriftClient {
|
|
|
3300
3288
|
* @param inAssociatedTokenAccount the token account to
|
|
3301
3289
|
* @param amount the amount of the token to sell
|
|
3302
3290
|
* @param slippageBps the max slippage passed to jupiter api
|
|
3291
|
+
* @param route the jupiter route to use for the swap
|
|
3303
3292
|
* @param txParams
|
|
3304
3293
|
*/
|
|
3305
3294
|
public async swap({
|
|
@@ -3310,32 +3299,42 @@ export class DriftClient {
|
|
|
3310
3299
|
inAssociatedTokenAccount,
|
|
3311
3300
|
amount,
|
|
3312
3301
|
slippageBps,
|
|
3302
|
+
swapMode,
|
|
3303
|
+
route,
|
|
3304
|
+
reduceOnly,
|
|
3313
3305
|
txParams,
|
|
3314
3306
|
}: {
|
|
3315
3307
|
jupiterClient: JupiterClient;
|
|
3316
3308
|
outMarketIndex: number;
|
|
3317
3309
|
inMarketIndex: number;
|
|
3318
|
-
outAssociatedTokenAccount
|
|
3319
|
-
inAssociatedTokenAccount
|
|
3310
|
+
outAssociatedTokenAccount?: PublicKey;
|
|
3311
|
+
inAssociatedTokenAccount?: PublicKey;
|
|
3320
3312
|
amount: BN;
|
|
3321
|
-
slippageBps
|
|
3313
|
+
slippageBps?: number;
|
|
3314
|
+
swapMode?: SwapMode;
|
|
3315
|
+
route?: Route;
|
|
3316
|
+
reduceOnly?: SwapReduceOnly;
|
|
3322
3317
|
txParams?: TxParams;
|
|
3323
3318
|
}): Promise<TransactionSignature> {
|
|
3324
3319
|
const outMarket = this.getSpotMarketAccount(outMarketIndex);
|
|
3325
3320
|
const inMarket = this.getSpotMarketAccount(inMarketIndex);
|
|
3326
3321
|
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3322
|
+
if (!route) {
|
|
3323
|
+
const routes = await jupiterClient.getRoutes({
|
|
3324
|
+
inputMint: inMarket.mint,
|
|
3325
|
+
outputMint: outMarket.mint,
|
|
3326
|
+
amount,
|
|
3327
|
+
slippageBps,
|
|
3328
|
+
swapMode,
|
|
3329
|
+
});
|
|
3330
|
+
|
|
3331
|
+
if (!routes || routes.length === 0) {
|
|
3332
|
+
throw new Error('No jupiter routes found');
|
|
3333
|
+
}
|
|
3333
3334
|
|
|
3334
|
-
|
|
3335
|
-
throw new Error('No jupiter routes found');
|
|
3335
|
+
route = routes[0];
|
|
3336
3336
|
}
|
|
3337
3337
|
|
|
3338
|
-
const route = routes[0];
|
|
3339
3338
|
const transaction = await jupiterClient.getSwapTransaction({
|
|
3340
3339
|
route,
|
|
3341
3340
|
userPublicKey: this.provider.wallet.publicKey,
|
|
@@ -3356,7 +3355,8 @@ export class DriftClient {
|
|
|
3356
3355
|
const preInstructions = [];
|
|
3357
3356
|
if (!outAssociatedTokenAccount) {
|
|
3358
3357
|
outAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3359
|
-
outMarket.marketIndex
|
|
3358
|
+
outMarket.marketIndex,
|
|
3359
|
+
false
|
|
3360
3360
|
);
|
|
3361
3361
|
|
|
3362
3362
|
const accountInfo = await this.connection.getAccountInfo(
|
|
@@ -3376,7 +3376,8 @@ export class DriftClient {
|
|
|
3376
3376
|
|
|
3377
3377
|
if (!inAssociatedTokenAccount) {
|
|
3378
3378
|
inAssociatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
3379
|
-
inMarket.marketIndex
|
|
3379
|
+
inMarket.marketIndex,
|
|
3380
|
+
false
|
|
3380
3381
|
);
|
|
3381
3382
|
|
|
3382
3383
|
const accountInfo = await this.connection.getAccountInfo(
|
|
@@ -3400,6 +3401,7 @@ export class DriftClient {
|
|
|
3400
3401
|
amountIn: amount,
|
|
3401
3402
|
inTokenAccount: inAssociatedTokenAccount,
|
|
3402
3403
|
outTokenAccount: outAssociatedTokenAccount,
|
|
3404
|
+
reduceOnly,
|
|
3403
3405
|
});
|
|
3404
3406
|
|
|
3405
3407
|
const instructions = [
|
|
@@ -3440,6 +3442,7 @@ export class DriftClient {
|
|
|
3440
3442
|
inTokenAccount,
|
|
3441
3443
|
outTokenAccount,
|
|
3442
3444
|
limitPrice,
|
|
3445
|
+
reduceOnly,
|
|
3443
3446
|
}: {
|
|
3444
3447
|
outMarketIndex: number;
|
|
3445
3448
|
inMarketIndex: number;
|
|
@@ -3447,6 +3450,7 @@ export class DriftClient {
|
|
|
3447
3450
|
inTokenAccount: PublicKey;
|
|
3448
3451
|
outTokenAccount: PublicKey;
|
|
3449
3452
|
limitPrice?: BN;
|
|
3453
|
+
reduceOnly?: SwapReduceOnly;
|
|
3450
3454
|
}): Promise<{
|
|
3451
3455
|
beginSwapIx: TransactionInstruction;
|
|
3452
3456
|
endSwapIx: TransactionInstruction;
|
|
@@ -3487,6 +3491,7 @@ export class DriftClient {
|
|
|
3487
3491
|
inMarketIndex,
|
|
3488
3492
|
outMarketIndex,
|
|
3489
3493
|
limitPrice ?? null,
|
|
3494
|
+
reduceOnly ?? null,
|
|
3490
3495
|
{
|
|
3491
3496
|
accounts: {
|
|
3492
3497
|
state: await this.getStatePublicKey(),
|
|
@@ -5011,8 +5016,7 @@ export class DriftClient {
|
|
|
5011
5016
|
|
|
5012
5017
|
if (createWSOLTokenAccount) {
|
|
5013
5018
|
tx.add(
|
|
5014
|
-
|
|
5015
|
-
TOKEN_PROGRAM_ID,
|
|
5019
|
+
createCloseAccountInstruction(
|
|
5016
5020
|
tokenAccount,
|
|
5017
5021
|
this.wallet.publicKey,
|
|
5018
5022
|
this.wallet.publicKey,
|
|
@@ -5162,8 +5166,7 @@ export class DriftClient {
|
|
|
5162
5166
|
// Close the wrapped sol account at the end of the transaction
|
|
5163
5167
|
if (createWSOLTokenAccount) {
|
|
5164
5168
|
tx.add(
|
|
5165
|
-
|
|
5166
|
-
TOKEN_PROGRAM_ID,
|
|
5169
|
+
createCloseAccountInstruction(
|
|
5167
5170
|
tokenAccount,
|
|
5168
5171
|
this.wallet.publicKey,
|
|
5169
5172
|
this.wallet.publicKey,
|
|
@@ -5364,7 +5367,8 @@ export class DriftClient {
|
|
|
5364
5367
|
allIx.push(instructions);
|
|
5365
5368
|
}
|
|
5366
5369
|
|
|
5367
|
-
|
|
5370
|
+
txVersion = txVersion ?? this.txVersion;
|
|
5371
|
+
if (txVersion === 'legacy') {
|
|
5368
5372
|
return new Transaction().add(...allIx);
|
|
5369
5373
|
} else {
|
|
5370
5374
|
const marketLookupTable = await this.fetchMarketLookupTableAccount();
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getMarketOrderParams,
|
|
6
6
|
Wallet,
|
|
7
7
|
} from '..';
|
|
8
|
-
import {
|
|
8
|
+
import { getAssociatedTokenAddress } from '@solana/spl-token';
|
|
9
9
|
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
|
10
10
|
import {
|
|
11
11
|
DriftClient,
|
|
@@ -25,9 +25,7 @@ export const getTokenAddress = (
|
|
|
25
25
|
mintAddress: string,
|
|
26
26
|
userPubKey: string
|
|
27
27
|
): Promise<PublicKey> => {
|
|
28
|
-
return
|
|
29
|
-
new PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
|
|
30
|
-
TOKEN_PROGRAM_ID,
|
|
28
|
+
return getAssociatedTokenAddress(
|
|
31
29
|
new PublicKey(mintAddress),
|
|
32
30
|
new PublicKey(userPubKey)
|
|
33
31
|
);
|