@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.14
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/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
- package/lib/accounts/types.d.ts +14 -1
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/pda.d.ts +1 -0
- package/lib/addresses/pda.js +8 -1
- package/lib/admin.d.ts +2 -0
- package/lib/admin.js +18 -0
- package/lib/clearingHouse.d.ts +24 -3
- package/lib/clearingHouse.js +352 -51
- package/lib/clearingHouseConfig.d.ts +1 -0
- package/lib/clearingHouseUser.d.ts +15 -15
- package/lib/clearingHouseUser.js +185 -73
- package/lib/clearingHouseUserStats.d.ts +17 -0
- package/lib/clearingHouseUserStats.js +36 -0
- package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
- package/lib/clearingHouseUserStatsConfig.js +2 -0
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +4 -3
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +37 -11
- package/lib/idl/clearing_house.json +692 -58
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/amm.js +2 -2
- package/lib/math/bankBalance.d.ts +7 -1
- package/lib/math/bankBalance.js +76 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +25 -5
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +43 -12
- package/lib/math/trade.js +2 -2
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +2 -77
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/types.d.ts +78 -10
- package/lib/types.js +12 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +1 -1
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
- package/src/accounts/types.ts +18 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/pda.ts +13 -0
- package/src/admin.ts +29 -1
- package/src/clearingHouse.ts +619 -62
- package/src/clearingHouseConfig.ts +1 -0
- package/src/clearingHouseUser.ts +317 -105
- package/src/clearingHouseUserStats.ts +53 -0
- package/src/clearingHouseUserStatsConfig.ts +18 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +6 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/types.ts +2 -0
- package/src/factory/bigNum.js +37 -11
- package/src/factory/bigNum.ts +43 -13
- package/src/idl/clearing_house.json +692 -58
- package/src/index.ts +1 -0
- package/src/math/amm.ts +8 -5
- package/src/math/bankBalance.ts +147 -1
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/oracles.ts +42 -5
- package/src/math/position.ts +60 -9
- package/src/math/trade.ts +2 -2
- package/src/orders.ts +4 -157
- package/src/tokenFaucet.js +189 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +11 -3
- package/src/types.js +12 -1
- package/src/types.ts +83 -10
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +2 -0
- package/src/accounts/bulkAccountLoader.js +0 -197
- package/src/accounts/bulkUserSubscription.js +0 -33
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
- package/src/accounts/pollingOracleSubscriber.js +0 -93
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
- package/src/accounts/pollingUserAccountSubscriber.js +0 -132
- package/src/accounts/types.js +0 -10
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -93
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
- package/src/addresses/pda.js +0 -104
- package/src/index.js +0 -100
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/mockUSDCFaucet.js +0 -280
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
package/src/orders.ts
CHANGED
|
@@ -1,163 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isVariant,
|
|
3
|
-
MarketAccount,
|
|
4
|
-
Order,
|
|
5
|
-
PositionDirection,
|
|
6
|
-
UserAccount,
|
|
7
|
-
UserPosition,
|
|
8
|
-
} from './types';
|
|
1
|
+
import { isVariant, MarketAccount, Order, PositionDirection } from './types';
|
|
9
2
|
import { BN, standardizeBaseAssetAmount } from '.';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
13
|
-
PEG_PRECISION,
|
|
14
|
-
ZERO,
|
|
15
|
-
} from './constants/numericConstants';
|
|
3
|
+
import { ZERO } from './constants/numericConstants';
|
|
16
4
|
import { calculateMaxBaseAssetAmountToTrade } from './math/amm';
|
|
17
|
-
import {
|
|
18
|
-
findDirectionToClose,
|
|
19
|
-
positionCurrentDirection,
|
|
20
|
-
} from './math/position';
|
|
21
5
|
import { OraclePriceData } from '.';
|
|
22
6
|
|
|
23
|
-
export function calculateNewStateAfterOrder(
|
|
24
|
-
userAccount: UserAccount,
|
|
25
|
-
userPosition: UserPosition,
|
|
26
|
-
market: MarketAccount,
|
|
27
|
-
order: Order
|
|
28
|
-
): [UserAccount, UserPosition, MarketAccount] | null {
|
|
29
|
-
if (isVariant(order.status, 'init')) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(
|
|
34
|
-
market,
|
|
35
|
-
order
|
|
36
|
-
);
|
|
37
|
-
if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const userAccountAfter = Object.assign({}, userAccount);
|
|
42
|
-
const userPositionAfter = Object.assign({}, userPosition);
|
|
43
|
-
|
|
44
|
-
const currentPositionDirection = positionCurrentDirection(userPosition);
|
|
45
|
-
const increasePosition =
|
|
46
|
-
userPosition.baseAssetAmount.eq(ZERO) ||
|
|
47
|
-
isSameDirection(order.direction, currentPositionDirection);
|
|
48
|
-
|
|
49
|
-
if (increasePosition) {
|
|
50
|
-
const marketAfter = calculateNewMarketAfterTrade(
|
|
51
|
-
baseAssetAmountToTrade,
|
|
52
|
-
order.direction,
|
|
53
|
-
market
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } =
|
|
57
|
-
calculateAmountSwapped(market, marketAfter);
|
|
58
|
-
|
|
59
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(
|
|
60
|
-
baseAssetAmountSwapped
|
|
61
|
-
);
|
|
62
|
-
userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(
|
|
63
|
-
quoteAssetAmountSwapped
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
67
|
-
} else {
|
|
68
|
-
const reversePosition = baseAssetAmountToTrade.gt(
|
|
69
|
-
userPosition.baseAssetAmount.abs()
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
if (reversePosition) {
|
|
73
|
-
const intermediateMarket = calculateNewMarketAfterTrade(
|
|
74
|
-
userPosition.baseAssetAmount,
|
|
75
|
-
findDirectionToClose(userPosition),
|
|
76
|
-
market
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
const { quoteAssetAmountSwapped: baseAssetValue } =
|
|
80
|
-
calculateAmountSwapped(market, intermediateMarket);
|
|
81
|
-
|
|
82
|
-
let pnl;
|
|
83
|
-
if (isVariant(currentPositionDirection, 'long')) {
|
|
84
|
-
pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
|
|
85
|
-
} else {
|
|
86
|
-
pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
90
|
-
|
|
91
|
-
const baseAssetAmountLeft = baseAssetAmountToTrade.sub(
|
|
92
|
-
userPosition.baseAssetAmount.abs()
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const marketAfter = calculateNewMarketAfterTrade(
|
|
96
|
-
baseAssetAmountLeft,
|
|
97
|
-
order.direction,
|
|
98
|
-
intermediateMarket
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } =
|
|
102
|
-
calculateAmountSwapped(intermediateMarket, marketAfter);
|
|
103
|
-
|
|
104
|
-
userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
|
|
105
|
-
userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
|
|
106
|
-
|
|
107
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
108
|
-
} else {
|
|
109
|
-
const marketAfter = calculateNewMarketAfterTrade(
|
|
110
|
-
baseAssetAmountToTrade,
|
|
111
|
-
order.direction,
|
|
112
|
-
market
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
const {
|
|
116
|
-
quoteAssetAmountSwapped: baseAssetValue,
|
|
117
|
-
baseAssetAmountSwapped,
|
|
118
|
-
} = calculateAmountSwapped(market, marketAfter);
|
|
119
|
-
|
|
120
|
-
const costBasisRealized = userPosition.quoteAssetAmount
|
|
121
|
-
.mul(baseAssetAmountSwapped.abs())
|
|
122
|
-
.div(userPosition.baseAssetAmount.abs());
|
|
123
|
-
|
|
124
|
-
let pnl;
|
|
125
|
-
if (isVariant(currentPositionDirection, 'long')) {
|
|
126
|
-
pnl = baseAssetValue.sub(costBasisRealized);
|
|
127
|
-
} else {
|
|
128
|
-
pnl = costBasisRealized.sub(baseAssetValue);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
132
|
-
|
|
133
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(
|
|
134
|
-
baseAssetAmountSwapped
|
|
135
|
-
);
|
|
136
|
-
userPositionAfter.quoteAssetAmount =
|
|
137
|
-
userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
|
|
138
|
-
|
|
139
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function calculateAmountSwapped(
|
|
145
|
-
marketBefore: MarketAccount,
|
|
146
|
-
marketAfter: MarketAccount
|
|
147
|
-
): { quoteAssetAmountSwapped: BN; baseAssetAmountSwapped: BN } {
|
|
148
|
-
return {
|
|
149
|
-
quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
|
|
150
|
-
.sub(marketAfter.amm.quoteAssetReserve)
|
|
151
|
-
.abs()
|
|
152
|
-
.mul(marketBefore.amm.pegMultiplier)
|
|
153
|
-
.div(PEG_PRECISION)
|
|
154
|
-
.div(AMM_TO_QUOTE_PRECISION_RATIO),
|
|
155
|
-
baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(
|
|
156
|
-
marketAfter.amm.baseAssetReserve
|
|
157
|
-
),
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
7
|
export function calculateBaseAssetAmountMarketCanExecute(
|
|
162
8
|
market: MarketAccount,
|
|
163
9
|
order: Order,
|
|
@@ -192,7 +38,8 @@ export function calculateAmountToTradeForLimit(
|
|
|
192
38
|
const [maxAmountToTrade, direction] = calculateMaxBaseAssetAmountToTrade(
|
|
193
39
|
market.amm,
|
|
194
40
|
limitPrice,
|
|
195
|
-
order.direction
|
|
41
|
+
order.direction,
|
|
42
|
+
oraclePriceData
|
|
196
43
|
);
|
|
197
44
|
|
|
198
45
|
const baseAssetAmount = standardizeBaseAssetAmount(
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.TokenFaucet = void 0;
|
|
35
|
+
const anchor = __importStar(require("@project-serum/anchor"));
|
|
36
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
37
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
38
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
39
|
+
const token_faucet_json_1 = __importDefault(require("./idl/token_faucet.json"));
|
|
40
|
+
class TokenFaucet {
|
|
41
|
+
constructor(connection, wallet, programId, mint, opts) {
|
|
42
|
+
this.connection = connection;
|
|
43
|
+
this.wallet = wallet;
|
|
44
|
+
this.opts = opts || anchor_1.AnchorProvider.defaultOptions();
|
|
45
|
+
const provider = new anchor_1.AnchorProvider(connection, wallet, this.opts);
|
|
46
|
+
this.provider = provider;
|
|
47
|
+
this.program = new anchor_1.Program(token_faucet_json_1.default, programId, provider);
|
|
48
|
+
this.mint = mint;
|
|
49
|
+
}
|
|
50
|
+
getFaucetConfigPublicKeyAndNonce() {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
return anchor.web3.PublicKey.findProgramAddress([
|
|
53
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('faucet_config')),
|
|
54
|
+
this.mint.toBuffer(),
|
|
55
|
+
], this.program.programId);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
getMintAuthority() {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
return (yield anchor.web3.PublicKey.findProgramAddress([
|
|
61
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('mint_authority')),
|
|
62
|
+
this.mint.toBuffer(),
|
|
63
|
+
], this.program.programId))[0];
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
getFaucetConfigPublicKey() {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
return (yield this.getFaucetConfigPublicKeyAndNonce())[0];
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
initialize() {
|
|
72
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
const [faucetConfigPublicKey] = yield this.getFaucetConfigPublicKeyAndNonce();
|
|
74
|
+
return yield this.program.rpc.initialize({
|
|
75
|
+
accounts: {
|
|
76
|
+
faucetConfig: faucetConfigPublicKey,
|
|
77
|
+
admin: this.wallet.publicKey,
|
|
78
|
+
mintAccount: this.mint,
|
|
79
|
+
rent: web3_js_1.SYSVAR_RENT_PUBKEY,
|
|
80
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
81
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
fetchState() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
return yield this.program.account.faucetConfig.fetch(yield this.getFaucetConfigPublicKey());
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
mintToUserIx(userTokenAccount, amount) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
return this.program.instruction.mintToUser(amount, {
|
|
94
|
+
accounts: {
|
|
95
|
+
faucetConfig: yield this.getFaucetConfigPublicKey(),
|
|
96
|
+
mintAccount: this.mint,
|
|
97
|
+
userTokenAccount,
|
|
98
|
+
mintAuthority: yield this.getMintAuthority(),
|
|
99
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
mintToUser(userTokenAccount, amount) {
|
|
105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
const mintIx = yield this.mintToUserIx(userTokenAccount, amount);
|
|
107
|
+
const tx = new web3_js_1.Transaction().add(mintIx);
|
|
108
|
+
const txSig = yield this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
109
|
+
return txSig;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
transferMintAuthority() {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
return yield this.program.rpc.transferMintAuthority({
|
|
115
|
+
accounts: {
|
|
116
|
+
faucetConfig: yield this.getFaucetConfigPublicKey(),
|
|
117
|
+
mintAccount: this.mint,
|
|
118
|
+
mintAuthority: yield this.getMintAuthority(),
|
|
119
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
120
|
+
admin: this.wallet.publicKey,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
createAssociatedTokenAccountAndMintTo(userPublicKey, amount) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
const tx = new web3_js_1.Transaction();
|
|
128
|
+
const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] = yield this.createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount);
|
|
129
|
+
let associatedTokenAccountExists = false;
|
|
130
|
+
try {
|
|
131
|
+
const assosciatedTokenAccount = yield this.connection.getAccountInfo(associatedTokenPublicKey);
|
|
132
|
+
associatedTokenAccountExists = !!assosciatedTokenAccount;
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
// token account doesn't exist
|
|
136
|
+
associatedTokenAccountExists = false;
|
|
137
|
+
}
|
|
138
|
+
const skipAccountCreation = associatedTokenAccountExists;
|
|
139
|
+
if (!skipAccountCreation)
|
|
140
|
+
tx.add(createAssociatedAccountIx);
|
|
141
|
+
tx.add(mintToTx);
|
|
142
|
+
const txSig = yield this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
143
|
+
return [associatedTokenPublicKey, txSig];
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
const state = yield this.fetchState();
|
|
149
|
+
const associateTokenPublicKey = yield this.getAssosciatedMockUSDMintAddress({ userPubKey: userPublicKey });
|
|
150
|
+
const createAssociatedAccountIx = spl_token_1.Token.createAssociatedTokenAccountInstruction(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.mint, associateTokenPublicKey, userPublicKey, this.wallet.publicKey);
|
|
151
|
+
const mintToIx = yield this.mintToUserIx(associateTokenPublicKey, amount);
|
|
152
|
+
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
getAssosciatedMockUSDMintAddress(props) {
|
|
156
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
+
const state = yield this.fetchState();
|
|
158
|
+
return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.mint, props.userPubKey);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
getTokenAccountInfo(props) {
|
|
162
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
const assosciatedKey = yield this.getAssosciatedMockUSDMintAddress(props);
|
|
164
|
+
const state = yield this.fetchState();
|
|
165
|
+
const token = new spl_token_1.Token(this.connection, state.mint, spl_token_1.TOKEN_PROGRAM_ID,
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
this.provider.payer);
|
|
169
|
+
return yield token.getAccountInfo(assosciatedKey);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
subscribeToTokenAccount(props) {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
try {
|
|
175
|
+
const tokenAccountKey = yield this.getAssosciatedMockUSDMintAddress(props);
|
|
176
|
+
props.callback(yield this.getTokenAccountInfo(props));
|
|
177
|
+
// Couldn't find a way to do it using anchor framework subscription, someone on serum discord recommended this way
|
|
178
|
+
this.connection.onAccountChange(tokenAccountKey, (_accountInfo /* accountInfo is a buffer which we don't know how to deserialize */) => __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
props.callback(yield this.getTokenAccountInfo(props));
|
|
180
|
+
}));
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.TokenFaucet = TokenFaucet;
|
package/src/tokenFaucet.ts
CHANGED
|
@@ -92,11 +92,8 @@ export class TokenFaucet {
|
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
amount: BN
|
|
98
|
-
): Promise<TransactionSignature> {
|
|
99
|
-
return await this.program.rpc.mintToUser(amount, {
|
|
95
|
+
private async mintToUserIx(userTokenAccount: PublicKey, amount: BN) {
|
|
96
|
+
return this.program.instruction.mintToUser(amount, {
|
|
100
97
|
accounts: {
|
|
101
98
|
faucetConfig: await this.getFaucetConfigPublicKey(),
|
|
102
99
|
mintAccount: this.mint,
|
|
@@ -107,6 +104,19 @@ export class TokenFaucet {
|
|
|
107
104
|
});
|
|
108
105
|
}
|
|
109
106
|
|
|
107
|
+
public async mintToUser(
|
|
108
|
+
userTokenAccount: PublicKey,
|
|
109
|
+
amount: BN
|
|
110
|
+
): Promise<TransactionSignature> {
|
|
111
|
+
const mintIx = await this.mintToUserIx(userTokenAccount, amount);
|
|
112
|
+
|
|
113
|
+
const tx = new Transaction().add(mintIx);
|
|
114
|
+
|
|
115
|
+
const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
116
|
+
|
|
117
|
+
return txSig;
|
|
118
|
+
}
|
|
119
|
+
|
|
110
120
|
public async transferMintAuthority(): Promise<TransactionSignature> {
|
|
111
121
|
return await this.program.rpc.transferMintAuthority({
|
|
112
122
|
accounts: {
|
|
@@ -123,12 +133,33 @@ export class TokenFaucet {
|
|
|
123
133
|
userPublicKey: PublicKey,
|
|
124
134
|
amount: BN
|
|
125
135
|
): Promise<[PublicKey, TransactionSignature]> {
|
|
136
|
+
const tx = new Transaction();
|
|
137
|
+
|
|
126
138
|
const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] =
|
|
127
139
|
await this.createAssociatedTokenAccountAndMintToInstructions(
|
|
128
140
|
userPublicKey,
|
|
129
141
|
amount
|
|
130
142
|
);
|
|
131
|
-
|
|
143
|
+
|
|
144
|
+
let associatedTokenAccountExists = false;
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const assosciatedTokenAccount = await this.connection.getAccountInfo(
|
|
148
|
+
associatedTokenPublicKey
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
associatedTokenAccountExists = !!assosciatedTokenAccount;
|
|
152
|
+
} catch (e) {
|
|
153
|
+
// token account doesn't exist
|
|
154
|
+
associatedTokenAccountExists = false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const skipAccountCreation = associatedTokenAccountExists;
|
|
158
|
+
|
|
159
|
+
if (!skipAccountCreation) tx.add(createAssociatedAccountIx);
|
|
160
|
+
|
|
161
|
+
tx.add(mintToTx);
|
|
162
|
+
|
|
132
163
|
const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
133
164
|
return [associatedTokenPublicKey, txSig];
|
|
134
165
|
}
|
|
@@ -153,15 +184,7 @@ export class TokenFaucet {
|
|
|
153
184
|
this.wallet.publicKey
|
|
154
185
|
);
|
|
155
186
|
|
|
156
|
-
const mintToIx = await this.
|
|
157
|
-
accounts: {
|
|
158
|
-
faucetConfig: await this.getFaucetConfigPublicKey(),
|
|
159
|
-
mintAccount: state.mint,
|
|
160
|
-
userTokenAccount: associateTokenPublicKey,
|
|
161
|
-
mintAuthority: state.mintAuthority,
|
|
162
|
-
tokenProgram: TOKEN_PROGRAM_ID,
|
|
163
|
-
},
|
|
164
|
-
});
|
|
187
|
+
const mintToIx = await this.mintToUserIx(associateTokenPublicKey, amount);
|
|
165
188
|
|
|
166
189
|
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
|
|
167
190
|
}
|
package/src/tx/retryTxSender.ts
CHANGED
|
@@ -56,9 +56,17 @@ export class RetryTxSender implements TxSender {
|
|
|
56
56
|
const rawTransaction = tx.serialize();
|
|
57
57
|
const startTime = this.getTimestamp();
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
let txid: TransactionSignature;
|
|
60
|
+
try {
|
|
61
|
+
txid = await this.provider.connection.sendRawTransaction(
|
|
62
|
+
rawTransaction,
|
|
63
|
+
opts
|
|
64
|
+
);
|
|
65
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.error(e);
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
62
70
|
|
|
63
71
|
let done = false;
|
|
64
72
|
const resolveReference: ResolveReference = {
|
package/src/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DefaultOrderParams = exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
|
|
3
|
+
exports.DefaultOrderParams = exports.LiquidationType = exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
5
|
// # Utility Types / Enums / Constants
|
|
6
6
|
class SwapDirection {
|
|
@@ -91,6 +91,17 @@ var TradeSide;
|
|
|
91
91
|
TradeSide[TradeSide["Buy"] = 1] = "Buy";
|
|
92
92
|
TradeSide[TradeSide["Sell"] = 2] = "Sell";
|
|
93
93
|
})(TradeSide = exports.TradeSide || (exports.TradeSide = {}));
|
|
94
|
+
class LiquidationType {
|
|
95
|
+
}
|
|
96
|
+
exports.LiquidationType = LiquidationType;
|
|
97
|
+
LiquidationType.LIQUIDATE_PERP = { liquidatePerp: {} };
|
|
98
|
+
LiquidationType.LIQUIDATE_BORROW = { liquidateBorrow: {} };
|
|
99
|
+
LiquidationType.LIQUIDATE_BORROW_FOR_PERP_PNL = {
|
|
100
|
+
liquidateBorrowForPerpPnl: {},
|
|
101
|
+
};
|
|
102
|
+
LiquidationType.LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
|
|
103
|
+
liquidatePerpPnlForDeposit: {},
|
|
104
|
+
};
|
|
94
105
|
exports.DefaultOrderParams = {
|
|
95
106
|
orderType: OrderType.MARKET,
|
|
96
107
|
userOrderId: 0,
|
package/src/types.ts
CHANGED
|
@@ -67,6 +67,12 @@ export class OrderActionExplanation {
|
|
|
67
67
|
static readonly MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
|
|
68
68
|
marketOrderFilledToLimitPrice: {},
|
|
69
69
|
};
|
|
70
|
+
static readonly CANCELED_FOR_LIQUIDATION = {
|
|
71
|
+
canceledForLiquidation: {},
|
|
72
|
+
};
|
|
73
|
+
static readonly MARKET_ORDER_AUCTION_EXPIRED = {
|
|
74
|
+
marketOrderAuctionExpired: {},
|
|
75
|
+
};
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
export class OrderTriggerCondition {
|
|
@@ -166,10 +172,13 @@ export type LiquidationRecord = {
|
|
|
166
172
|
liquidationType: LiquidationType;
|
|
167
173
|
marginRequirement: BN;
|
|
168
174
|
totalCollateral: BN;
|
|
175
|
+
liquidationId: number;
|
|
169
176
|
liquidatePerp: LiquidatePerpRecord;
|
|
170
177
|
liquidateBorrow: LiquidateBorrowRecord;
|
|
171
178
|
liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
|
|
172
179
|
liquidatePerpPnlForDeposit: LiquidatePerpPnlForDepositRecord;
|
|
180
|
+
perpBankruptcy: PerpBankruptcyRecord;
|
|
181
|
+
borrowBankruptcy: BorrowBankruptcyRecord;
|
|
173
182
|
};
|
|
174
183
|
|
|
175
184
|
export class LiquidationType {
|
|
@@ -181,6 +190,12 @@ export class LiquidationType {
|
|
|
181
190
|
static readonly LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
|
|
182
191
|
liquidatePerpPnlForDeposit: {},
|
|
183
192
|
};
|
|
193
|
+
static readonly PERP_BANKRUPTCY = {
|
|
194
|
+
perpBankruptcy: {},
|
|
195
|
+
};
|
|
196
|
+
static readonly BORROW_BANKRUPTCY = {
|
|
197
|
+
borrowBankruptcy: {},
|
|
198
|
+
};
|
|
184
199
|
}
|
|
185
200
|
|
|
186
201
|
export type LiquidatePerpRecord = {
|
|
@@ -224,14 +239,37 @@ export type LiquidatePerpPnlForDepositRecord = {
|
|
|
224
239
|
assetTransfer: BN;
|
|
225
240
|
};
|
|
226
241
|
|
|
242
|
+
export type PerpBankruptcyRecord = {
|
|
243
|
+
marketIndex: BN;
|
|
244
|
+
pnl: BN;
|
|
245
|
+
cumulativeFundingRateDelta: BN;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export type BorrowBankruptcyRecord = {
|
|
249
|
+
bankIndex: BN;
|
|
250
|
+
borrowAmount: BN;
|
|
251
|
+
cumulativeDepositInterestDelta: BN;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export type SettlePnlRecord = {
|
|
255
|
+
ts: BN;
|
|
256
|
+
user: PublicKey;
|
|
257
|
+
marketIndex: BN;
|
|
258
|
+
pnl: BN;
|
|
259
|
+
baseAssetAmount: BN;
|
|
260
|
+
quoteAssetAmountAfter: BN;
|
|
261
|
+
quoteEntryamount: BN;
|
|
262
|
+
settlePrice: BN;
|
|
263
|
+
};
|
|
264
|
+
|
|
227
265
|
export type OrderRecord = {
|
|
228
266
|
ts: BN;
|
|
229
267
|
taker: PublicKey;
|
|
230
268
|
maker: PublicKey;
|
|
231
269
|
takerOrder: Order;
|
|
232
270
|
makerOrder: Order;
|
|
233
|
-
|
|
234
|
-
|
|
271
|
+
takerPnl: BN;
|
|
272
|
+
makerPnl: BN;
|
|
235
273
|
action: OrderAction;
|
|
236
274
|
actionExplanation: OrderActionExplanation;
|
|
237
275
|
filler: PublicKey;
|
|
@@ -291,6 +329,10 @@ export type MarketAccount = {
|
|
|
291
329
|
nextFillRecordId: BN;
|
|
292
330
|
pnlPool: PoolBalance;
|
|
293
331
|
liquidationFee: BN;
|
|
332
|
+
imfFactor: BN;
|
|
333
|
+
unsettledImfFactor: BN;
|
|
334
|
+
unsettledInitialAssetWeight: number;
|
|
335
|
+
unsettledMaintenanceAssetWeight: number;
|
|
294
336
|
};
|
|
295
337
|
|
|
296
338
|
export type BankAccount = {
|
|
@@ -315,6 +357,12 @@ export type BankAccount = {
|
|
|
315
357
|
initialLiabilityWeight: BN;
|
|
316
358
|
maintenanceLiabilityWeight: BN;
|
|
317
359
|
liquidationFee: BN;
|
|
360
|
+
imfFactor: BN;
|
|
361
|
+
|
|
362
|
+
withdrawGuardThreshold: BN;
|
|
363
|
+
depositTokenTwap: BN;
|
|
364
|
+
borrowTokenTwap: BN;
|
|
365
|
+
utilizationTwap: BN;
|
|
318
366
|
};
|
|
319
367
|
|
|
320
368
|
export type PoolBalance = {
|
|
@@ -328,8 +376,10 @@ export type AMM = {
|
|
|
328
376
|
lastFundingRate: BN;
|
|
329
377
|
lastFundingRateTs: BN;
|
|
330
378
|
lastMarkPriceTwap: BN;
|
|
379
|
+
lastMarkPriceTwap5min: BN;
|
|
331
380
|
lastMarkPriceTwapTs: BN;
|
|
332
381
|
lastOraclePriceTwap: BN;
|
|
382
|
+
lastOraclePriceTwap5min: BN;
|
|
333
383
|
lastOraclePriceTwapTs: BN;
|
|
334
384
|
lastOracleMarkSpreadPct: BN;
|
|
335
385
|
lastOracleConfPct: BN;
|
|
@@ -340,11 +390,16 @@ export type AMM = {
|
|
|
340
390
|
pegMultiplier: BN;
|
|
341
391
|
cumulativeFundingRateLong: BN;
|
|
342
392
|
cumulativeFundingRateShort: BN;
|
|
393
|
+
cumulativeFundingRateLp: BN;
|
|
343
394
|
cumulativeRepegRebateLong: BN;
|
|
344
395
|
cumulativeRepegRebateShort: BN;
|
|
345
396
|
totalFeeMinusDistributions: BN;
|
|
346
397
|
totalFeeWithdrawn: BN;
|
|
347
398
|
totalFee: BN;
|
|
399
|
+
cumulativeFundingPaymentPerLp: BN;
|
|
400
|
+
cumulativeFeePerLp: BN;
|
|
401
|
+
cumulativeNetBaseAssetAmountPerLp: BN;
|
|
402
|
+
userLpShares: BN;
|
|
348
403
|
minimumQuoteAssetTradeSize: BN;
|
|
349
404
|
baseAssetAmountStepSize: BN;
|
|
350
405
|
maxBaseAssetAmountRatio: number;
|
|
@@ -366,6 +421,8 @@ export type AMM = {
|
|
|
366
421
|
longSpread: BN;
|
|
367
422
|
shortSpread: BN;
|
|
368
423
|
maxSpread: number;
|
|
424
|
+
marketPosition: UserPosition;
|
|
425
|
+
marketPositionPerLp: UserPosition;
|
|
369
426
|
};
|
|
370
427
|
|
|
371
428
|
// # User Account Types
|
|
@@ -376,18 +433,23 @@ export type UserPosition = {
|
|
|
376
433
|
quoteAssetAmount: BN;
|
|
377
434
|
quoteEntryAmount: BN;
|
|
378
435
|
openOrders: BN;
|
|
379
|
-
unsettledPnl: BN;
|
|
380
436
|
openBids: BN;
|
|
381
437
|
openAsks: BN;
|
|
438
|
+
realizedPnl: BN;
|
|
439
|
+
lpShares: BN;
|
|
440
|
+
lastFeePerLp: BN;
|
|
441
|
+
lastNetBaseAssetAmountPerLp: BN;
|
|
442
|
+
lastNetQuoteAssetAmountPerLp: BN;
|
|
382
443
|
};
|
|
383
444
|
|
|
384
|
-
export type
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
445
|
+
export type UserStatsAccount = {
|
|
446
|
+
numberOfUsers: number;
|
|
447
|
+
makerVolume30D: BN;
|
|
448
|
+
takerVolume30D: BN;
|
|
449
|
+
fillerVolume30D: BN;
|
|
450
|
+
lastMakerVolume30DTs: BN;
|
|
451
|
+
lastTakerVolume30DTs: BN;
|
|
452
|
+
lastFillerVolume30DTs: BN;
|
|
391
453
|
fees: {
|
|
392
454
|
totalFeePaid: BN;
|
|
393
455
|
totalFeeRebate: BN;
|
|
@@ -395,9 +457,18 @@ export type UserAccount = {
|
|
|
395
457
|
totalReferralReward: BN;
|
|
396
458
|
totalRefereeDiscount: BN;
|
|
397
459
|
};
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
export type UserAccount = {
|
|
463
|
+
authority: PublicKey;
|
|
464
|
+
name: number[];
|
|
465
|
+
userId: number;
|
|
466
|
+
bankBalances: UserBankBalance[];
|
|
398
467
|
positions: UserPosition[];
|
|
399
468
|
orders: Order[];
|
|
400
469
|
beingLiquidated: boolean;
|
|
470
|
+
bankrupt: boolean;
|
|
471
|
+
nextLiquidationId: number;
|
|
401
472
|
};
|
|
402
473
|
|
|
403
474
|
export type UserBankBalance = {
|
|
@@ -493,11 +564,13 @@ export const DefaultOrderParams = {
|
|
|
493
564
|
|
|
494
565
|
export type MakerInfo = {
|
|
495
566
|
maker: PublicKey;
|
|
567
|
+
makerStats: PublicKey;
|
|
496
568
|
order: Order;
|
|
497
569
|
};
|
|
498
570
|
|
|
499
571
|
export type TakerInfo = {
|
|
500
572
|
taker: PublicKey;
|
|
573
|
+
takerStats: PublicKey;
|
|
501
574
|
order: Order;
|
|
502
575
|
};
|
|
503
576
|
|