@drift-labs/sdk 2.30.0-beta.1 → 2.30.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/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 +23 -1
- 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 +15 -2
- package/lib/types.js +6 -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/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 +23 -1
- 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 +16 -2
- package/src/wallet.ts +34 -12
- 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/token/index.js
CHANGED
|
@@ -2,37 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseTokenAccount = void 0;
|
|
4
4
|
const spl_token_1 = require("@solana/spl-token");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const accountInfo =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(Buffer.from('0'));
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
|
|
18
|
-
accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount);
|
|
19
|
-
}
|
|
20
|
-
accountInfo.isInitialized = accountInfo.state !== 0;
|
|
21
|
-
accountInfo.isFrozen = accountInfo.state === 2;
|
|
22
|
-
if (accountInfo.isNativeOption === 1) {
|
|
23
|
-
accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative);
|
|
24
|
-
accountInfo.isNative = true;
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
accountInfo.rentExemptReserve = null;
|
|
28
|
-
accountInfo.isNative = false;
|
|
29
|
-
}
|
|
30
|
-
if (accountInfo.closeAuthorityOption === 0) {
|
|
31
|
-
accountInfo.closeAuthority = null;
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority);
|
|
35
|
-
}
|
|
36
|
-
return accountInfo;
|
|
5
|
+
function parseTokenAccount(data, pubkey) {
|
|
6
|
+
// mock AccountInfo so unpackAccount can be used
|
|
7
|
+
const accountInfo = {
|
|
8
|
+
data,
|
|
9
|
+
owner: spl_token_1.TOKEN_PROGRAM_ID,
|
|
10
|
+
executable: false,
|
|
11
|
+
lamports: 0,
|
|
12
|
+
};
|
|
13
|
+
return (0, spl_token_1.unpackAccount)(pubkey, accountInfo, spl_token_1.TOKEN_PROGRAM_ID);
|
|
37
14
|
}
|
|
38
15
|
exports.parseTokenAccount = parseTokenAccount;
|
package/lib/tokenFaucet.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as anchor from '@coral-xyz/anchor';
|
|
2
2
|
import { AnchorProvider, Program } from '@coral-xyz/anchor';
|
|
3
|
-
import {
|
|
3
|
+
import { Account } from '@solana/spl-token';
|
|
4
4
|
import { ConfirmOptions, Connection, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
5
5
|
import { BN } from '.';
|
|
6
6
|
import { IWallet } from './types';
|
|
@@ -30,9 +30,9 @@ export declare class TokenFaucet {
|
|
|
30
30
|
}): Promise<anchor.web3.PublicKey>;
|
|
31
31
|
getTokenAccountInfo(props: {
|
|
32
32
|
userPubKey: PublicKey;
|
|
33
|
-
}): Promise<
|
|
33
|
+
}): Promise<Account>;
|
|
34
34
|
subscribeToTokenAccount(props: {
|
|
35
35
|
userPubKey: PublicKey;
|
|
36
|
-
callback: (accountInfo:
|
|
36
|
+
callback: (accountInfo: Account) => void;
|
|
37
37
|
}): Promise<boolean>;
|
|
38
38
|
}
|
package/lib/tokenFaucet.js
CHANGED
|
@@ -123,22 +123,17 @@ class TokenFaucet {
|
|
|
123
123
|
async createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount) {
|
|
124
124
|
const state = await this.fetchState();
|
|
125
125
|
const associateTokenPublicKey = await this.getAssosciatedMockUSDMintAddress({ userPubKey: userPublicKey });
|
|
126
|
-
const createAssociatedAccountIx = spl_token_1.
|
|
126
|
+
const createAssociatedAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associateTokenPublicKey, userPublicKey, state.mint);
|
|
127
127
|
const mintToIx = await this.mintToUserIx(associateTokenPublicKey, amount);
|
|
128
128
|
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
|
|
129
129
|
}
|
|
130
130
|
async getAssosciatedMockUSDMintAddress(props) {
|
|
131
131
|
const state = await this.fetchState();
|
|
132
|
-
return
|
|
132
|
+
return (0, spl_token_1.getAssociatedTokenAddress)(state.mint, props.userPubKey);
|
|
133
133
|
}
|
|
134
134
|
async getTokenAccountInfo(props) {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const token = new spl_token_1.Token(this.connection, state.mint, spl_token_1.TOKEN_PROGRAM_ID,
|
|
138
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
139
|
-
// @ts-ignore
|
|
140
|
-
this.provider.payer);
|
|
141
|
-
return await token.getAccountInfo(assosciatedKey);
|
|
135
|
+
const associatedKey = await this.getAssosciatedMockUSDMintAddress(props);
|
|
136
|
+
return await (0, spl_token_1.getAccount)(this.connection, associatedKey);
|
|
142
137
|
}
|
|
143
138
|
async subscribeToTokenAccount(props) {
|
|
144
139
|
try {
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -57,6 +57,9 @@ class RetryTxSender {
|
|
|
57
57
|
async sendVersionedTransaction(tx, additionalSigners, opts) {
|
|
58
58
|
// @ts-ignore
|
|
59
59
|
tx.sign((additionalSigners !== null && additionalSigners !== void 0 ? additionalSigners : []).concat(this.provider.wallet.payer));
|
|
60
|
+
if (opts === undefined) {
|
|
61
|
+
opts = this.provider.opts;
|
|
62
|
+
}
|
|
60
63
|
return this.sendRawTransaction(tx.serialize(), opts);
|
|
61
64
|
}
|
|
62
65
|
async sendRawTransaction(rawTransaction, opts) {
|
package/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublicKey, Transaction } from '@solana/web3.js';
|
|
1
|
+
import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
2
2
|
import { BN } from '.';
|
|
3
3
|
export declare enum ExchangeStatus {
|
|
4
4
|
ACTIVE = 0,
|
|
@@ -585,7 +585,7 @@ export type OrderActionRecord = {
|
|
|
585
585
|
oraclePrice: BN;
|
|
586
586
|
};
|
|
587
587
|
export type SwapRecord = {
|
|
588
|
-
ts:
|
|
588
|
+
ts: BN;
|
|
589
589
|
user: PublicKey;
|
|
590
590
|
amountOut: BN;
|
|
591
591
|
amountIn: BN;
|
|
@@ -979,11 +979,24 @@ export type TxParams = {
|
|
|
979
979
|
computeUnits?: number;
|
|
980
980
|
computeUnitsPrice?: number;
|
|
981
981
|
};
|
|
982
|
+
export declare class SwapReduceOnly {
|
|
983
|
+
static readonly In: {
|
|
984
|
+
in: {};
|
|
985
|
+
};
|
|
986
|
+
static readonly Out: {
|
|
987
|
+
out: {};
|
|
988
|
+
};
|
|
989
|
+
}
|
|
982
990
|
export interface IWallet {
|
|
983
991
|
signTransaction(tx: Transaction): Promise<Transaction>;
|
|
984
992
|
signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
|
|
985
993
|
publicKey: PublicKey;
|
|
986
994
|
}
|
|
995
|
+
export interface IVersionedWallet {
|
|
996
|
+
signVersionedTransaction(tx: VersionedTransaction): Promise<VersionedTransaction>;
|
|
997
|
+
signAllVersionedTransactions(txs: VersionedTransaction[]): Promise<VersionedTransaction[]>;
|
|
998
|
+
publicKey: PublicKey;
|
|
999
|
+
}
|
|
987
1000
|
export type FeeStructure = {
|
|
988
1001
|
feeTiers: FeeTier[];
|
|
989
1002
|
makerRebateNumerator: BN;
|
package/lib/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.PostOnlyParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.UserStatus = exports.MarketStatus = exports.ExchangeStatus = void 0;
|
|
3
|
+
exports.SwapReduceOnly = exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.PostOnlyParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.UserStatus = exports.MarketStatus = exports.ExchangeStatus = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
5
|
// # Utility Types / Enums / Constants
|
|
6
6
|
var ExchangeStatus;
|
|
@@ -266,3 +266,8 @@ exports.DefaultOrderParams = {
|
|
|
266
266
|
auctionStartPrice: null,
|
|
267
267
|
auctionEndPrice: null,
|
|
268
268
|
};
|
|
269
|
+
class SwapReduceOnly {
|
|
270
|
+
}
|
|
271
|
+
exports.SwapReduceOnly = SwapReduceOnly;
|
|
272
|
+
SwapReduceOnly.In = { in: {} };
|
|
273
|
+
SwapReduceOnly.Out = { out: {} };
|
package/lib/wallet.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Keypair, PublicKey, Transaction } from '@solana/web3.js';
|
|
2
|
-
import { IWallet } from './types';
|
|
3
|
-
export declare class Wallet implements IWallet {
|
|
1
|
+
import { Keypair, PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import { IWallet, IVersionedWallet } from './types';
|
|
3
|
+
export declare class Wallet implements IWallet, IVersionedWallet {
|
|
4
4
|
readonly payer: Keypair;
|
|
5
5
|
constructor(payer: Keypair);
|
|
6
6
|
signTransaction(tx: Transaction): Promise<Transaction>;
|
|
7
|
+
signVersionedTransaction(tx: VersionedTransaction): Promise<VersionedTransaction>;
|
|
7
8
|
signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
|
|
9
|
+
signAllVersionedTransactions(txs: VersionedTransaction[]): Promise<VersionedTransaction[]>;
|
|
8
10
|
get publicKey(): PublicKey;
|
|
9
11
|
}
|
|
10
12
|
export declare function loadKeypair(privateKey: string): Keypair;
|
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.30.0
|
|
3
|
+
"version": "2.30.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 {
|
|
@@ -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
|
}
|