@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/mockUSDCFaucet.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
var __createBinding =
|
|
3
|
-
(this && this.__createBinding) ||
|
|
4
|
-
(Object.create
|
|
5
|
-
? function (o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
Object.defineProperty(o, k2, {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
get: function () {
|
|
10
|
-
return m[k];
|
|
11
|
-
},
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
: function (o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
});
|
|
18
|
-
var __setModuleDefault =
|
|
19
|
-
(this && this.__setModuleDefault) ||
|
|
20
|
-
(Object.create
|
|
21
|
-
? function (o, v) {
|
|
22
|
-
Object.defineProperty(o, 'default', { enumerable: true, value: v });
|
|
23
|
-
}
|
|
24
|
-
: function (o, v) {
|
|
25
|
-
o['default'] = v;
|
|
26
|
-
});
|
|
27
|
-
var __importStar =
|
|
28
|
-
(this && this.__importStar) ||
|
|
29
|
-
function (mod) {
|
|
30
|
-
if (mod && mod.__esModule) return mod;
|
|
31
|
-
var result = {};
|
|
32
|
-
if (mod != null)
|
|
33
|
-
for (var k in mod)
|
|
34
|
-
if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k))
|
|
35
|
-
__createBinding(result, mod, k);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
var __awaiter =
|
|
40
|
-
(this && this.__awaiter) ||
|
|
41
|
-
function (thisArg, _arguments, P, generator) {
|
|
42
|
-
function adopt(value) {
|
|
43
|
-
return value instanceof P
|
|
44
|
-
? value
|
|
45
|
-
: new P(function (resolve) {
|
|
46
|
-
resolve(value);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
50
|
-
function fulfilled(value) {
|
|
51
|
-
try {
|
|
52
|
-
step(generator.next(value));
|
|
53
|
-
} catch (e) {
|
|
54
|
-
reject(e);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function rejected(value) {
|
|
58
|
-
try {
|
|
59
|
-
step(generator['throw'](value));
|
|
60
|
-
} catch (e) {
|
|
61
|
-
reject(e);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function step(result) {
|
|
65
|
-
result.done
|
|
66
|
-
? resolve(result.value)
|
|
67
|
-
: adopt(result.value).then(fulfilled, rejected);
|
|
68
|
-
}
|
|
69
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
var __importDefault =
|
|
73
|
-
(this && this.__importDefault) ||
|
|
74
|
-
function (mod) {
|
|
75
|
-
return mod && mod.__esModule ? mod : { default: mod };
|
|
76
|
-
};
|
|
77
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
78
|
-
exports.MockUSDCFaucet = void 0;
|
|
79
|
-
const anchor = __importStar(require('@project-serum/anchor'));
|
|
80
|
-
const anchor_1 = require('@project-serum/anchor');
|
|
81
|
-
const spl_token_1 = require('@solana/spl-token');
|
|
82
|
-
const web3_js_1 = require('@solana/web3.js');
|
|
83
|
-
const mock_usdc_faucet_json_1 = __importDefault(
|
|
84
|
-
require('./idl/token_faucet.json')
|
|
85
|
-
);
|
|
86
|
-
class MockUSDCFaucet {
|
|
87
|
-
constructor(connection, wallet, programId, opts) {
|
|
88
|
-
this.connection = connection;
|
|
89
|
-
this.wallet = wallet;
|
|
90
|
-
this.opts = opts || anchor_1.AnchorProvider.defaultOptions();
|
|
91
|
-
const provider = new anchor_1.AnchorProvider(connection, wallet, this.opts);
|
|
92
|
-
this.provider = provider;
|
|
93
|
-
this.program = new anchor_1.Program(
|
|
94
|
-
mock_usdc_faucet_json_1.default,
|
|
95
|
-
programId,
|
|
96
|
-
provider
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
getMockUSDCFaucetStatePublicKeyAndNonce() {
|
|
100
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
return anchor.web3.PublicKey.findProgramAddress(
|
|
102
|
-
[Buffer.from(anchor.utils.bytes.utf8.encode('mock_usdc_faucet'))],
|
|
103
|
-
this.program.programId
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
getMockUSDCFaucetStatePublicKey() {
|
|
108
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
-
if (this.mockUSDCFaucetStatePublicKey) {
|
|
110
|
-
return this.mockUSDCFaucetStatePublicKey;
|
|
111
|
-
}
|
|
112
|
-
this.mockUSDCFaucetStatePublicKey =
|
|
113
|
-
(yield this.getMockUSDCFaucetStatePublicKeyAndNonce())[0];
|
|
114
|
-
return this.mockUSDCFaucetStatePublicKey;
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
initialize() {
|
|
118
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
119
|
-
const stateAccountRPCResponse =
|
|
120
|
-
yield this.connection.getParsedAccountInfo(
|
|
121
|
-
yield this.getMockUSDCFaucetStatePublicKey()
|
|
122
|
-
);
|
|
123
|
-
if (stateAccountRPCResponse.value !== null) {
|
|
124
|
-
throw new Error('Faucet already initialized');
|
|
125
|
-
}
|
|
126
|
-
const fakeUSDCMint = anchor.web3.Keypair.generate();
|
|
127
|
-
const createUSDCMintAccountIx = web3_js_1.SystemProgram.createAccount({
|
|
128
|
-
fromPubkey: this.wallet.publicKey,
|
|
129
|
-
newAccountPubkey: fakeUSDCMint.publicKey,
|
|
130
|
-
lamports: yield spl_token_1.Token.getMinBalanceRentForExemptMint(
|
|
131
|
-
this.connection
|
|
132
|
-
),
|
|
133
|
-
space: spl_token_1.MintLayout.span,
|
|
134
|
-
programId: spl_token_1.TOKEN_PROGRAM_ID,
|
|
135
|
-
});
|
|
136
|
-
const [mintAuthority, _mintAuthorityNonce] =
|
|
137
|
-
yield web3_js_1.PublicKey.findProgramAddress(
|
|
138
|
-
[fakeUSDCMint.publicKey.toBuffer()],
|
|
139
|
-
this.program.programId
|
|
140
|
-
);
|
|
141
|
-
const initUSDCMintIx = spl_token_1.Token.createInitMintInstruction(
|
|
142
|
-
spl_token_1.TOKEN_PROGRAM_ID,
|
|
143
|
-
fakeUSDCMint.publicKey,
|
|
144
|
-
6,
|
|
145
|
-
mintAuthority,
|
|
146
|
-
null
|
|
147
|
-
);
|
|
148
|
-
const [mockUSDCFaucetStatePublicKey, mockUSDCFaucetStateNonce] =
|
|
149
|
-
yield this.getMockUSDCFaucetStatePublicKeyAndNonce();
|
|
150
|
-
return yield this.program.rpc.initialize(mockUSDCFaucetStateNonce, {
|
|
151
|
-
accounts: {
|
|
152
|
-
mockUsdcFaucetState: mockUSDCFaucetStatePublicKey,
|
|
153
|
-
admin: this.wallet.publicKey,
|
|
154
|
-
mintAccount: fakeUSDCMint.publicKey,
|
|
155
|
-
rent: web3_js_1.SYSVAR_RENT_PUBKEY,
|
|
156
|
-
systemProgram: anchor.web3.SystemProgram.programId,
|
|
157
|
-
},
|
|
158
|
-
instructions: [createUSDCMintAccountIx, initUSDCMintIx],
|
|
159
|
-
signers: [fakeUSDCMint],
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
fetchState() {
|
|
164
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
-
return yield this.program.account.mockUsdcFaucetState.fetch(
|
|
166
|
-
yield this.getMockUSDCFaucetStatePublicKey()
|
|
167
|
-
);
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
mintToUser(userTokenAccount, amount) {
|
|
171
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
-
const state = yield this.fetchState();
|
|
173
|
-
return yield this.program.rpc.mintToUser(amount, {
|
|
174
|
-
accounts: {
|
|
175
|
-
mockUsdcFaucetState: yield this.getMockUSDCFaucetStatePublicKey(),
|
|
176
|
-
mintAccount: state.mint,
|
|
177
|
-
userTokenAccount,
|
|
178
|
-
mintAuthority: state.mintAuthority,
|
|
179
|
-
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
createAssociatedTokenAccountAndMintTo(userPublicKey, amount) {
|
|
185
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] =
|
|
187
|
-
yield this.createAssociatedTokenAccountAndMintToInstructions(
|
|
188
|
-
userPublicKey,
|
|
189
|
-
amount
|
|
190
|
-
);
|
|
191
|
-
const tx = new web3_js_1.Transaction()
|
|
192
|
-
.add(createAssociatedAccountIx)
|
|
193
|
-
.add(mintToTx);
|
|
194
|
-
const txSig = yield this.program.provider.sendAndConfirm(
|
|
195
|
-
tx,
|
|
196
|
-
[],
|
|
197
|
-
this.opts
|
|
198
|
-
);
|
|
199
|
-
return [associatedTokenPublicKey, txSig];
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount) {
|
|
203
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
204
|
-
const state = yield this.fetchState();
|
|
205
|
-
const associateTokenPublicKey =
|
|
206
|
-
yield this.getAssosciatedMockUSDMintAddress({
|
|
207
|
-
userPubKey: userPublicKey,
|
|
208
|
-
});
|
|
209
|
-
const createAssociatedAccountIx =
|
|
210
|
-
spl_token_1.Token.createAssociatedTokenAccountInstruction(
|
|
211
|
-
spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
212
|
-
spl_token_1.TOKEN_PROGRAM_ID,
|
|
213
|
-
state.mint,
|
|
214
|
-
associateTokenPublicKey,
|
|
215
|
-
userPublicKey,
|
|
216
|
-
this.wallet.publicKey
|
|
217
|
-
);
|
|
218
|
-
const mintToIx = yield this.program.instruction.mintToUser(amount, {
|
|
219
|
-
accounts: {
|
|
220
|
-
mockUsdcFaucetState: yield this.getMockUSDCFaucetStatePublicKey(),
|
|
221
|
-
mintAccount: state.mint,
|
|
222
|
-
userTokenAccount: associateTokenPublicKey,
|
|
223
|
-
mintAuthority: state.mintAuthority,
|
|
224
|
-
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
getAssosciatedMockUSDMintAddress(props) {
|
|
231
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
-
const state = yield this.fetchState();
|
|
233
|
-
return spl_token_1.Token.getAssociatedTokenAddress(
|
|
234
|
-
spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
235
|
-
spl_token_1.TOKEN_PROGRAM_ID,
|
|
236
|
-
state.mint,
|
|
237
|
-
props.userPubKey
|
|
238
|
-
);
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
getTokenAccountInfo(props) {
|
|
242
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
243
|
-
const assosciatedKey = yield this.getAssosciatedMockUSDMintAddress(props);
|
|
244
|
-
const state = yield this.fetchState();
|
|
245
|
-
const token = new spl_token_1.Token(
|
|
246
|
-
this.connection,
|
|
247
|
-
state.mint,
|
|
248
|
-
spl_token_1.TOKEN_PROGRAM_ID,
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
250
|
-
// @ts-ignore
|
|
251
|
-
this.provider.payer
|
|
252
|
-
);
|
|
253
|
-
return yield token.getAccountInfo(assosciatedKey);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
subscribeToTokenAccount(props) {
|
|
257
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
258
|
-
try {
|
|
259
|
-
const tokenAccountKey = yield this.getAssosciatedMockUSDMintAddress(
|
|
260
|
-
props
|
|
261
|
-
);
|
|
262
|
-
props.callback(yield this.getTokenAccountInfo(props));
|
|
263
|
-
// Couldn't find a way to do it using anchor framework subscription, someone on serum discord recommended this way
|
|
264
|
-
this.connection.onAccountChange(
|
|
265
|
-
tokenAccountKey,
|
|
266
|
-
(
|
|
267
|
-
_accountInfo /* accountInfo is a buffer which we don't know how to deserialize */
|
|
268
|
-
) =>
|
|
269
|
-
__awaiter(this, void 0, void 0, function* () {
|
|
270
|
-
props.callback(yield this.getTokenAccountInfo(props));
|
|
271
|
-
})
|
|
272
|
-
);
|
|
273
|
-
return true;
|
|
274
|
-
} catch (e) {
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
exports.MockUSDCFaucet = MockUSDCFaucet;
|
package/src/orders.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = exports.calculateNewStateAfterOrder = void 0;
|
|
4
|
-
const types_1 = require("./types");
|
|
5
|
-
const _1 = require(".");
|
|
6
|
-
const market_1 = require("./math/market");
|
|
7
|
-
const numericConstants_1 = require("./constants/numericConstants");
|
|
8
|
-
const amm_1 = require("./math/amm");
|
|
9
|
-
const position_1 = require("./math/position");
|
|
10
|
-
function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
|
|
11
|
-
if (types_1.isVariant(order.status, 'init')) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
|
|
15
|
-
if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const userAccountAfter = Object.assign({}, userAccount);
|
|
19
|
-
const userPositionAfter = Object.assign({}, userPosition);
|
|
20
|
-
const currentPositionDirection = position_1.positionCurrentDirection(userPosition);
|
|
21
|
-
const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
|
|
22
|
-
isSameDirection(order.direction, currentPositionDirection);
|
|
23
|
-
if (increasePosition) {
|
|
24
|
-
const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
|
|
25
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
|
|
26
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
27
|
-
userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
|
|
28
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
|
|
32
|
-
if (reversePosition) {
|
|
33
|
-
const intermediateMarket = market_1.calculateNewMarketAfterTrade(userPosition.baseAssetAmount, position_1.findDirectionToClose(userPosition), market);
|
|
34
|
-
const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
|
|
35
|
-
let pnl;
|
|
36
|
-
if (types_1.isVariant(currentPositionDirection, 'long')) {
|
|
37
|
-
pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
41
|
-
}
|
|
42
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
43
|
-
const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
|
|
44
|
-
const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountLeft, order.direction, intermediateMarket);
|
|
45
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
|
|
46
|
-
userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
|
|
47
|
-
userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
|
|
48
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
|
|
52
|
-
const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
|
|
53
|
-
const costBasisRealized = userPosition.quoteAssetAmount
|
|
54
|
-
.mul(baseAssetAmountSwapped.abs())
|
|
55
|
-
.div(userPosition.baseAssetAmount.abs());
|
|
56
|
-
let pnl;
|
|
57
|
-
if (types_1.isVariant(currentPositionDirection, 'long')) {
|
|
58
|
-
pnl = baseAssetValue.sub(costBasisRealized);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
pnl = costBasisRealized.sub(baseAssetValue);
|
|
62
|
-
}
|
|
63
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
64
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
65
|
-
userPositionAfter.quoteAssetAmount =
|
|
66
|
-
userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
|
|
67
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
exports.calculateNewStateAfterOrder = calculateNewStateAfterOrder;
|
|
72
|
-
function calculateAmountSwapped(marketBefore, marketAfter) {
|
|
73
|
-
return {
|
|
74
|
-
quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
|
|
75
|
-
.sub(marketAfter.amm.quoteAssetReserve)
|
|
76
|
-
.abs()
|
|
77
|
-
.mul(marketBefore.amm.pegMultiplier)
|
|
78
|
-
.div(numericConstants_1.PEG_PRECISION)
|
|
79
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO),
|
|
80
|
-
baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function calculateBaseAssetAmountMarketCanExecute(market, order, oraclePriceData) {
|
|
84
|
-
if (types_1.isVariant(order.orderType, 'limit')) {
|
|
85
|
-
return calculateAmountToTradeForLimit(market, order, oraclePriceData);
|
|
86
|
-
}
|
|
87
|
-
else if (types_1.isVariant(order.orderType, 'triggerLimit')) {
|
|
88
|
-
return calculateAmountToTradeForTriggerLimit(market, order);
|
|
89
|
-
}
|
|
90
|
-
else if (types_1.isVariant(order.orderType, 'market')) {
|
|
91
|
-
return numericConstants_1.ZERO;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
return calculateAmountToTradeForTriggerMarket(market, order);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
exports.calculateBaseAssetAmountMarketCanExecute = calculateBaseAssetAmountMarketCanExecute;
|
|
98
|
-
function calculateAmountToTradeForLimit(market, order, oraclePriceData) {
|
|
99
|
-
let limitPrice = order.price;
|
|
100
|
-
if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
|
|
101
|
-
if (!oraclePriceData) {
|
|
102
|
-
throw Error('Cant calculate limit price for oracle offset oracle without OraclePriceData');
|
|
103
|
-
}
|
|
104
|
-
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
105
|
-
}
|
|
106
|
-
const [maxAmountToTrade, direction] = amm_1.calculateMaxBaseAssetAmountToTrade(market.amm, limitPrice, order.direction);
|
|
107
|
-
const baseAssetAmount = _1.standardizeBaseAssetAmount(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
|
|
108
|
-
// Check that directions are the same
|
|
109
|
-
const sameDirection = isSameDirection(direction, order.direction);
|
|
110
|
-
if (!sameDirection) {
|
|
111
|
-
return numericConstants_1.ZERO;
|
|
112
|
-
}
|
|
113
|
-
return baseAssetAmount.gt(order.baseAssetAmount)
|
|
114
|
-
? order.baseAssetAmount
|
|
115
|
-
: baseAssetAmount;
|
|
116
|
-
}
|
|
117
|
-
exports.calculateAmountToTradeForLimit = calculateAmountToTradeForLimit;
|
|
118
|
-
function calculateAmountToTradeForTriggerLimit(market, order) {
|
|
119
|
-
if (!order.triggered) {
|
|
120
|
-
return numericConstants_1.ZERO;
|
|
121
|
-
}
|
|
122
|
-
return calculateAmountToTradeForLimit(market, order);
|
|
123
|
-
}
|
|
124
|
-
exports.calculateAmountToTradeForTriggerLimit = calculateAmountToTradeForTriggerLimit;
|
|
125
|
-
function isSameDirection(firstDirection, secondDirection) {
|
|
126
|
-
return ((types_1.isVariant(firstDirection, 'long') && types_1.isVariant(secondDirection, 'long')) ||
|
|
127
|
-
(types_1.isVariant(firstDirection, 'short') && types_1.isVariant(secondDirection, 'short')));
|
|
128
|
-
}
|
|
129
|
-
function calculateAmountToTradeForTriggerMarket(market, order) {
|
|
130
|
-
if (!order.triggered) {
|
|
131
|
-
return numericConstants_1.ZERO;
|
|
132
|
-
}
|
|
133
|
-
return order.baseAssetAmount;
|
|
134
|
-
}
|
package/src/tx/retryTxSender.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.RetryTxSender = void 0;
|
|
16
|
-
const assert_1 = __importDefault(require("assert"));
|
|
17
|
-
const bs58_1 = __importDefault(require("bs58"));
|
|
18
|
-
const DEFAULT_TIMEOUT = 35000;
|
|
19
|
-
const DEFAULT_RETRY = 8000;
|
|
20
|
-
class RetryTxSender {
|
|
21
|
-
constructor(provider, timeout, retrySleep, additionalConnections = new Array()) {
|
|
22
|
-
this.provider = provider;
|
|
23
|
-
this.timeout = timeout !== null && timeout !== void 0 ? timeout : DEFAULT_TIMEOUT;
|
|
24
|
-
this.retrySleep = retrySleep !== null && retrySleep !== void 0 ? retrySleep : DEFAULT_RETRY;
|
|
25
|
-
this.additionalConnections = additionalConnections;
|
|
26
|
-
}
|
|
27
|
-
send(tx, additionalSigners, opts) {
|
|
28
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
-
if (additionalSigners === undefined) {
|
|
30
|
-
additionalSigners = [];
|
|
31
|
-
}
|
|
32
|
-
if (opts === undefined) {
|
|
33
|
-
opts = this.provider.opts;
|
|
34
|
-
}
|
|
35
|
-
yield this.prepareTx(tx, additionalSigners, opts);
|
|
36
|
-
const rawTransaction = tx.serialize();
|
|
37
|
-
const startTime = this.getTimestamp();
|
|
38
|
-
const txid = yield this.provider.connection.sendRawTransaction(rawTransaction, opts);
|
|
39
|
-
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
40
|
-
let done = false;
|
|
41
|
-
const resolveReference = {
|
|
42
|
-
resolve: undefined,
|
|
43
|
-
};
|
|
44
|
-
const stopWaiting = () => {
|
|
45
|
-
done = true;
|
|
46
|
-
if (resolveReference.resolve) {
|
|
47
|
-
resolveReference.resolve();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
(() => __awaiter(this, void 0, void 0, function* () {
|
|
51
|
-
while (!done && this.getTimestamp() - startTime < this.timeout) {
|
|
52
|
-
yield this.sleep(resolveReference);
|
|
53
|
-
if (!done) {
|
|
54
|
-
this.provider.connection
|
|
55
|
-
.sendRawTransaction(rawTransaction, opts)
|
|
56
|
-
.catch((e) => {
|
|
57
|
-
console.error(e);
|
|
58
|
-
stopWaiting();
|
|
59
|
-
});
|
|
60
|
-
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}))();
|
|
64
|
-
let slot;
|
|
65
|
-
try {
|
|
66
|
-
const result = yield this.confirmTransaction(txid, opts.commitment);
|
|
67
|
-
slot = result.context.slot;
|
|
68
|
-
}
|
|
69
|
-
catch (e) {
|
|
70
|
-
console.error(e);
|
|
71
|
-
throw e;
|
|
72
|
-
}
|
|
73
|
-
finally {
|
|
74
|
-
stopWaiting();
|
|
75
|
-
}
|
|
76
|
-
return { txSig: txid, slot };
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
prepareTx(tx, additionalSigners, opts) {
|
|
80
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
-
tx.feePayer = this.provider.wallet.publicKey;
|
|
82
|
-
tx.recentBlockhash = (yield this.provider.connection.getRecentBlockhash(opts.preflightCommitment)).blockhash;
|
|
83
|
-
yield this.provider.wallet.signTransaction(tx);
|
|
84
|
-
additionalSigners
|
|
85
|
-
.filter((s) => s !== undefined)
|
|
86
|
-
.forEach((kp) => {
|
|
87
|
-
tx.partialSign(kp);
|
|
88
|
-
});
|
|
89
|
-
return tx;
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
confirmTransaction(signature, commitment) {
|
|
93
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
let decodedSignature;
|
|
95
|
-
try {
|
|
96
|
-
decodedSignature = bs58_1.default.decode(signature);
|
|
97
|
-
}
|
|
98
|
-
catch (err) {
|
|
99
|
-
throw new Error('signature must be base58 encoded: ' + signature);
|
|
100
|
-
}
|
|
101
|
-
assert_1.default(decodedSignature.length === 64, 'signature has invalid length');
|
|
102
|
-
const start = Date.now();
|
|
103
|
-
const subscriptionCommitment = commitment || this.provider.opts.commitment;
|
|
104
|
-
const subscriptionIds = new Array();
|
|
105
|
-
const connections = [
|
|
106
|
-
this.provider.connection,
|
|
107
|
-
...this.additionalConnections,
|
|
108
|
-
];
|
|
109
|
-
let response = null;
|
|
110
|
-
const promises = connections.map((connection, i) => {
|
|
111
|
-
let subscriptionId;
|
|
112
|
-
const confirmPromise = new Promise((resolve, reject) => {
|
|
113
|
-
try {
|
|
114
|
-
subscriptionId = connection.onSignature(signature, (result, context) => {
|
|
115
|
-
subscriptionIds[i] = undefined;
|
|
116
|
-
response = {
|
|
117
|
-
context,
|
|
118
|
-
value: result,
|
|
119
|
-
};
|
|
120
|
-
resolve(null);
|
|
121
|
-
}, subscriptionCommitment);
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
reject(err);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
subscriptionIds.push(subscriptionId);
|
|
128
|
-
return confirmPromise;
|
|
129
|
-
});
|
|
130
|
-
try {
|
|
131
|
-
yield this.promiseTimeout(promises, this.timeout);
|
|
132
|
-
}
|
|
133
|
-
finally {
|
|
134
|
-
for (const [i, subscriptionId] of subscriptionIds.entries()) {
|
|
135
|
-
if (subscriptionId) {
|
|
136
|
-
connections[i].removeSignatureListener(subscriptionId);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (response === null) {
|
|
141
|
-
const duration = (Date.now() - start) / 1000;
|
|
142
|
-
throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
|
|
143
|
-
}
|
|
144
|
-
return response;
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
getTimestamp() {
|
|
148
|
-
return new Date().getTime();
|
|
149
|
-
}
|
|
150
|
-
sleep(reference) {
|
|
151
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
152
|
-
return new Promise((resolve) => {
|
|
153
|
-
reference.resolve = resolve;
|
|
154
|
-
setTimeout(resolve, this.retrySleep);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
promiseTimeout(promises, timeoutMs) {
|
|
159
|
-
let timeoutId;
|
|
160
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
161
|
-
timeoutId = setTimeout(() => resolve(null), timeoutMs);
|
|
162
|
-
});
|
|
163
|
-
return Promise.race([...promises, timeoutPromise]).then((result) => {
|
|
164
|
-
clearTimeout(timeoutId);
|
|
165
|
-
return result;
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
sendToAdditionalConnections(rawTx, opts) {
|
|
169
|
-
this.additionalConnections.map((connection) => {
|
|
170
|
-
connection.sendRawTransaction(rawTx, opts).catch((e) => {
|
|
171
|
-
console.error(
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
`error sending tx to additional connection ${connection._rpcEndpoint}`);
|
|
174
|
-
console.error(e);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
addAdditionalConnection(newConnection) {
|
|
179
|
-
const alreadyUsingConnection = this.additionalConnections.filter((connection) => {
|
|
180
|
-
// @ts-ignore
|
|
181
|
-
return connection._rpcEndpoint === newConnection.rpcEndpoint;
|
|
182
|
-
}).length > 0;
|
|
183
|
-
if (!alreadyUsingConnection) {
|
|
184
|
-
this.additionalConnections.push(newConnection);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
exports.RetryTxSender = RetryTxSender;
|