@drift-labs/sdk 0.1.36-master.5 → 0.2.0-master.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/bulkAccountLoader.d.ts +7 -6
- package/lib/accounts/bulkAccountLoader.js +83 -93
- package/lib/accounts/bulkUserSubscription.js +13 -57
- package/lib/accounts/fetch.d.ts +4 -0
- package/lib/accounts/fetch.js +18 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
- package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
- package/lib/accounts/pollingOracleSubscriber.js +37 -49
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
- package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
- package/lib/accounts/types.d.ts +34 -41
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
- package/lib/accounts/webSocketAccountSubscriber.js +39 -35
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
- package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
- package/lib/addresses/marketAddresses.d.ts +4 -0
- package/lib/addresses/marketAddresses.js +15 -0
- package/lib/addresses/pda.d.ts +12 -0
- package/lib/addresses/pda.js +83 -0
- package/lib/admin.d.ts +8 -12
- package/lib/admin.js +366 -490
- package/lib/clearingHouse.d.ts +84 -103
- package/lib/clearingHouse.js +779 -810
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -18
- package/lib/clearingHouseUser.js +157 -115
- package/lib/clearingHouseUserConfig.d.ts +14 -0
- package/lib/clearingHouseUserConfig.js +2 -0
- package/lib/config.d.ts +12 -0
- package/lib/config.js +35 -4
- package/lib/constants/banks.d.ts +16 -0
- package/lib/constants/banks.js +34 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +16 -0
- package/lib/constants/numericConstants.js +22 -6
- package/lib/events/eventList.d.ts +22 -0
- package/lib/events/eventList.js +77 -0
- package/lib/events/eventSubscriber.d.ts +34 -0
- package/lib/events/eventSubscriber.js +126 -0
- package/lib/events/fetchLogs.d.ts +13 -0
- package/lib/events/fetchLogs.js +39 -0
- package/lib/events/pollingLogProvider.d.ts +15 -0
- package/lib/events/pollingLogProvider.js +53 -0
- package/lib/events/sort.d.ts +2 -0
- package/lib/events/sort.js +44 -0
- package/lib/events/txEventCache.d.ts +24 -0
- package/lib/events/txEventCache.js +71 -0
- package/lib/events/types.d.ts +49 -0
- package/lib/events/types.js +20 -0
- package/lib/events/webSocketLogProvider.d.ts +12 -0
- package/lib/events/webSocketLogProvider.js +30 -0
- package/lib/examples/makeTradeExample.js +26 -27
- package/lib/factory/bigNum.d.ts +112 -0
- package/lib/factory/bigNum.js +356 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +1739 -2287
- package/lib/index.d.ts +13 -4
- package/lib/index.js +13 -4
- package/lib/math/amm.d.ts +19 -29
- package/lib/math/amm.js +129 -179
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +39 -0
- package/lib/math/bankBalance.d.ts +9 -0
- package/lib/math/bankBalance.js +75 -0
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -5
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +158 -175
- package/lib/math/market.d.ts +6 -6
- package/lib/math/market.js +10 -9
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +26 -0
- package/lib/math/orders.d.ts +5 -0
- package/lib/math/orders.js +31 -1
- package/lib/math/position.d.ts +7 -4
- package/lib/math/position.js +27 -9
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +13 -8
- package/lib/math/trade.js +85 -22
- package/lib/mockUSDCFaucet.js +87 -116
- package/lib/oracles/oracleClientCache.d.ts +8 -0
- package/lib/oracles/oracleClientCache.js +19 -0
- package/lib/oracles/pythClient.d.ts +3 -5
- package/lib/oracles/pythClient.js +12 -30
- package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
- package/lib/oracles/quoteAssetOracleClient.js +21 -0
- package/lib/oracles/switchboardClient.d.ts +3 -5
- package/lib/oracles/switchboardClient.js +29 -47
- package/lib/oracles/types.d.ts +7 -1
- package/lib/orders.d.ts +6 -6
- package/lib/orders.js +10 -9
- package/lib/slot/SlotSubscriber.d.ts +12 -0
- package/lib/slot/SlotSubscriber.js +23 -0
- package/lib/tx/retryTxSender.d.ts +2 -2
- package/lib/tx/retryTxSender.js +108 -123
- package/lib/tx/types.d.ts +5 -1
- package/lib/tx/utils.d.ts +1 -1
- package/lib/tx/utils.js +11 -2
- package/lib/types.d.ts +105 -98
- package/lib/types.js +13 -1
- package/lib/userName.d.ts +4 -0
- package/lib/userName.js +20 -0
- package/lib/util/computeUnits.js +10 -21
- package/lib/util/tps.js +11 -22
- package/lib/wallet.js +7 -20
- package/package.json +10 -3
- package/src/accounts/bulkAccountLoader.ts +26 -15
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.ts +41 -70
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.ts +18 -0
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +209 -267
- package/src/clearingHouse.ts +921 -829
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +280 -127
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +43 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +33 -5
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.ts +507 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +1739 -2287
- package/src/index.ts +13 -4
- package/src/math/amm.ts +229 -245
- package/src/math/auction.ts +39 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.ts +12 -9
- package/src/math/market.ts +37 -30
- package/src/math/oracles.ts +36 -0
- package/src/math/orders.ts +38 -0
- package/src/math/position.ts +48 -13
- package/src/math/repeg.ts +175 -0
- package/src/math/trade.ts +114 -36
- package/src/math/utils.js +27 -0
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.ts +5 -11
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.ts +16 -24
- package/src/oracles/types.ts +8 -1
- package/src/orders.ts +35 -20
- package/src/slot/SlotSubscriber.ts +32 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.ts +22 -3
- package/src/types.ts +108 -110
- package/src/userName.ts +20 -0
- package/src/util/computeUnits.js +17 -0
- package/src/util/computeUnits.js.map +1 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -9
- package/lib/addresses.js +0 -87
- package/lib/constants/accounts.d.ts +0 -15
- package/lib/constants/accounts.js +0 -18
- package/lib/factory/clearingHouse.d.ts +0 -35
- package/lib/factory/clearingHouse.js +0 -81
- package/lib/factory/clearingHouseUser.d.ts +0 -19
- package/lib/factory/clearingHouseUser.js +0 -34
- package/lib/math/insuranceFund.d.ts +0 -15
- package/lib/math/insuranceFund.js +0 -33
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -71
- package/src/constants/accounts.ts +0 -26
- package/src/factory/clearingHouse.ts +0 -173
- package/src/factory/clearingHouseUser.ts +0 -73
- package/src/math/insuranceFund.ts +0 -29
- package/src/tx/defaultTxSender.ts +0 -24
package/lib/clearingHouse.js
CHANGED
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -41,27 +32,62 @@ const spl_token_1 = require("@solana/spl-token");
|
|
|
41
32
|
const anchor = __importStar(require("@project-serum/anchor"));
|
|
42
33
|
const clearing_house_json_1 = __importDefault(require("./idl/clearing_house.json"));
|
|
43
34
|
const web3_js_1 = require("@solana/web3.js");
|
|
44
|
-
const
|
|
35
|
+
const pda_1 = require("./addresses/pda");
|
|
45
36
|
const utils_1 = require("./tx/utils");
|
|
46
|
-
const clearingHouse_1 = require("./factory/clearingHouse");
|
|
47
37
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
38
|
+
const position_1 = require("./math/position");
|
|
39
|
+
const bankBalance_1 = require("./math/bankBalance");
|
|
40
|
+
const userName_1 = require("./userName");
|
|
41
|
+
const pollingClearingHouseAccountSubscriber_1 = require("./accounts/pollingClearingHouseAccountSubscriber");
|
|
42
|
+
const webSocketClearingHouseAccountSubscriber_1 = require("./accounts/webSocketClearingHouseAccountSubscriber");
|
|
43
|
+
const retryTxSender_1 = require("./tx/retryTxSender");
|
|
44
|
+
const clearingHouseUser_1 = require("./clearingHouseUser");
|
|
45
|
+
const orderParams_1 = require("./orderParams");
|
|
46
|
+
const config_1 = require("./config");
|
|
48
47
|
/**
|
|
49
48
|
* # ClearingHouse
|
|
50
49
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
51
|
-
*
|
|
52
|
-
* The default way to construct a ClearingHouse instance is using the {@link from} method. This will create an instance using the static {@link WebSocketClearingHouseAccountSubscriber}, which will use a websocket for each state account subscription.
|
|
53
|
-
* Alternatively, if you want to implement your own method of subscribing to the state accounts on the blockchain, you can implement a {@link ClearingHouseAccountSubscriber} and use it in the {@link ClearingHouse.constructor}
|
|
54
50
|
*/
|
|
55
51
|
class ClearingHouse {
|
|
56
|
-
constructor(
|
|
52
|
+
constructor(config) {
|
|
53
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
54
|
+
this.users = new Map();
|
|
57
55
|
this._isSubscribed = false;
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
56
|
+
this.marketLastSlotCache = new Map();
|
|
57
|
+
this.connection = config.connection;
|
|
58
|
+
this.wallet = config.wallet;
|
|
59
|
+
this.opts = config.opts || anchor_1.AnchorProvider.defaultOptions();
|
|
60
|
+
this.provider = new anchor_1.AnchorProvider(config.connection, config.wallet, this.opts);
|
|
61
|
+
this.program = new anchor_1.Program(clearing_house_json_1.default, config.programID, this.provider);
|
|
62
|
+
const userIds = (_a = config.userIds) !== null && _a !== void 0 ? _a : [0];
|
|
63
|
+
this.activeUserId = (_b = config.activeUserId) !== null && _b !== void 0 ? _b : userIds[0];
|
|
64
|
+
this.userAccountSubscriptionConfig =
|
|
65
|
+
((_c = config.accountSubscription) === null || _c === void 0 ? void 0 : _c.type) === 'polling'
|
|
66
|
+
? {
|
|
67
|
+
type: 'polling',
|
|
68
|
+
accountLoader: config.accountSubscription.accountLoader,
|
|
69
|
+
}
|
|
70
|
+
: {
|
|
71
|
+
type: 'websocket',
|
|
72
|
+
};
|
|
73
|
+
this.createUsers(userIds, this.userAccountSubscriptionConfig);
|
|
74
|
+
let marketIndexes = config.marketIndexes;
|
|
75
|
+
let bankIndexes = config.bankIndexes;
|
|
76
|
+
let oracleInfos = config.oracleInfos;
|
|
77
|
+
if (config.env) {
|
|
78
|
+
const { marketIndexes: envMarketIndexes, bankIndexes: envBankIndexes, oracleInfos: envOralceInfos, } = (0, config_1.getMarketsBanksAndOraclesForSubscription)(config.env);
|
|
79
|
+
marketIndexes = marketIndexes ? marketIndexes : envMarketIndexes;
|
|
80
|
+
bankIndexes = bankIndexes ? bankIndexes : envBankIndexes;
|
|
81
|
+
oracleInfos = oracleInfos ? oracleInfos : envOralceInfos;
|
|
82
|
+
}
|
|
83
|
+
if (((_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.type) === 'polling') {
|
|
84
|
+
this.accountSubscriber = new pollingClearingHouseAccountSubscriber_1.PollingClearingHouseAccountSubscriber(this.program, config.accountSubscription.accountLoader, marketIndexes !== null && marketIndexes !== void 0 ? marketIndexes : [], bankIndexes !== null && bankIndexes !== void 0 ? bankIndexes : [], oracleInfos !== null && oracleInfos !== void 0 ? oracleInfos : []);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.accountSubscriber = new webSocketClearingHouseAccountSubscriber_1.WebSocketClearingHouseAccountSubscriber(this.program, (_e = config.marketIndexes) !== null && _e !== void 0 ? _e : [], (_f = config.bankIndexes) !== null && _f !== void 0 ? _f : [], (_g = config.oracleInfos) !== null && _g !== void 0 ? _g : []);
|
|
88
|
+
}
|
|
63
89
|
this.eventEmitter = this.accountSubscriber.eventEmitter;
|
|
64
|
-
this.txSender =
|
|
90
|
+
this.txSender = new retryTxSender_1.RetryTxSender(this.provider, (_h = config.txSenderConfig) === null || _h === void 0 ? void 0 : _h.timeout, (_j = config.txSenderConfig) === null || _j === void 0 ? void 0 : _j.retrySleep, (_k = config.txSenderConfig) === null || _k === void 0 ? void 0 : _k.additionalConnections);
|
|
65
91
|
}
|
|
66
92
|
get isSubscribed() {
|
|
67
93
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
@@ -69,122 +95,82 @@ class ClearingHouse {
|
|
|
69
95
|
set isSubscribed(val) {
|
|
70
96
|
this._isSubscribed = val;
|
|
71
97
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* @param opts
|
|
78
|
-
* @returns
|
|
79
|
-
*/
|
|
80
|
-
static from(connection, wallet, clearingHouseProgramId, opts = anchor_1.AnchorProvider.defaultOptions()) {
|
|
81
|
-
const config = (0, clearingHouse_1.getWebSocketClearingHouseConfig)(connection, wallet, clearingHouseProgramId, opts);
|
|
82
|
-
return (0, clearingHouse_1.getClearingHouse)(config);
|
|
98
|
+
createUsers(userIds, accountSubscriptionConfig) {
|
|
99
|
+
for (const userId of userIds) {
|
|
100
|
+
const user = this.createUser(userId, accountSubscriptionConfig);
|
|
101
|
+
this.users.set(userId, user);
|
|
102
|
+
}
|
|
83
103
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
this.isSubscribed = yield this.accountSubscriber.subscribe(optionalSubscriptions);
|
|
92
|
-
return this.isSubscribed;
|
|
104
|
+
createUser(userId, accountSubscriptionConfig) {
|
|
105
|
+
const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, userId);
|
|
106
|
+
return new clearingHouseUser_1.ClearingHouseUser({
|
|
107
|
+
clearingHouse: this,
|
|
108
|
+
userAccountPublicKey,
|
|
109
|
+
accountSubscription: accountSubscriptionConfig,
|
|
93
110
|
});
|
|
94
111
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
subscribeToAll() {
|
|
100
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
return this.subscribe([
|
|
102
|
-
'curveHistoryAccount',
|
|
103
|
-
'depositHistoryAccount',
|
|
104
|
-
'fundingPaymentHistoryAccount',
|
|
105
|
-
'fundingRateHistoryAccount',
|
|
106
|
-
'liquidationHistoryAccount',
|
|
107
|
-
'tradeHistoryAccount',
|
|
108
|
-
'orderHistoryAccount',
|
|
109
|
-
]);
|
|
110
|
-
});
|
|
112
|
+
async subscribe() {
|
|
113
|
+
const subscribePromises = this.subscribeUsers().concat(this.accountSubscriber.subscribe());
|
|
114
|
+
this.isSubscribed = (await Promise.all(subscribePromises)).reduce((success, prevSuccess) => success && prevSuccess);
|
|
115
|
+
return this.isSubscribed;
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*/
|
|
115
|
-
fetchAccounts() {
|
|
116
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
yield this.accountSubscriber.fetch();
|
|
118
|
-
});
|
|
117
|
+
subscribeUsers() {
|
|
118
|
+
return [...this.users.values()].map((user) => user.subscribe());
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
|
-
*
|
|
121
|
+
* Forces the accountSubscriber to fetch account updates from rpc
|
|
122
122
|
*/
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this.
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
getStatePublicKey() {
|
|
130
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
if (this.statePublicKey) {
|
|
132
|
-
return this.statePublicKey;
|
|
133
|
-
}
|
|
134
|
-
this.statePublicKey = yield (0, addresses_1.getClearingHouseStateAccountPublicKey)(this.program.programId);
|
|
135
|
-
return this.statePublicKey;
|
|
136
|
-
});
|
|
123
|
+
async fetchAccounts() {
|
|
124
|
+
await Promise.all([...this.users.values()]
|
|
125
|
+
.map((user) => user.fetchAccounts())
|
|
126
|
+
.concat(this.accountSubscriber.fetch()));
|
|
137
127
|
}
|
|
138
|
-
|
|
139
|
-
|
|
128
|
+
async unsubscribe() {
|
|
129
|
+
const unsubscribePromises = this.unsubscribeUsers().concat(this.accountSubscriber.unsubscribe());
|
|
130
|
+
await Promise.all(unsubscribePromises);
|
|
131
|
+
this.isSubscribed = false;
|
|
140
132
|
}
|
|
141
|
-
|
|
142
|
-
return this.
|
|
133
|
+
unsubscribeUsers() {
|
|
134
|
+
return [...this.users.values()].map((user) => user.unsubscribe());
|
|
143
135
|
}
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
136
|
+
async getStatePublicKey() {
|
|
137
|
+
if (this.statePublicKey) {
|
|
138
|
+
return this.statePublicKey;
|
|
147
139
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
getFundingPaymentHistoryAccount() {
|
|
151
|
-
return this.accountSubscriber.getFundingPaymentHistoryAccount();
|
|
152
|
-
}
|
|
153
|
-
getFundingRateHistoryAccount() {
|
|
154
|
-
return this.accountSubscriber.getFundingRateHistoryAccount();
|
|
155
|
-
}
|
|
156
|
-
getTradeHistoryAccount() {
|
|
157
|
-
return this.accountSubscriber.getTradeHistoryAccount();
|
|
140
|
+
this.statePublicKey = await (0, pda_1.getClearingHouseStateAccountPublicKey)(this.program.programId);
|
|
141
|
+
return this.statePublicKey;
|
|
158
142
|
}
|
|
159
|
-
|
|
160
|
-
return this.accountSubscriber.
|
|
143
|
+
getStateAccount() {
|
|
144
|
+
return this.accountSubscriber.getStateAccountAndSlot().data;
|
|
161
145
|
}
|
|
162
|
-
|
|
163
|
-
|
|
146
|
+
getMarketAccount(marketIndex) {
|
|
147
|
+
var _a;
|
|
148
|
+
marketIndex = marketIndex instanceof anchor_1.BN ? marketIndex : new anchor_1.BN(marketIndex);
|
|
149
|
+
return (_a = this.accountSubscriber.getMarketAccountAndSlot(marketIndex)) === null || _a === void 0 ? void 0 : _a.data;
|
|
164
150
|
}
|
|
165
|
-
|
|
166
|
-
return this.accountSubscriber
|
|
151
|
+
getMarketAccounts() {
|
|
152
|
+
return this.accountSubscriber
|
|
153
|
+
.getMarketAccountsAndSlots()
|
|
154
|
+
.map((value) => value.data);
|
|
167
155
|
}
|
|
168
|
-
|
|
169
|
-
|
|
156
|
+
getBankAccount(bankIndex) {
|
|
157
|
+
bankIndex = bankIndex instanceof anchor_1.BN ? bankIndex : new anchor_1.BN(bankIndex);
|
|
158
|
+
return this.accountSubscriber.getBankAccountAndSlot(bankIndex).data;
|
|
170
159
|
}
|
|
171
|
-
|
|
172
|
-
return
|
|
173
|
-
|
|
174
|
-
return this.orderStatePublicKey;
|
|
175
|
-
}
|
|
176
|
-
this.orderStatePublicKey = yield (0, addresses_1.getOrderStateAccountPublicKey)(this.program.programId);
|
|
177
|
-
return this.orderStatePublicKey;
|
|
178
|
-
});
|
|
160
|
+
getQuoteAssetBankAccount() {
|
|
161
|
+
return this.accountSubscriber.getBankAccountAndSlot(numericConstants_1.QUOTE_ASSET_BANK_INDEX)
|
|
162
|
+
.data;
|
|
179
163
|
}
|
|
180
|
-
|
|
181
|
-
return this.accountSubscriber.
|
|
164
|
+
getOraclePriceDataAndSlot(oraclePublicKey) {
|
|
165
|
+
return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
|
|
182
166
|
}
|
|
183
167
|
/**
|
|
184
168
|
* Update the wallet to use for clearing house transactions and linked user account
|
|
185
169
|
* @param newWallet
|
|
170
|
+
* @param userIds
|
|
171
|
+
* @param activeUserId
|
|
186
172
|
*/
|
|
187
|
-
updateWallet(newWallet) {
|
|
173
|
+
async updateWallet(newWallet, userIds = [0], activeUserId = 0) {
|
|
188
174
|
const newProvider = new anchor_1.AnchorProvider(this.connection, newWallet, this.opts);
|
|
189
175
|
const newProgram = new anchor_1.Program(clearing_house_json_1.default, this.program.programId, newProvider);
|
|
190
176
|
// Update provider for txSender with new wallet details
|
|
@@ -192,771 +178,754 @@ class ClearingHouse {
|
|
|
192
178
|
this.wallet = newWallet;
|
|
193
179
|
this.provider = newProvider;
|
|
194
180
|
this.program = newProgram;
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
this.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
.add(initializeUserAccountIx)
|
|
205
|
-
.add(initializeUserOrdersAccountIx);
|
|
206
|
-
const txSig = yield this.txSender.send(tx, [userPositionsAccount], this.opts);
|
|
207
|
-
return [txSig, userAccountPublicKey];
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
getInitializeUserInstructions() {
|
|
211
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
212
|
-
const [userAccountPublicKey, userAccountNonce] = yield (0, addresses_1.getUserAccountPublicKeyAndNonce)(this.program.programId, this.wallet.publicKey);
|
|
213
|
-
const remainingAccounts = [];
|
|
214
|
-
const optionalAccounts = {
|
|
215
|
-
whitelistToken: false,
|
|
216
|
-
};
|
|
217
|
-
const state = this.getStateAccount();
|
|
218
|
-
if (state.whitelistMint) {
|
|
219
|
-
optionalAccounts.whitelistToken = true;
|
|
220
|
-
const associatedTokenPublicKey = yield spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.whitelistMint, this.wallet.publicKey);
|
|
221
|
-
remainingAccounts.push({
|
|
222
|
-
pubkey: associatedTokenPublicKey,
|
|
223
|
-
isWritable: false,
|
|
224
|
-
isSigner: false,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
const userPositions = new web3_js_1.Keypair();
|
|
228
|
-
const initializeUserAccountIx = yield this.program.instruction.initializeUser(userAccountNonce, optionalAccounts, {
|
|
229
|
-
accounts: {
|
|
230
|
-
user: userAccountPublicKey,
|
|
231
|
-
authority: this.wallet.publicKey,
|
|
232
|
-
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
233
|
-
systemProgram: anchor.web3.SystemProgram.programId,
|
|
234
|
-
userPositions: userPositions.publicKey,
|
|
235
|
-
state: yield this.getStatePublicKey(),
|
|
236
|
-
},
|
|
237
|
-
remainingAccounts: remainingAccounts,
|
|
238
|
-
});
|
|
239
|
-
const initializeUserOrdersAccountIx = yield this.getInitializeUserOrdersInstruction(userAccountPublicKey);
|
|
240
|
-
return [
|
|
241
|
-
userPositions,
|
|
242
|
-
userAccountPublicKey,
|
|
243
|
-
initializeUserAccountIx,
|
|
244
|
-
initializeUserOrdersAccountIx,
|
|
245
|
-
];
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
getInitializeUserOrdersInstruction(userAccountPublicKey) {
|
|
249
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
if (!userAccountPublicKey) {
|
|
251
|
-
userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
252
|
-
}
|
|
253
|
-
const [userOrdersAccountPublicKey, userOrdersAccountNonce] = yield (0, addresses_1.getUserOrdersAccountPublicKeyAndNonce)(this.program.programId, userAccountPublicKey);
|
|
254
|
-
return yield this.program.instruction.initializeUserOrders(userOrdersAccountNonce, {
|
|
255
|
-
accounts: {
|
|
256
|
-
user: userAccountPublicKey,
|
|
257
|
-
authority: this.wallet.publicKey,
|
|
258
|
-
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
259
|
-
systemProgram: anchor.web3.SystemProgram.programId,
|
|
260
|
-
userOrders: userOrdersAccountPublicKey,
|
|
261
|
-
state: yield this.getStatePublicKey(),
|
|
262
|
-
},
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Get the address for the Clearing House User's account. NOT the user's wallet address.
|
|
268
|
-
* @returns
|
|
269
|
-
*/
|
|
270
|
-
getUserAccountPublicKey() {
|
|
271
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
272
|
-
if (this.userAccountPublicKey) {
|
|
273
|
-
return this.userAccountPublicKey;
|
|
274
|
-
}
|
|
275
|
-
this.userAccountPublicKey = yield (0, addresses_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey);
|
|
276
|
-
return this.userAccountPublicKey;
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
getUserAccount() {
|
|
280
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
281
|
-
if (this.userAccount) {
|
|
282
|
-
return this.userAccount;
|
|
283
|
-
}
|
|
284
|
-
this.userAccount = (yield this.program.account.user.fetch(yield this.getUserAccountPublicKey()));
|
|
285
|
-
return this.userAccount;
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Get the address for the Clearing House User Order's account. NOT the user's wallet address.
|
|
290
|
-
* @returns
|
|
291
|
-
*/
|
|
292
|
-
getUserOrdersAccountPublicKey() {
|
|
293
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
294
|
-
if (this.userOrdersAccountPublicKey) {
|
|
295
|
-
return this.userOrdersAccountPublicKey;
|
|
296
|
-
}
|
|
297
|
-
this.userOrdersAccountPublicKey = yield (0, addresses_1.getUserOrdersAccountPublicKey)(this.program.programId, yield this.getUserAccountPublicKey());
|
|
298
|
-
return this.userOrdersAccountPublicKey;
|
|
299
|
-
});
|
|
181
|
+
if (this.isSubscribed) {
|
|
182
|
+
await Promise.all(this.unsubscribeUsers());
|
|
183
|
+
}
|
|
184
|
+
this.users.clear();
|
|
185
|
+
this.createUsers(userIds, this.userAccountSubscriptionConfig);
|
|
186
|
+
if (this.isSubscribed) {
|
|
187
|
+
await Promise.all(this.subscribeUsers());
|
|
188
|
+
}
|
|
189
|
+
this.activeUserId = activeUserId;
|
|
300
190
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (this.userOrdersExist) {
|
|
304
|
-
return this.userOrdersExist;
|
|
305
|
-
}
|
|
306
|
-
const userOrdersAccountRPCResponse = yield this.connection.getParsedAccountInfo(yield this.getUserOrdersAccountPublicKey());
|
|
307
|
-
this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
|
|
308
|
-
return this.userOrdersExist;
|
|
309
|
-
});
|
|
191
|
+
async switchActiveUser(userId) {
|
|
192
|
+
this.activeUserId = userId;
|
|
310
193
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
194
|
+
async addUser(userId) {
|
|
195
|
+
if (this.users.has(userId)) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const user = this.createUser(userId, this.userAccountSubscriptionConfig);
|
|
199
|
+
await user.subscribe();
|
|
200
|
+
this.users.set(userId, user);
|
|
201
|
+
}
|
|
202
|
+
async initializeUserAccount(userId = 0, name = userName_1.DEFAULT_USER_NAME) {
|
|
203
|
+
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
204
|
+
const tx = new web3_js_1.Transaction().add(initializeUserAccountIx);
|
|
205
|
+
const { txSig } = await this.txSender.send(tx, [], this.opts);
|
|
206
|
+
return [txSig, userAccountPublicKey];
|
|
207
|
+
}
|
|
208
|
+
async getInitializeUserInstructions(userId = 0, name = userName_1.DEFAULT_USER_NAME) {
|
|
209
|
+
const userAccountPublicKey = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, userId);
|
|
210
|
+
const nameBuffer = (0, userName_1.encodeName)(name);
|
|
211
|
+
const initializeUserAccountIx = await this.program.instruction.initializeUser(userId, nameBuffer, {
|
|
212
|
+
accounts: {
|
|
213
|
+
user: userAccountPublicKey,
|
|
214
|
+
authority: this.wallet.publicKey,
|
|
215
|
+
payer: this.wallet.publicKey,
|
|
216
|
+
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
217
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
218
|
+
state: await this.getStatePublicKey(),
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
return [userAccountPublicKey, initializeUserAccountIx];
|
|
222
|
+
}
|
|
223
|
+
getUser(userId) {
|
|
224
|
+
userId = userId !== null && userId !== void 0 ? userId : this.activeUserId;
|
|
225
|
+
if (!this.users.has(userId)) {
|
|
226
|
+
throw new Error(`Clearing House has no user for user id ${userId}`);
|
|
227
|
+
}
|
|
228
|
+
return this.users.get(userId);
|
|
317
229
|
}
|
|
318
|
-
|
|
319
|
-
return
|
|
320
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
321
|
-
if (!userPositionsAccountPublicKey) {
|
|
322
|
-
userPositionsAccountPublicKey = (yield this.getUserAccount()).positions;
|
|
323
|
-
}
|
|
324
|
-
const state = this.getStateAccount();
|
|
325
|
-
return yield this.program.instruction.depositCollateral(amount, {
|
|
326
|
-
accounts: {
|
|
327
|
-
state: yield this.getStatePublicKey(),
|
|
328
|
-
user: userAccountPublicKey,
|
|
329
|
-
collateralVault: state.collateralVault,
|
|
330
|
-
userCollateralAccount: collateralAccountPublicKey,
|
|
331
|
-
authority: this.wallet.publicKey,
|
|
332
|
-
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
333
|
-
markets: state.markets,
|
|
334
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
335
|
-
depositHistory: state.depositHistory,
|
|
336
|
-
userPositions: userPositionsAccountPublicKey,
|
|
337
|
-
},
|
|
338
|
-
});
|
|
339
|
-
});
|
|
230
|
+
getUsers() {
|
|
231
|
+
return [...this.users.values()];
|
|
340
232
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
* @param amount
|
|
344
|
-
* @param collateralAccountPublicKey
|
|
345
|
-
* @returns
|
|
346
|
-
*/
|
|
347
|
-
initializeUserAccountAndDepositCollateral(amount, collateralAccountPublicKey) {
|
|
348
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
-
const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx, initializeUserOrdersAccountIx,] = yield this.getInitializeUserInstructions();
|
|
350
|
-
const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, collateralAccountPublicKey, userPositionsAccount.publicKey);
|
|
351
|
-
const tx = new web3_js_1.Transaction()
|
|
352
|
-
.add(initializeUserAccountIx)
|
|
353
|
-
.add(initializeUserOrdersAccountIx)
|
|
354
|
-
.add(depositCollateralIx);
|
|
355
|
-
const txSig = yield this.txSender.send(tx, [userPositionsAccount]);
|
|
356
|
-
return [txSig, userAccountPublicKey];
|
|
357
|
-
});
|
|
233
|
+
async getUserAccountPublicKey() {
|
|
234
|
+
return this.getUser().userAccountPublicKey;
|
|
358
235
|
}
|
|
359
|
-
|
|
360
|
-
return
|
|
361
|
-
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = yield mockUSDCFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
362
|
-
const [userPositionsAccount, userAccountPublicKey, initializeUserAccountIx, initializeUserOrdersAccountIx,] = yield this.getInitializeUserInstructions();
|
|
363
|
-
const depositCollateralIx = yield this.getDepositCollateralInstruction(amount, associateTokenPublicKey, userPositionsAccount.publicKey);
|
|
364
|
-
const tx = new web3_js_1.Transaction()
|
|
365
|
-
.add(createAssociatedAccountIx)
|
|
366
|
-
.add(mintToIx)
|
|
367
|
-
.add(initializeUserAccountIx)
|
|
368
|
-
.add(initializeUserOrdersAccountIx)
|
|
369
|
-
.add(depositCollateralIx);
|
|
370
|
-
const txSig = yield this.program.provider.sendAndConfirm(tx, [
|
|
371
|
-
userPositionsAccount,
|
|
372
|
-
]);
|
|
373
|
-
return [txSig, userAccountPublicKey];
|
|
374
|
-
});
|
|
236
|
+
getUserAccount(userId) {
|
|
237
|
+
return this.getUser(userId).getUserAccount();
|
|
375
238
|
}
|
|
376
|
-
|
|
377
|
-
return
|
|
378
|
-
return this.txSender.send((0, utils_1.wrapInTx)(yield this.getWithdrawCollateralIx(amount, collateralAccountPublicKey)), [], this.opts);
|
|
379
|
-
});
|
|
239
|
+
getUserAccountAndSlot(userId) {
|
|
240
|
+
return this.getUser(userId).getUserAccountAndSlot();
|
|
380
241
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const user = yield this.program.account.user.fetch(userAccountPublicKey);
|
|
385
|
-
const state = this.getStateAccount();
|
|
386
|
-
return yield this.program.instruction.withdrawCollateral(amount, {
|
|
387
|
-
accounts: {
|
|
388
|
-
state: yield this.getStatePublicKey(),
|
|
389
|
-
user: userAccountPublicKey,
|
|
390
|
-
collateralVault: state.collateralVault,
|
|
391
|
-
collateralVaultAuthority: state.collateralVaultAuthority,
|
|
392
|
-
insuranceVault: state.insuranceVault,
|
|
393
|
-
insuranceVaultAuthority: state.insuranceVaultAuthority,
|
|
394
|
-
userCollateralAccount: collateralAccountPublicKey,
|
|
395
|
-
authority: this.wallet.publicKey,
|
|
396
|
-
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
397
|
-
markets: state.markets,
|
|
398
|
-
userPositions: user.positions,
|
|
399
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
400
|
-
depositHistory: state.depositHistory,
|
|
401
|
-
},
|
|
402
|
-
});
|
|
403
|
-
});
|
|
242
|
+
getUserBankBalance(bankIndex) {
|
|
243
|
+
const bankIndexBN = bankIndex instanceof anchor_1.BN ? bankIndex : new anchor_1.BN(bankIndex);
|
|
244
|
+
return this.getUserAccount().bankBalances.find((bankBalance) => bankBalance.bankIndex.eq(bankIndexBN));
|
|
404
245
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
246
|
+
getQuoteAssetTokenAmount() {
|
|
247
|
+
const bank = this.getBankAccount(numericConstants_1.QUOTE_ASSET_BANK_INDEX);
|
|
248
|
+
const userBankBalance = this.getUserBankBalance(numericConstants_1.QUOTE_ASSET_BANK_INDEX);
|
|
249
|
+
return (0, bankBalance_1.getTokenAmount)(userBankBalance.balance, bank, userBankBalance.balanceType);
|
|
409
250
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
pubkey:
|
|
426
|
-
isWritable: false,
|
|
251
|
+
getRemainingAccounts(params) {
|
|
252
|
+
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
253
|
+
if (!userAccountAndSlot) {
|
|
254
|
+
throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
|
|
255
|
+
}
|
|
256
|
+
const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
|
|
257
|
+
const oracleAccountMap = new Map();
|
|
258
|
+
const bankAccountMap = new Map();
|
|
259
|
+
const marketAccountMap = new Map();
|
|
260
|
+
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
261
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
262
|
+
// otherwise remove from slot
|
|
263
|
+
if (slot > lastUserPositionsSlot) {
|
|
264
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
265
|
+
marketAccountMap.set(marketIndexNum, {
|
|
266
|
+
pubkey: marketAccount.pubkey,
|
|
427
267
|
isSigner: false,
|
|
268
|
+
isWritable: false,
|
|
428
269
|
});
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
optionalAccounts.referrer = true;
|
|
432
|
-
remainingAccounts.push({
|
|
433
|
-
pubkey: referrer,
|
|
434
|
-
isWritable: true,
|
|
270
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
271
|
+
pubkey: marketAccount.amm.oracle,
|
|
435
272
|
isSigner: false,
|
|
273
|
+
isWritable: false,
|
|
436
274
|
});
|
|
437
275
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
return yield this.program.instruction.openPosition(direction, amount, marketIndex, limitPrice, optionalAccounts, {
|
|
441
|
-
accounts: {
|
|
442
|
-
state: yield this.getStatePublicKey(),
|
|
443
|
-
user: userAccountPublicKey,
|
|
444
|
-
authority: this.wallet.publicKey,
|
|
445
|
-
markets: state.markets,
|
|
446
|
-
userPositions: userAccount.positions,
|
|
447
|
-
tradeHistory: state.tradeHistory,
|
|
448
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
449
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
450
|
-
oracle: priceOracle,
|
|
451
|
-
},
|
|
452
|
-
remainingAccounts: remainingAccounts,
|
|
453
|
-
});
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
initializeUserOrdersThenPlaceOrder(orderParams, discountToken, referrer) {
|
|
457
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
458
|
-
const instructions = [];
|
|
459
|
-
const userOrdersAccountExists = yield this.userOrdersAccountExists();
|
|
460
|
-
if (!userOrdersAccountExists) {
|
|
461
|
-
instructions.push(yield this.getInitializeUserOrdersInstruction());
|
|
462
|
-
}
|
|
463
|
-
instructions.push(yield this.getPlaceOrderIx(orderParams, discountToken, referrer));
|
|
464
|
-
const tx = new web3_js_1.Transaction();
|
|
465
|
-
for (const instruction of instructions) {
|
|
466
|
-
tx.add(instruction);
|
|
276
|
+
else {
|
|
277
|
+
this.marketLastSlotCache.delete(marketIndexNum);
|
|
467
278
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
getPlaceOrderIx(orderParams, discountToken, referrer) {
|
|
477
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
478
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
479
|
-
const userAccount = yield this.getUserAccount();
|
|
480
|
-
const priceOracle = this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
|
|
481
|
-
.oracle;
|
|
482
|
-
const remainingAccounts = [];
|
|
483
|
-
if (orderParams.optionalAccounts.discountToken) {
|
|
484
|
-
if (!discountToken) {
|
|
485
|
-
throw Error('Optional accounts specified discount token but no discount token present');
|
|
486
|
-
}
|
|
487
|
-
remainingAccounts.push({
|
|
488
|
-
pubkey: discountToken,
|
|
489
|
-
isWritable: false,
|
|
279
|
+
}
|
|
280
|
+
for (const position of userAccount.positions) {
|
|
281
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
282
|
+
const marketIndexNum = position.marketIndex.toNumber();
|
|
283
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
284
|
+
marketAccountMap.set(marketIndexNum, {
|
|
285
|
+
pubkey: marketAccount.pubkey,
|
|
490
286
|
isSigner: false,
|
|
287
|
+
// isWritable: false, // TODO
|
|
288
|
+
isWritable: true,
|
|
491
289
|
});
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (!referrer) {
|
|
495
|
-
throw Error('Optional accounts specified referrer but no referrer present');
|
|
496
|
-
}
|
|
497
|
-
remainingAccounts.push({
|
|
498
|
-
pubkey: referrer,
|
|
499
|
-
isWritable: false,
|
|
290
|
+
oracleAccountMap.set(marketAccount.pubkey.toString(), {
|
|
291
|
+
pubkey: marketAccount.amm.oracle,
|
|
500
292
|
isSigner: false,
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
if (!orderParams.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
|
|
504
|
-
remainingAccounts.push({
|
|
505
|
-
pubkey: priceOracle,
|
|
506
293
|
isWritable: false,
|
|
507
|
-
isSigner: false,
|
|
508
294
|
});
|
|
509
295
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
markets: state.markets,
|
|
518
|
-
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
519
|
-
userPositions: userAccount.positions,
|
|
520
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
521
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
522
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
523
|
-
orderHistory: orderState.orderHistory,
|
|
524
|
-
},
|
|
525
|
-
remainingAccounts,
|
|
296
|
+
}
|
|
297
|
+
if (params.writableMarketIndex) {
|
|
298
|
+
const marketAccount = this.getMarketAccount(params.writableMarketIndex.toNumber());
|
|
299
|
+
marketAccountMap.set(params.writableMarketIndex.toNumber(), {
|
|
300
|
+
pubkey: marketAccount.pubkey,
|
|
301
|
+
isSigner: false,
|
|
302
|
+
isWritable: true,
|
|
526
303
|
});
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getExpireOrdersIx(userAccountPublicKey, userOrdersAccountPublicKey)), [], this.opts);
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
|
-
getExpireOrdersIx(userAccountPublicKey, userOrdersAccountPublicKey) {
|
|
535
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
536
|
-
const fillerPublicKey = yield this.getUserAccountPublicKey();
|
|
537
|
-
const userAccount = yield this.program.account.user.fetch(userAccountPublicKey);
|
|
538
|
-
const orderState = this.getOrderStateAccount();
|
|
539
|
-
return yield this.program.instruction.expireOrders({
|
|
540
|
-
accounts: {
|
|
541
|
-
state: yield this.getStatePublicKey(),
|
|
542
|
-
filler: fillerPublicKey,
|
|
543
|
-
user: userAccountPublicKey,
|
|
544
|
-
authority: this.wallet.publicKey,
|
|
545
|
-
userPositions: userAccount.positions,
|
|
546
|
-
userOrders: userOrdersAccountPublicKey,
|
|
547
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
548
|
-
orderHistory: orderState.orderHistory,
|
|
549
|
-
},
|
|
304
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
305
|
+
pubkey: marketAccount.amm.oracle,
|
|
306
|
+
isSigner: false,
|
|
307
|
+
isWritable: false,
|
|
550
308
|
});
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
getCancelOrderIx(orderId, oracle) {
|
|
559
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
560
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
561
|
-
const userAccount = yield this.getUserAccount();
|
|
562
|
-
const state = this.getStateAccount();
|
|
563
|
-
const orderState = this.getOrderStateAccount();
|
|
564
|
-
const remainingAccounts = [];
|
|
565
|
-
if (oracle) {
|
|
566
|
-
remainingAccounts.push({
|
|
567
|
-
pubkey: oracle,
|
|
568
|
-
isWritable: false,
|
|
309
|
+
}
|
|
310
|
+
for (const userBankBalance of userAccount.bankBalances) {
|
|
311
|
+
if (!userBankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
312
|
+
const bankAccount = this.getBankAccount(userBankBalance.bankIndex);
|
|
313
|
+
bankAccountMap.set(userBankBalance.bankIndex.toNumber(), {
|
|
314
|
+
pubkey: bankAccount.pubkey,
|
|
569
315
|
isSigner: false,
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
return yield this.program.instruction.cancelOrder(orderId, {
|
|
573
|
-
accounts: {
|
|
574
|
-
state: yield this.getStatePublicKey(),
|
|
575
|
-
user: userAccountPublicKey,
|
|
576
|
-
authority: this.wallet.publicKey,
|
|
577
|
-
markets: state.markets,
|
|
578
|
-
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
579
|
-
userPositions: userAccount.positions,
|
|
580
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
581
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
582
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
583
|
-
orderHistory: orderState.orderHistory,
|
|
584
|
-
},
|
|
585
|
-
remainingAccounts,
|
|
586
|
-
});
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
cancelOrderByUserId(userOrderId, oracle) {
|
|
590
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
591
|
-
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelOrderByUserIdIx(userOrderId, oracle)), [], this.opts);
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
getCancelOrderByUserIdIx(userOrderId, oracle) {
|
|
595
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
596
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
597
|
-
const userAccount = yield this.getUserAccount();
|
|
598
|
-
const state = this.getStateAccount();
|
|
599
|
-
const orderState = this.getOrderStateAccount();
|
|
600
|
-
const remainingAccounts = [];
|
|
601
|
-
if (oracle) {
|
|
602
|
-
remainingAccounts.push({
|
|
603
|
-
pubkey: oracle,
|
|
604
316
|
isWritable: false,
|
|
605
|
-
isSigner: false,
|
|
606
317
|
});
|
|
318
|
+
if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
|
|
319
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
320
|
+
pubkey: bankAccount.oracle,
|
|
321
|
+
isSigner: false,
|
|
322
|
+
isWritable: false,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
607
325
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
userPositions: userAccount.positions,
|
|
616
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
617
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
618
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
619
|
-
orderHistory: orderState.orderHistory,
|
|
620
|
-
},
|
|
621
|
-
remainingAccounts,
|
|
326
|
+
}
|
|
327
|
+
if (params.writableBankIndex) {
|
|
328
|
+
const bankAccount = this.getBankAccount(params.writableBankIndex);
|
|
329
|
+
bankAccountMap.set(params.writableBankIndex.toNumber(), {
|
|
330
|
+
pubkey: bankAccount.pubkey,
|
|
331
|
+
isSigner: false,
|
|
332
|
+
isWritable: true,
|
|
622
333
|
});
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
627
|
-
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelAllOrdersIx(oracles, bestEffort)), [], this.opts);
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
getCancelAllOrdersIx(oracles, bestEffort) {
|
|
631
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
632
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
633
|
-
const userAccount = yield this.getUserAccount();
|
|
634
|
-
const state = this.getStateAccount();
|
|
635
|
-
const orderState = this.getOrderStateAccount();
|
|
636
|
-
const remainingAccounts = [];
|
|
637
|
-
for (const oracle of oracles) {
|
|
638
|
-
remainingAccounts.push({
|
|
639
|
-
pubkey: oracle,
|
|
640
|
-
isWritable: false,
|
|
334
|
+
if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
|
|
335
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
336
|
+
pubkey: bankAccount.oracle,
|
|
641
337
|
isSigner: false,
|
|
338
|
+
isWritable: false,
|
|
642
339
|
});
|
|
643
340
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
341
|
+
}
|
|
342
|
+
return [
|
|
343
|
+
...oracleAccountMap.values(),
|
|
344
|
+
...bankAccountMap.values(),
|
|
345
|
+
...marketAccountMap.values(),
|
|
346
|
+
];
|
|
347
|
+
}
|
|
348
|
+
getOrder(orderId) {
|
|
349
|
+
var _a;
|
|
350
|
+
const orderIdBN = orderId instanceof anchor_1.BN ? orderId : new anchor_1.BN(orderId);
|
|
351
|
+
return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.orderId.eq(orderIdBN));
|
|
352
|
+
}
|
|
353
|
+
getOrderByUserId(userOrderId) {
|
|
354
|
+
var _a;
|
|
355
|
+
return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.userOrderId === userOrderId);
|
|
356
|
+
}
|
|
357
|
+
async deposit(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly = false) {
|
|
358
|
+
const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly, true);
|
|
359
|
+
const tx = new web3_js_1.Transaction().add(depositCollateralIx);
|
|
360
|
+
const { txSig } = await this.txSender.send(tx);
|
|
361
|
+
return txSig;
|
|
362
|
+
}
|
|
363
|
+
async getDepositInstruction(amount, bankIndex, userTokenAccount, userId, reduceOnly = false, userInitialized = true) {
|
|
364
|
+
const userAccountPublicKey = userId
|
|
365
|
+
? await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, userId)
|
|
366
|
+
: await this.getUserAccountPublicKey();
|
|
367
|
+
let remainingAccounts = [];
|
|
368
|
+
if (userInitialized) {
|
|
369
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
370
|
+
writableBankIndex: bankIndex,
|
|
658
371
|
});
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
getCancelOrdersByMarketAndSideIx(oracles, bestEffort, marketIndexOnly, directionOnly) {
|
|
667
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
668
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
669
|
-
const userAccount = yield this.getUserAccount();
|
|
670
|
-
const state = this.getStateAccount();
|
|
671
|
-
const orderState = this.getOrderStateAccount();
|
|
672
|
-
const remainingAccounts = [];
|
|
673
|
-
for (const oracle of oracles) {
|
|
674
|
-
remainingAccounts.push({
|
|
675
|
-
pubkey: oracle,
|
|
676
|
-
isWritable: false,
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
remainingAccounts = [
|
|
375
|
+
{
|
|
376
|
+
pubkey: this.getBankAccount(bankIndex).pubkey,
|
|
677
377
|
isSigner: false,
|
|
678
|
-
|
|
679
|
-
}
|
|
680
|
-
return yield this.program.instruction.cancelOrdersByMarketAndSide(bestEffort, marketIndexOnly, directionOnly, {
|
|
681
|
-
accounts: {
|
|
682
|
-
state: yield this.getStatePublicKey(),
|
|
683
|
-
user: userAccountPublicKey,
|
|
684
|
-
authority: this.wallet.publicKey,
|
|
685
|
-
markets: state.markets,
|
|
686
|
-
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
687
|
-
userPositions: userAccount.positions,
|
|
688
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
689
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
690
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
691
|
-
orderHistory: orderState.orderHistory,
|
|
378
|
+
isWritable: true,
|
|
692
379
|
},
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
380
|
+
];
|
|
381
|
+
}
|
|
382
|
+
const bank = this.getBankAccount(bankIndex);
|
|
383
|
+
return await this.program.instruction.deposit(bankIndex, amount, reduceOnly, {
|
|
384
|
+
accounts: {
|
|
385
|
+
state: await this.getStatePublicKey(),
|
|
386
|
+
bank: bank.pubkey,
|
|
387
|
+
bankVault: bank.vault,
|
|
388
|
+
user: userAccountPublicKey,
|
|
389
|
+
userTokenAccount: userTokenAccount,
|
|
390
|
+
authority: this.wallet.publicKey,
|
|
391
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
392
|
+
},
|
|
393
|
+
remainingAccounts,
|
|
700
394
|
});
|
|
701
395
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Creates the Clearing House User account for a user, and deposits some initial collateral
|
|
398
|
+
* @param userId
|
|
399
|
+
* @param name
|
|
400
|
+
* @param amount
|
|
401
|
+
* @param userTokenAccount
|
|
402
|
+
* @param fromUserId
|
|
403
|
+
* @returns
|
|
404
|
+
*/
|
|
405
|
+
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, bankIndex = new anchor_1.BN(0), userId = 0, name = userName_1.DEFAULT_USER_NAME, fromUserId) {
|
|
406
|
+
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
407
|
+
const depositCollateralIx = fromUserId != null
|
|
408
|
+
? await this.getTransferDepositIx(amount, bankIndex, fromUserId, userId)
|
|
409
|
+
: await this.getDepositInstruction(amount, bankIndex, userTokenAccount, userId, false, false);
|
|
410
|
+
const tx = new web3_js_1.Transaction()
|
|
411
|
+
.add(initializeUserAccountIx)
|
|
412
|
+
.add(depositCollateralIx);
|
|
413
|
+
const { txSig } = await this.txSender.send(tx, []);
|
|
414
|
+
return [txSig, userAccountPublicKey];
|
|
415
|
+
}
|
|
416
|
+
async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, mockUSDCFaucet, amount) {
|
|
417
|
+
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await mockUSDCFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
418
|
+
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
419
|
+
const depositCollateralIx = await this.getDepositInstruction(amount, new anchor_1.BN(0), associateTokenPublicKey, userId, false, false);
|
|
420
|
+
const tx = new web3_js_1.Transaction()
|
|
421
|
+
.add(createAssociatedAccountIx)
|
|
422
|
+
.add(mintToIx)
|
|
423
|
+
.add(initializeUserAccountIx)
|
|
424
|
+
.add(depositCollateralIx);
|
|
425
|
+
const txSig = await this.program.provider.sendAndConfirm(tx, []);
|
|
426
|
+
return [txSig, userAccountPublicKey];
|
|
427
|
+
}
|
|
428
|
+
async withdraw(amount, bankIndex, userTokenAccount, reduceOnly = false) {
|
|
429
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly)), [], this.opts);
|
|
430
|
+
return txSig;
|
|
431
|
+
}
|
|
432
|
+
async getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly = false) {
|
|
433
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
434
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
435
|
+
writableBankIndex: bankIndex,
|
|
436
|
+
});
|
|
437
|
+
const bank = this.getBankAccount(bankIndex);
|
|
438
|
+
return await this.program.instruction.withdraw(bankIndex, amount, reduceOnly, {
|
|
439
|
+
accounts: {
|
|
440
|
+
state: await this.getStatePublicKey(),
|
|
441
|
+
bank: bank.pubkey,
|
|
442
|
+
bankVault: bank.vault,
|
|
443
|
+
bankVaultAuthority: bank.vaultAuthority,
|
|
444
|
+
user: userAccountPublicKey,
|
|
445
|
+
userTokenAccount: userTokenAccount,
|
|
446
|
+
authority: this.wallet.publicKey,
|
|
447
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
448
|
+
},
|
|
449
|
+
remainingAccounts,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
async transferDeposit(amount, bankIndex, fromUserId, toUserId) {
|
|
453
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTransferDepositIx(amount, bankIndex, fromUserId, toUserId)), [], this.opts);
|
|
454
|
+
return txSig;
|
|
455
|
+
}
|
|
456
|
+
async getTransferDepositIx(amount, bankIndex, fromUserId, toUserId) {
|
|
457
|
+
const fromUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, fromUserId);
|
|
458
|
+
const toUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, toUserId);
|
|
459
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
460
|
+
writableBankIndex: bankIndex,
|
|
461
|
+
});
|
|
462
|
+
return await this.program.instruction.transferDeposit(bankIndex, amount, {
|
|
463
|
+
accounts: {
|
|
464
|
+
authority: this.wallet.publicKey,
|
|
465
|
+
fromUser,
|
|
466
|
+
toUser,
|
|
467
|
+
state: await this.getStatePublicKey(),
|
|
468
|
+
},
|
|
469
|
+
remainingAccounts,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
async updateBankCumulativeInterest(bankIndex) {
|
|
473
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.updateBankCumulativeInterestIx(bankIndex)), [], this.opts);
|
|
474
|
+
return txSig;
|
|
475
|
+
}
|
|
476
|
+
async updateBankCumulativeInterestIx(bankIndex) {
|
|
477
|
+
const bank = this.getBankAccount(bankIndex);
|
|
478
|
+
return await this.program.instruction.updateBankCumulativeInterest({
|
|
479
|
+
accounts: {
|
|
480
|
+
bank: bank.pubkey,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
async openPosition(direction, amount, marketIndex, limitPrice) {
|
|
485
|
+
return await this.placeAndTake((0, orderParams_1.getMarketOrderParams)(marketIndex, direction, numericConstants_1.ZERO, amount, false, limitPrice));
|
|
486
|
+
}
|
|
487
|
+
async placeOrder(orderParams) {
|
|
488
|
+
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceOrderIx(orderParams)), [], this.opts);
|
|
489
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
490
|
+
return txSig;
|
|
491
|
+
}
|
|
492
|
+
async getPlaceOrderIx(orderParams) {
|
|
493
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
494
|
+
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
495
|
+
.oracle;
|
|
496
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
497
|
+
writableMarketIndex: orderParams.marketIndex,
|
|
498
|
+
});
|
|
499
|
+
return await this.program.instruction.placeOrder(orderParams, {
|
|
500
|
+
accounts: {
|
|
501
|
+
state: await this.getStatePublicKey(),
|
|
502
|
+
user: userAccountPublicKey,
|
|
503
|
+
authority: this.wallet.publicKey,
|
|
504
|
+
oracle: priceOracle,
|
|
505
|
+
},
|
|
506
|
+
remainingAccounts,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
async expireOrders(userAccountPublicKey) {
|
|
510
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getExpireOrdersIx(userAccountPublicKey)), [], this.opts);
|
|
511
|
+
return txSig;
|
|
512
|
+
}
|
|
513
|
+
async getExpireOrdersIx(userAccountPublicKey) {
|
|
514
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
515
|
+
return await this.program.instruction.expireOrders({
|
|
516
|
+
accounts: {
|
|
517
|
+
state: await this.getStatePublicKey(),
|
|
518
|
+
filler: fillerPublicKey,
|
|
519
|
+
user: userAccountPublicKey,
|
|
520
|
+
authority: this.wallet.publicKey,
|
|
521
|
+
},
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
async updateAMMs(marketIndexes) {
|
|
525
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateAMMsIx(marketIndexes)), [], this.opts);
|
|
526
|
+
return txSig;
|
|
527
|
+
}
|
|
528
|
+
async getUpdateAMMsIx(marketIndexes) {
|
|
529
|
+
for (let i = marketIndexes.length; i < 5; i++) {
|
|
530
|
+
marketIndexes.push(new anchor_1.BN(100));
|
|
531
|
+
}
|
|
532
|
+
const marketAccountInfos = [];
|
|
533
|
+
const oracleAccountInfos = [];
|
|
534
|
+
for (const marketIndex of marketIndexes) {
|
|
535
|
+
if (!marketIndex.eq(new anchor_1.BN(100))) {
|
|
536
|
+
const market = this.getMarketAccount(marketIndex);
|
|
537
|
+
marketAccountInfos.push({
|
|
538
|
+
pubkey: market.pubkey,
|
|
714
539
|
isWritable: true,
|
|
715
540
|
isSigner: false,
|
|
716
541
|
});
|
|
542
|
+
oracleAccountInfos.push({
|
|
543
|
+
pubkey: market.amm.oracle,
|
|
544
|
+
isWritable: false,
|
|
545
|
+
isSigner: false,
|
|
546
|
+
});
|
|
717
547
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
548
|
+
}
|
|
549
|
+
const remainingAccounts = oracleAccountInfos.concat(marketAccountInfos);
|
|
550
|
+
return await this.program.instruction.updateAmms(marketIndexes, {
|
|
551
|
+
accounts: {
|
|
552
|
+
state: await this.getStatePublicKey(),
|
|
553
|
+
authority: this.wallet.publicKey,
|
|
554
|
+
},
|
|
555
|
+
remainingAccounts,
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
async cancelOrder(orderId) {
|
|
559
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrderIx(orderId)), [], this.opts);
|
|
560
|
+
return txSig;
|
|
561
|
+
}
|
|
562
|
+
async getCancelOrderIx(orderId) {
|
|
563
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
564
|
+
const order = this.getOrder(orderId);
|
|
565
|
+
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
566
|
+
const remainingAccounts = this.getRemainingAccounts({});
|
|
567
|
+
return await this.program.instruction.cancelOrder(orderId, {
|
|
568
|
+
accounts: {
|
|
569
|
+
state: await this.getStatePublicKey(),
|
|
570
|
+
user: userAccountPublicKey,
|
|
571
|
+
authority: this.wallet.publicKey,
|
|
572
|
+
oracle,
|
|
573
|
+
},
|
|
574
|
+
remainingAccounts,
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async cancelOrderByUserId(userOrderId) {
|
|
578
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrderByUserIdIx(userOrderId)), [], this.opts);
|
|
579
|
+
return txSig;
|
|
580
|
+
}
|
|
581
|
+
async getCancelOrderByUserIdIx(userOrderId) {
|
|
582
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
583
|
+
const order = this.getOrderByUserId(userOrderId);
|
|
584
|
+
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
585
|
+
const remainingAccounts = this.getRemainingAccounts({});
|
|
586
|
+
return await this.program.instruction.cancelOrderByUserId(userOrderId, {
|
|
587
|
+
accounts: {
|
|
588
|
+
state: await this.getStatePublicKey(),
|
|
589
|
+
user: userAccountPublicKey,
|
|
590
|
+
authority: this.wallet.publicKey,
|
|
591
|
+
oracle,
|
|
592
|
+
},
|
|
593
|
+
remainingAccounts,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
async cancelAllOrders(bestEffort) {
|
|
597
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelAllOrdersIx(bestEffort)), [], this.opts);
|
|
598
|
+
return txSig;
|
|
599
|
+
}
|
|
600
|
+
async getCancelAllOrdersIx(bestEffort) {
|
|
601
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
602
|
+
const remainingAccounts = this.getRemainingAccounts({});
|
|
603
|
+
for (const order of this.getUserAccount().orders) {
|
|
604
|
+
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
605
|
+
remainingAccounts.push({
|
|
606
|
+
pubkey: oracle,
|
|
607
|
+
isWritable: false,
|
|
608
|
+
isSigner: false,
|
|
737
609
|
});
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
.
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
610
|
+
}
|
|
611
|
+
return await this.program.instruction.cancelAllOrders(bestEffort, {
|
|
612
|
+
accounts: {
|
|
613
|
+
state: await this.getStatePublicKey(),
|
|
614
|
+
user: userAccountPublicKey,
|
|
615
|
+
authority: this.wallet.publicKey,
|
|
616
|
+
},
|
|
617
|
+
remainingAccounts,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
async cancelOrdersByMarketAndSide(bestEffort, marketIndexOnly, directionOnly) {
|
|
621
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrdersByMarketAndSideIx(bestEffort, marketIndexOnly, directionOnly)), [], this.opts);
|
|
622
|
+
return txSig;
|
|
623
|
+
}
|
|
624
|
+
async getCancelOrdersByMarketAndSideIx(bestEffort, marketIndexOnly, directionOnly) {
|
|
625
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
626
|
+
const remainingAccounts = this.getRemainingAccounts({});
|
|
627
|
+
for (const order of this.getUserAccount().orders) {
|
|
628
|
+
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
629
|
+
remainingAccounts.push({
|
|
630
|
+
pubkey: oracle,
|
|
631
|
+
isWritable: false,
|
|
632
|
+
isSigner: false,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
return await this.program.instruction.cancelOrdersByMarketAndSide(bestEffort, marketIndexOnly, directionOnly, {
|
|
636
|
+
accounts: {
|
|
637
|
+
state: await this.getStatePublicKey(),
|
|
638
|
+
user: userAccountPublicKey,
|
|
639
|
+
authority: this.wallet.publicKey,
|
|
640
|
+
},
|
|
641
|
+
remainingAccounts,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
async fillOrder(userAccountPublicKey, user, order, makerInfo) {
|
|
645
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
|
|
646
|
+
return txSig;
|
|
647
|
+
}
|
|
648
|
+
async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
|
|
649
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
650
|
+
const marketIndex = order.marketIndex;
|
|
651
|
+
const marketAccount = this.getMarketAccount(marketIndex);
|
|
652
|
+
const oracle = marketAccount.amm.oracle;
|
|
653
|
+
const bankAccountInfos = [
|
|
654
|
+
{
|
|
655
|
+
pubkey: this.getQuoteAssetBankAccount().pubkey,
|
|
656
|
+
isSigner: false,
|
|
657
|
+
isWritable: true,
|
|
658
|
+
},
|
|
659
|
+
];
|
|
660
|
+
const marketAccountInfos = [
|
|
661
|
+
{
|
|
662
|
+
pubkey: marketAccount.pubkey,
|
|
663
|
+
isWritable: true,
|
|
664
|
+
isSigner: false,
|
|
665
|
+
},
|
|
666
|
+
];
|
|
667
|
+
const oracleAccountInfos = [
|
|
668
|
+
{
|
|
669
|
+
pubkey: marketAccount.amm.oracle,
|
|
670
|
+
isWritable: false,
|
|
671
|
+
isSigner: false,
|
|
672
|
+
},
|
|
673
|
+
];
|
|
674
|
+
for (const position of userAccount.positions) {
|
|
675
|
+
if (!(0, position_1.positionIsAvailable)(position) &&
|
|
676
|
+
!position.marketIndex.eq(order.marketIndex)) {
|
|
677
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
678
|
+
marketAccountInfos.push({
|
|
679
|
+
pubkey: market.pubkey,
|
|
773
680
|
isWritable: false,
|
|
774
681
|
isSigner: false,
|
|
775
682
|
});
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
throw Error('Optional accounts specified referrer but no referrer present');
|
|
780
|
-
}
|
|
781
|
-
remainingAccounts.push({
|
|
782
|
-
pubkey: referrer,
|
|
783
|
-
isWritable: true,
|
|
683
|
+
oracleAccountInfos.push({
|
|
684
|
+
pubkey: market.amm.oracle,
|
|
685
|
+
isWritable: false,
|
|
784
686
|
isSigner: false,
|
|
785
687
|
});
|
|
786
688
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
markets: state.markets,
|
|
795
|
-
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
796
|
-
userPositions: userAccount.positions,
|
|
797
|
-
tradeHistory: state.tradeHistory,
|
|
798
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
799
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
800
|
-
orderState: yield this.getOrderStatePublicKey(),
|
|
801
|
-
orderHistory: orderState.orderHistory,
|
|
802
|
-
extendedCurveHistory: state.extendedCurveHistory,
|
|
803
|
-
oracle: priceOracle,
|
|
804
|
-
},
|
|
805
|
-
remainingAccounts,
|
|
689
|
+
}
|
|
690
|
+
const remainingAccounts = oracleAccountInfos.concat(bankAccountInfos.concat(marketAccountInfos));
|
|
691
|
+
if (makerInfo) {
|
|
692
|
+
remainingAccounts.push({
|
|
693
|
+
pubkey: makerInfo.maker,
|
|
694
|
+
isWritable: true,
|
|
695
|
+
isSigner: false,
|
|
806
696
|
});
|
|
697
|
+
}
|
|
698
|
+
const orderId = order.orderId;
|
|
699
|
+
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
700
|
+
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
701
|
+
accounts: {
|
|
702
|
+
state: await this.getStatePublicKey(),
|
|
703
|
+
filler: fillerPublicKey,
|
|
704
|
+
user: userAccountPublicKey,
|
|
705
|
+
authority: this.wallet.publicKey,
|
|
706
|
+
oracle: oracle,
|
|
707
|
+
},
|
|
708
|
+
remainingAccounts,
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
async placeAndTake(orderParams, makerInfo) {
|
|
712
|
+
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndTakeIx(orderParams, makerInfo)), [], this.opts);
|
|
713
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
714
|
+
return txSig;
|
|
715
|
+
}
|
|
716
|
+
async getPlaceAndTakeIx(orderParams, makerInfo) {
|
|
717
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
718
|
+
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
719
|
+
.oracle;
|
|
720
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
721
|
+
writableMarketIndex: orderParams.marketIndex,
|
|
722
|
+
writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
|
|
723
|
+
});
|
|
724
|
+
let makerOrderId = null;
|
|
725
|
+
if (makerInfo) {
|
|
726
|
+
makerOrderId = makerInfo.order.orderId;
|
|
727
|
+
remainingAccounts.push({
|
|
728
|
+
pubkey: makerInfo.maker,
|
|
729
|
+
isSigner: false,
|
|
730
|
+
isWritable: true,
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
return await this.program.instruction.placeAndTake(orderParams, makerOrderId, {
|
|
734
|
+
accounts: {
|
|
735
|
+
state: await this.getStatePublicKey(),
|
|
736
|
+
user: userAccountPublicKey,
|
|
737
|
+
authority: this.wallet.publicKey,
|
|
738
|
+
oracle: priceOracle,
|
|
739
|
+
},
|
|
740
|
+
remainingAccounts,
|
|
807
741
|
});
|
|
808
742
|
}
|
|
809
743
|
/**
|
|
810
744
|
* Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
|
|
811
745
|
* @param marketIndex
|
|
812
|
-
* @param discountToken
|
|
813
|
-
* @param referrer
|
|
814
746
|
* @returns
|
|
815
747
|
*/
|
|
816
|
-
closePosition(marketIndex
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
748
|
+
async closePosition(marketIndex) {
|
|
749
|
+
const userPosition = this.getUser().getUserPosition(marketIndex);
|
|
750
|
+
if (!userPosition) {
|
|
751
|
+
throw Error(`No position in market ${marketIndex.toString()}`);
|
|
752
|
+
}
|
|
753
|
+
return await this.placeAndTake((0, orderParams_1.getMarketOrderParams)(marketIndex, (0, position_1.findDirectionToClose)(userPosition), numericConstants_1.ZERO, userPosition.baseAssetAmount, true, undefined));
|
|
820
754
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
755
|
+
async settlePNLs(users, marketIndex) {
|
|
756
|
+
const ixs = [];
|
|
757
|
+
for (const { settleeUserAccountPublicKey, settleeUserAccount } of users) {
|
|
758
|
+
ixs.push(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex));
|
|
759
|
+
}
|
|
760
|
+
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
761
|
+
const { txSig } = await this.txSender.send(tx, [], this.opts);
|
|
762
|
+
return txSig;
|
|
763
|
+
}
|
|
764
|
+
async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
|
|
765
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex)), [], this.opts);
|
|
766
|
+
return txSig;
|
|
767
|
+
}
|
|
768
|
+
async settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
|
|
769
|
+
const marketAccountMap = new Map();
|
|
770
|
+
const oracleAccountMap = new Map();
|
|
771
|
+
const bankAccountMap = new Map();
|
|
772
|
+
for (const position of settleeUserAccount.positions) {
|
|
773
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
774
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
775
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
776
|
+
pubkey: market.pubkey,
|
|
777
|
+
isWritable: true,
|
|
778
|
+
isSigner: false,
|
|
779
|
+
});
|
|
780
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
781
|
+
pubkey: market.amm.oracle,
|
|
835
782
|
isWritable: false,
|
|
836
783
|
isSigner: false,
|
|
837
784
|
});
|
|
838
785
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
786
|
+
}
|
|
787
|
+
for (const userBankBalance of settleeUserAccount.bankBalances) {
|
|
788
|
+
if (!userBankBalance.balance.eq(numericConstants_1.QUOTE_ASSET_BANK_INDEX)) {
|
|
789
|
+
const bankAccount = this.getBankAccount(userBankBalance.bankIndex);
|
|
790
|
+
bankAccountMap.set(userBankBalance.bankIndex.toNumber(), {
|
|
791
|
+
pubkey: bankAccount.pubkey,
|
|
844
792
|
isSigner: false,
|
|
793
|
+
isWritable: false,
|
|
845
794
|
});
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
accounts: {
|
|
850
|
-
state: yield this.getStatePublicKey(),
|
|
851
|
-
user: userAccountPublicKey,
|
|
852
|
-
authority: this.wallet.publicKey,
|
|
853
|
-
markets: state.markets,
|
|
854
|
-
userPositions: userAccount.positions,
|
|
855
|
-
tradeHistory: state.tradeHistory,
|
|
856
|
-
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
857
|
-
fundingRateHistory: state.fundingRateHistory,
|
|
858
|
-
oracle: priceOracle,
|
|
859
|
-
},
|
|
860
|
-
remainingAccounts: remainingAccounts,
|
|
861
|
-
});
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
closeAllPositions(userPositionsAccount, discountToken, referrer) {
|
|
865
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
866
|
-
const ixs = [];
|
|
867
|
-
for (const userPosition of userPositionsAccount.positions) {
|
|
868
|
-
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
869
|
-
continue;
|
|
870
|
-
}
|
|
871
|
-
ixs.push(yield this.getClosePositionIx(userPosition.marketIndex, discountToken, referrer));
|
|
872
|
-
}
|
|
873
|
-
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
874
|
-
return this.txSender.send(tx, [], this.opts);
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
liquidate(liquidateeUserAccountPublicKey) {
|
|
878
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
879
|
-
return this.txSender.send((0, utils_1.wrapInTx)(yield this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
getLiquidateIx(liquidateeUserAccountPublicKey) {
|
|
883
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
884
|
-
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
885
|
-
const liquidateeUserAccount = yield this.program.account.user.fetch(liquidateeUserAccountPublicKey);
|
|
886
|
-
const liquidateePositions = yield this.program.account.userPositions.fetch(liquidateeUserAccount.positions);
|
|
887
|
-
const markets = this.getMarketsAccount();
|
|
888
|
-
const remainingAccounts = [];
|
|
889
|
-
for (const position of liquidateePositions.positions) {
|
|
890
|
-
if (!position.baseAssetAmount.eq(new anchor_1.BN(0))) {
|
|
891
|
-
const market = markets.markets[position.marketIndex.toNumber()];
|
|
892
|
-
remainingAccounts.push({
|
|
893
|
-
pubkey: market.amm.oracle,
|
|
894
|
-
isWritable: false,
|
|
795
|
+
if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
|
|
796
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
797
|
+
pubkey: bankAccount.oracle,
|
|
895
798
|
isSigner: false,
|
|
799
|
+
isWritable: false,
|
|
896
800
|
});
|
|
897
801
|
}
|
|
898
802
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
|
|
803
|
+
}
|
|
804
|
+
const marketAccount = this.getMarketAccount(marketIndex.toNumber());
|
|
805
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
806
|
+
pubkey: marketAccount.pubkey,
|
|
807
|
+
isSigner: false,
|
|
808
|
+
isWritable: true,
|
|
809
|
+
});
|
|
810
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
811
|
+
pubkey: marketAccount.amm.oracle,
|
|
812
|
+
isSigner: false,
|
|
813
|
+
isWritable: false,
|
|
814
|
+
});
|
|
815
|
+
bankAccountMap.set(numericConstants_1.QUOTE_ASSET_BANK_INDEX.toNumber(), {
|
|
816
|
+
pubkey: this.getBankAccount(numericConstants_1.QUOTE_ASSET_BANK_INDEX).pubkey,
|
|
817
|
+
isSigner: false,
|
|
818
|
+
isWritable: true,
|
|
819
|
+
});
|
|
820
|
+
const remainingAccounts = [
|
|
821
|
+
...oracleAccountMap.values(),
|
|
822
|
+
...bankAccountMap.values(),
|
|
823
|
+
...marketAccountMap.values(),
|
|
824
|
+
];
|
|
825
|
+
return await this.program.instruction.settlePnl(marketIndex, {
|
|
826
|
+
accounts: {
|
|
827
|
+
state: await this.getStatePublicKey(),
|
|
828
|
+
authority: this.wallet.publicKey,
|
|
829
|
+
user: settleeUserAccountPublicKey,
|
|
830
|
+
},
|
|
831
|
+
remainingAccounts: remainingAccounts,
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
async liquidate(liquidateeUserAccountPublicKey) {
|
|
835
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
|
|
836
|
+
return txSig;
|
|
837
|
+
}
|
|
838
|
+
async getLiquidateIx(liquidateeUserAccountPublicKey) {
|
|
839
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
840
|
+
const liquidateeUserAccount = (await this.program.account.user.fetch(liquidateeUserAccountPublicKey));
|
|
841
|
+
const bankAccountInfos = [
|
|
842
|
+
{
|
|
843
|
+
pubkey: this.getQuoteAssetBankAccount().pubkey,
|
|
844
|
+
isSigner: false,
|
|
845
|
+
isWritable: true,
|
|
846
|
+
},
|
|
847
|
+
];
|
|
848
|
+
const marketAccountInfos = [];
|
|
849
|
+
const oracleAccountInfos = [];
|
|
850
|
+
for (const position of liquidateeUserAccount.positions) {
|
|
851
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
852
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
853
|
+
const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, position.marketIndex);
|
|
854
|
+
marketAccountInfos.push({
|
|
855
|
+
pubkey: marketPublicKey,
|
|
856
|
+
isWritable: true,
|
|
857
|
+
isSigner: false,
|
|
858
|
+
});
|
|
859
|
+
oracleAccountInfos.push({
|
|
860
|
+
pubkey: market.amm.oracle,
|
|
861
|
+
isWritable: false,
|
|
862
|
+
isSigner: false,
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
const remainingAccounts = oracleAccountInfos.concat(bankAccountInfos.concat(marketAccountInfos));
|
|
867
|
+
const state = this.getStateAccount();
|
|
868
|
+
const quoteAssetBankAccount = this.getQuoteAssetBankAccount();
|
|
869
|
+
return await this.program.instruction.liquidate({
|
|
870
|
+
accounts: {
|
|
871
|
+
state: await this.getStatePublicKey(),
|
|
872
|
+
authority: this.wallet.publicKey,
|
|
873
|
+
user: liquidateeUserAccountPublicKey,
|
|
874
|
+
liquidator: userAccountPublicKey,
|
|
875
|
+
bankVault: quoteAssetBankAccount.vault,
|
|
876
|
+
bankVaultAuthority: quoteAssetBankAccount.vaultAuthority,
|
|
877
|
+
insuranceVault: state.insuranceVault,
|
|
878
|
+
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
879
|
+
},
|
|
880
|
+
remainingAccounts: remainingAccounts,
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
async updateFundingRate(oracle, marketIndex) {
|
|
884
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateFundingRateIx(oracle, marketIndex)), [], this.opts);
|
|
885
|
+
return txSig;
|
|
886
|
+
}
|
|
887
|
+
async getUpdateFundingRateIx(oracle, marketIndex) {
|
|
888
|
+
return await this.program.instruction.updateFundingRate(marketIndex, {
|
|
889
|
+
accounts: {
|
|
890
|
+
state: await this.getStatePublicKey(),
|
|
891
|
+
market: await (0, pda_1.getMarketPublicKey)(this.program.programId, marketIndex),
|
|
892
|
+
oracle: oracle,
|
|
893
|
+
},
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
async settleFundingPayment(userAccount) {
|
|
897
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getSettleFundingPaymentIx(userAccount)), [], this.opts);
|
|
898
|
+
return txSig;
|
|
899
|
+
}
|
|
900
|
+
async getSettleFundingPaymentIx(userAccount) {
|
|
901
|
+
const user = (await this.program.account.user.fetch(userAccount));
|
|
902
|
+
const userPositions = user.positions;
|
|
903
|
+
const remainingAccounts = [];
|
|
904
|
+
for (const position of userPositions) {
|
|
905
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
906
|
+
const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, position.marketIndex);
|
|
907
|
+
remainingAccounts.push({
|
|
908
|
+
pubkey: marketPublicKey,
|
|
909
|
+
isWritable: false,
|
|
910
|
+
isSigner: false,
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return await this.program.instruction.settleFundingPayment({
|
|
915
|
+
accounts: {
|
|
916
|
+
state: await this.getStatePublicKey(),
|
|
917
|
+
user: userAccount,
|
|
918
|
+
},
|
|
919
|
+
remainingAccounts,
|
|
956
920
|
});
|
|
957
921
|
}
|
|
958
922
|
triggerEvent(eventName, data) {
|
|
959
923
|
this.eventEmitter.emit(eventName, data);
|
|
960
924
|
}
|
|
925
|
+
getOracleDataForMarket(marketIndex) {
|
|
926
|
+
const oracleKey = this.getMarketAccount(marketIndex).amm.oracle;
|
|
927
|
+
const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
|
|
928
|
+
return oracleData;
|
|
929
|
+
}
|
|
961
930
|
}
|
|
962
931
|
exports.ClearingHouse = ClearingHouse;
|