@carrot-protocol/boost-http-client 0.2.15-swapper1-dev-cda79a9 → 0.2.15
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/dist/index.d.ts +8 -8
- package/dist/index.js +128 -126
- package/dist/types.d.ts +30 -7
- package/dist/utils.d.ts +0 -2
- package/dist/utils.js +0 -9
- package/package.json +2 -2
- package/src/index.ts +188 -160
- package/src/types.ts +38 -8
- package/src/utils.ts +0 -8
package/dist/index.d.ts
CHANGED
|
@@ -22,12 +22,7 @@ export declare class Client {
|
|
|
22
22
|
* @returns Index details
|
|
23
23
|
*/
|
|
24
24
|
index(): Promise<any>;
|
|
25
|
-
|
|
26
|
-
* Get user details for a wallet
|
|
27
|
-
* @param user wallet public key
|
|
28
|
-
* @returns User details
|
|
29
|
-
*/
|
|
30
|
-
getUser(groups: web3.PublicKey[], user: web3.PublicKey, getClendAccountSummary: boolean): Promise<GetUserResponse>;
|
|
25
|
+
getUser(user: web3.PublicKey, groups: web3.PublicKey[], getClendAccountSummary: boolean): Promise<GetUserResponse>;
|
|
31
26
|
/**
|
|
32
27
|
* Get all groups
|
|
33
28
|
* @param includeBankData Whether to include bank data in the response, if not strictly necessary keep false
|
|
@@ -57,11 +52,16 @@ export declare class Client {
|
|
|
57
52
|
* @param request Adjust leverage request parameters
|
|
58
53
|
* @returns Adjust leverage operation result
|
|
59
54
|
*/
|
|
60
|
-
adjustLeverage(
|
|
55
|
+
adjustLeverage(clendAccount: web3.PublicKey, assetTokenMint: web3.PublicKey, liabilityTokenMint: web3.PublicKey, leverage: number, slippageBps: number): Promise<string>;
|
|
61
56
|
/**
|
|
62
57
|
* Withdraw from or close a leveraged position
|
|
63
58
|
* @param request Withdraw leverage request parameters
|
|
64
59
|
* @returns Withdraw leverage operation result
|
|
65
60
|
*/
|
|
66
|
-
withdrawLeverage(
|
|
61
|
+
withdrawLeverage(clendAccount: web3.PublicKey, outputTokenMint: web3.PublicKey, assetTokenMint: web3.PublicKey, liabilityTokenMint: web3.PublicKey, uiAmount: number, slippageBps: number, withdrawAll: boolean): Promise<string>;
|
|
62
|
+
/**
|
|
63
|
+
* Withdraw emissions from a bank
|
|
64
|
+
* @returns Withdraw emissions operation result
|
|
65
|
+
*/
|
|
66
|
+
withdrawEmissions(): Promise<string>;
|
|
67
67
|
}
|
package/dist/index.js
CHANGED
|
@@ -99,143 +99,131 @@ class Client {
|
|
|
99
99
|
async index() {
|
|
100
100
|
return handleApiCall(() => this.http.get(""));
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* @param user wallet public key
|
|
105
|
-
* @returns User details
|
|
106
|
-
*/
|
|
107
|
-
async getUser(groups, user, getClendAccountSummary) {
|
|
102
|
+
async getUser(user, groups, getClendAccountSummary) {
|
|
103
|
+
// Make the API call to fetch the raw user data as a string.
|
|
108
104
|
const body = await handleApiCall(() => this.http.get(`/user?user=${user.toString()}&groups=${groups.map((g) => g.toString()).join(",")}&getClendAccountSummary=${getClendAccountSummary}`));
|
|
105
|
+
// Parse the raw string body into a JSON object.
|
|
109
106
|
const jsonRawResponse = JSON.parse(body);
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
const walletBalances = []
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
balanceUi: Number(b.balanceUi),
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
// get tokens still in user wallet
|
|
107
|
+
// 1. Parse Wallet Balances
|
|
108
|
+
// This section correctly iterates through the wallet balances and creates typed objects.
|
|
109
|
+
const walletBalances = (jsonRawResponse.wallet.balances || []).map((b) => ({
|
|
110
|
+
mint: new anchor_1.web3.PublicKey(b.mint),
|
|
111
|
+
balance: new anchor_1.BN(b.balance, "hex"),
|
|
112
|
+
balanceUi: Number(b.balanceUi),
|
|
113
|
+
}));
|
|
121
114
|
const wallet = {
|
|
122
115
|
balances: walletBalances,
|
|
123
116
|
};
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
const txSummary = {
|
|
133
|
-
txSig: s.txSig,
|
|
134
|
-
time: s.time,
|
|
135
|
-
clendAccount: new anchor_1.web3.PublicKey(s.clendAccount),
|
|
136
|
-
clendAccountAuthority: new anchor_1.web3.PublicKey(s.clendAccountAuthority),
|
|
137
|
-
clendGroup: new anchor_1.web3.PublicKey(s.clendGroup),
|
|
138
|
-
action: s.action,
|
|
139
|
-
input: undefined,
|
|
140
|
-
events: [],
|
|
141
|
-
};
|
|
142
|
-
// parse inputs if they exist
|
|
143
|
-
if (s.input) {
|
|
144
|
-
const input = {
|
|
145
|
-
apiPath: s.input.apiPath,
|
|
146
|
-
selectedTokenMint: s.input.selectedTokenMint
|
|
147
|
-
? new anchor_1.web3.PublicKey(s.input.selectedTokenMint)
|
|
148
|
-
: null,
|
|
149
|
-
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
150
|
-
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
151
|
-
slippageBps: s.input.slippageBps
|
|
152
|
-
? Number(s.input.slippageBps)
|
|
153
|
-
: null,
|
|
154
|
-
openPosition: s.input.openPosition
|
|
155
|
-
? Boolean(s.input.openPosition)
|
|
156
|
-
: null,
|
|
157
|
-
closePosition: s.input.closePosition
|
|
158
|
-
? Boolean(s.input.closePosition)
|
|
159
|
-
: null,
|
|
160
|
-
};
|
|
161
|
-
txSummary.input = input;
|
|
162
|
-
}
|
|
163
|
-
// get events for each summary
|
|
164
|
-
for (const event of s.events) {
|
|
165
|
-
let closeBalance = null;
|
|
166
|
-
if (event.closeBalance !== null) {
|
|
167
|
-
closeBalance = Boolean(event.closeBalance);
|
|
168
|
-
}
|
|
169
|
-
// parse amount
|
|
170
|
-
const clendAccountEvent = {
|
|
171
|
-
eventIndex: event.eventIndex,
|
|
172
|
-
eventName: event.eventName,
|
|
173
|
-
bank: event.bank ? new anchor_1.web3.PublicKey(event.bank) : null,
|
|
174
|
-
mint: event.mint ? new anchor_1.web3.PublicKey(event.mint) : null,
|
|
175
|
-
amount: event.amount ? new anchor_1.BN(event.amount, "hex") : null,
|
|
176
|
-
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
177
|
-
value: event.value ? Number(event.value) : null,
|
|
178
|
-
price: event.price ? Number(event.price) : null,
|
|
179
|
-
closeBalance,
|
|
180
|
-
};
|
|
181
|
-
txSummary.events.push(clendAccountEvent);
|
|
182
|
-
}
|
|
183
|
-
summaryByAccount.get(accountAddress).push(txSummary);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// if no clend accounts, return empty array
|
|
187
|
-
const clendAccounts = [];
|
|
188
|
-
for (const accountAndSumary of jsonRawResponse.clendAccounts) {
|
|
189
|
-
const clendAccountBalances = [];
|
|
190
|
-
const ca = accountAndSumary.clendAccount;
|
|
191
|
-
for (const b of ca.balances) {
|
|
192
|
-
// parse liquidation data if exists
|
|
117
|
+
// 2. Parse Clend Accounts and their Summaries
|
|
118
|
+
// This is the main refactored section. It iterates through the clendAccounts array
|
|
119
|
+
// from the response, which contains both the account data and its summary.
|
|
120
|
+
const clendAccounts = (jsonRawResponse.clendAccounts || []).map((accountData) => {
|
|
121
|
+
// A. Parse the main ClendAccount object
|
|
122
|
+
const rawClendAccount = accountData.clendAccount;
|
|
123
|
+
const clendAccountBalances = (rawClendAccount.balances || []).map((b) => {
|
|
193
124
|
const liquidation = b.liquidation
|
|
194
125
|
? {
|
|
195
126
|
price: Number(b.liquidation.price),
|
|
196
127
|
changePercentage: Number(b.liquidation.changePercentage),
|
|
197
128
|
}
|
|
198
129
|
: null;
|
|
199
|
-
|
|
200
|
-
|
|
130
|
+
const emissionsOutstandingAndUnclaimed = new anchor_1.BN(b.emissionsOutstandingAndUnclaimed, "hex");
|
|
131
|
+
return {
|
|
201
132
|
mint: new anchor_1.web3.PublicKey(b.mint),
|
|
202
133
|
bank: new anchor_1.web3.PublicKey(b.bank),
|
|
134
|
+
tokenYieldApy: Number(b.tokenYieldApy),
|
|
203
135
|
assetBalance: new anchor_1.BN(b.assetBalance, "hex"),
|
|
204
136
|
assetBalanceUi: Number(b.assetBalanceUi),
|
|
205
137
|
assetValue: Number(b.assetValue),
|
|
206
|
-
|
|
207
|
-
assetYieldApy: Number(b.assetYieldApy),
|
|
138
|
+
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
208
139
|
liabilityBalance: new anchor_1.BN(b.liabilityBalance, "hex"),
|
|
209
140
|
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
210
141
|
liabilityValue: Number(b.liabilityValue),
|
|
211
|
-
liabilityBorrowCostBps: Number(b.liabilityBorrowCostBps),
|
|
212
142
|
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
143
|
+
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
144
|
+
emissionsOutstandingAndUnclaimed,
|
|
145
|
+
emissionsOutstandingAndUnclaimedUi: Number(b.emissionsOutstandingAndUnclaimedUi),
|
|
213
146
|
price: Number(b.price),
|
|
214
147
|
liquidation,
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
// create clend account
|
|
218
|
-
const clendAccountAddress = new anchor_1.web3.PublicKey(accountAndSumary.clendAccount.key);
|
|
148
|
+
};
|
|
149
|
+
});
|
|
219
150
|
const clendAccount = {
|
|
220
|
-
key:
|
|
221
|
-
group: new anchor_1.web3.PublicKey(
|
|
151
|
+
key: new anchor_1.web3.PublicKey(rawClendAccount.key),
|
|
152
|
+
group: new anchor_1.web3.PublicKey(rawClendAccount.group),
|
|
222
153
|
balances: clendAccountBalances,
|
|
223
|
-
netValue: Number(
|
|
224
|
-
netApy: Number(
|
|
225
|
-
pnl: Number(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
154
|
+
netValue: Number(rawClendAccount.netValue),
|
|
155
|
+
netApy: Number(rawClendAccount.netApy),
|
|
156
|
+
pnl: Number(rawClendAccount.pnl),
|
|
157
|
+
totalEmissionsApy: Number(rawClendAccount.totalEmissionsApy),
|
|
158
|
+
totalAssetValue: Number(rawClendAccount.totalAssetValue),
|
|
159
|
+
totalLiabilityValue: Number(rawClendAccount.totalLiabilityValue),
|
|
160
|
+
healthFactorNotional: Number(rawClendAccount.healthFactorNotional),
|
|
161
|
+
healthFactorRiskAdjusted: Number(rawClendAccount.healthFactorRiskAdjusted),
|
|
162
|
+
notionalLeverage: Number(rawClendAccount.notionalLeverage),
|
|
163
|
+
riskAdjustedLeverage: Number(rawClendAccount.riskAdjustedLeverage),
|
|
164
|
+
notionalLtv: Number(rawClendAccount.notionalLtv),
|
|
165
|
+
riskAdjustedLtv: Number(rawClendAccount.riskAdjustedLtv),
|
|
234
166
|
};
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
167
|
+
// B. Parse the associated Summary array for the account
|
|
168
|
+
let summary = [];
|
|
169
|
+
if (getClendAccountSummary && accountData.summary) {
|
|
170
|
+
summary = accountData.summary.map((s) => {
|
|
171
|
+
let input = undefined;
|
|
172
|
+
if (s.input) {
|
|
173
|
+
input = {
|
|
174
|
+
apiPath: s.input.apiPath,
|
|
175
|
+
selectedTokenMint: s.input.selectedTokenMint
|
|
176
|
+
? new anchor_1.web3.PublicKey(s.input.selectedTokenMint)
|
|
177
|
+
: null,
|
|
178
|
+
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
179
|
+
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
180
|
+
slippageBps: s.input.slippageBps
|
|
181
|
+
? Number(s.input.slippageBps)
|
|
182
|
+
: null,
|
|
183
|
+
openPosition: s.input.openPosition != null
|
|
184
|
+
? Boolean(s.input.openPosition)
|
|
185
|
+
: null,
|
|
186
|
+
closePosition: s.input.closePosition != null
|
|
187
|
+
? Boolean(s.input.closePosition)
|
|
188
|
+
: null,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const events = (s.events || []).map((event) => {
|
|
192
|
+
let closeBalance = null;
|
|
193
|
+
// Only convert to boolean if the value is not null/undefined to preserve the null state.
|
|
194
|
+
if (event.closeBalance !== null &&
|
|
195
|
+
event.closeBalance !== undefined) {
|
|
196
|
+
closeBalance = Boolean(event.closeBalance);
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
eventIndex: event.eventIndex,
|
|
200
|
+
eventName: event.eventName,
|
|
201
|
+
bank: event.bank ? new anchor_1.web3.PublicKey(event.bank) : null,
|
|
202
|
+
mint: event.mint ? new anchor_1.web3.PublicKey(event.mint) : null,
|
|
203
|
+
amount: event.amount ? new anchor_1.BN(event.amount, "hex") : null,
|
|
204
|
+
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
205
|
+
value: event.value ? Number(event.value) : null,
|
|
206
|
+
price: event.price ? Number(event.price) : null,
|
|
207
|
+
closeBalance,
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
const txSummary = {
|
|
211
|
+
txSig: s.txSig,
|
|
212
|
+
time: s.time,
|
|
213
|
+
clendAccount: new anchor_1.web3.PublicKey(s.clendAccount),
|
|
214
|
+
clendAccountAuthority: new anchor_1.web3.PublicKey(s.clendAccountAuthority),
|
|
215
|
+
clendGroup: new anchor_1.web3.PublicKey(s.clendGroup),
|
|
216
|
+
action: s.action,
|
|
217
|
+
input,
|
|
218
|
+
events,
|
|
219
|
+
};
|
|
220
|
+
return txSummary;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
// C. Combine the parsed account and its summary
|
|
224
|
+
return { clendAccount, summary };
|
|
225
|
+
});
|
|
226
|
+
// 3. Return the final, correctly structured response object.
|
|
239
227
|
return {
|
|
240
228
|
wallet,
|
|
241
229
|
clendAccounts,
|
|
@@ -332,10 +320,8 @@ class Client {
|
|
|
332
320
|
* @param request Adjust leverage request parameters
|
|
333
321
|
* @returns Adjust leverage operation result
|
|
334
322
|
*/
|
|
335
|
-
async adjustLeverage(
|
|
323
|
+
async adjustLeverage(clendAccount, assetTokenMint, liabilityTokenMint, leverage, slippageBps) {
|
|
336
324
|
const req = {
|
|
337
|
-
owner: this.address(),
|
|
338
|
-
clendGroup,
|
|
339
325
|
clendAccount,
|
|
340
326
|
assetTokenMint,
|
|
341
327
|
liabilityTokenMint,
|
|
@@ -352,10 +338,8 @@ class Client {
|
|
|
352
338
|
* @param request Withdraw leverage request parameters
|
|
353
339
|
* @returns Withdraw leverage operation result
|
|
354
340
|
*/
|
|
355
|
-
async withdrawLeverage(
|
|
341
|
+
async withdrawLeverage(clendAccount, outputTokenMint, assetTokenMint, liabilityTokenMint, uiAmount, slippageBps, withdrawAll) {
|
|
356
342
|
const req = {
|
|
357
|
-
owner: this.address(),
|
|
358
|
-
clendGroup,
|
|
359
343
|
clendAccount,
|
|
360
344
|
outputTokenMint,
|
|
361
345
|
assetTokenMint,
|
|
@@ -369,16 +353,21 @@ class Client {
|
|
|
369
353
|
const txSig = await this.send(withdrawLeverageResponse.unsignedBase64Tx, withdrawLeverageResponse.userRequestId);
|
|
370
354
|
return txSig;
|
|
371
355
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
356
|
+
/**
|
|
357
|
+
* Withdraw emissions from a bank
|
|
358
|
+
* @returns Withdraw emissions operation result
|
|
359
|
+
*/
|
|
360
|
+
async withdrawEmissions() {
|
|
361
|
+
const req = {
|
|
362
|
+
owner: this.address(),
|
|
363
|
+
};
|
|
364
|
+
const body = await handleApiCall(() => this.http.post("emissions/withdraw", JSON.stringify(req)));
|
|
365
|
+
const withdrawEmissionsResponse = JSON.parse(body);
|
|
366
|
+
const txSig = await this.send(withdrawEmissionsResponse.unsignedBase64Tx, withdrawEmissionsResponse.userRequestId);
|
|
367
|
+
return txSig;
|
|
380
368
|
}
|
|
381
369
|
}
|
|
370
|
+
exports.Client = Client;
|
|
382
371
|
// Helper function to handle API calls
|
|
383
372
|
async function handleApiCall(call) {
|
|
384
373
|
try {
|
|
@@ -403,6 +392,17 @@ function getDummyProvider() {
|
|
|
403
392
|
});
|
|
404
393
|
}
|
|
405
394
|
function parseBank(bankJson) {
|
|
395
|
+
let bankEmissions = null;
|
|
396
|
+
if (bankJson.emissions) {
|
|
397
|
+
bankEmissions = {
|
|
398
|
+
emissionsMode: bankJson.emissions.emissionsMode,
|
|
399
|
+
emissionsApy: Number(bankJson.emissions.emissionsApy),
|
|
400
|
+
emissionsMint: new anchor_1.web3.PublicKey(bankJson.emissions.emissionsMint),
|
|
401
|
+
emissionsTokenPrice: Number(bankJson.emissions.emissionsTokenPrice),
|
|
402
|
+
emissionsRate: new anchor_1.BN(bankJson.emissions.emissionsRate, "hex"),
|
|
403
|
+
emissionsRemainingUi: Number(bankJson.emissions.emissionsRemainingUi),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
406
|
return {
|
|
407
407
|
mint: new anchor_1.web3.PublicKey(bankJson.mint),
|
|
408
408
|
key: new anchor_1.web3.PublicKey(bankJson.key),
|
|
@@ -416,6 +416,7 @@ function parseBank(bankJson) {
|
|
|
416
416
|
assetMaintWeight: Number(bankJson.assetMaintWeight),
|
|
417
417
|
totalAssetShares: Number(bankJson.totalAssetShares),
|
|
418
418
|
assetShareValue: Number(bankJson.assetShareValue),
|
|
419
|
+
tokenYieldApy: Number(bankJson.tokenYieldApy),
|
|
419
420
|
liabilityAmount: new anchor_1.BN(bankJson.liabilityAmount, "hex"),
|
|
420
421
|
liabilityAmountUi: Number(bankJson.liabilityAmountUi),
|
|
421
422
|
liabilityInitWeight: Number(bankJson.liabilityInitWeight),
|
|
@@ -427,5 +428,6 @@ function parseBank(bankJson) {
|
|
|
427
428
|
depositLimitUi: Number(bankJson.depositLimitUi),
|
|
428
429
|
borrowLimit: new anchor_1.BN(bankJson.borrowLimit, "hex"),
|
|
429
430
|
borrowLimitUi: Number(bankJson.borrowLimitUi),
|
|
431
|
+
emissions: bankEmissions,
|
|
430
432
|
};
|
|
431
433
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -28,8 +28,6 @@ export interface DepositLeverageResponse {
|
|
|
28
28
|
* Request to adjust the leverage of an existing position
|
|
29
29
|
*/
|
|
30
30
|
export interface AdjustLeverageRequest {
|
|
31
|
-
owner: web3.PublicKey;
|
|
32
|
-
clendGroup: web3.PublicKey;
|
|
33
31
|
clendAccount: web3.PublicKey;
|
|
34
32
|
assetTokenMint: web3.PublicKey;
|
|
35
33
|
liabilityTokenMint: web3.PublicKey;
|
|
@@ -47,8 +45,6 @@ export interface AdjustLeverageResponse {
|
|
|
47
45
|
* Request to withdraw from a leveraged position
|
|
48
46
|
*/
|
|
49
47
|
export interface WithdrawLeverageRequest {
|
|
50
|
-
owner: web3.PublicKey;
|
|
51
|
-
clendGroup: web3.PublicKey;
|
|
52
48
|
clendAccount: web3.PublicKey;
|
|
53
49
|
outputTokenMint: web3.PublicKey;
|
|
54
50
|
assetTokenMint: web3.PublicKey;
|
|
@@ -64,6 +60,19 @@ export interface WithdrawLeverageResponse {
|
|
|
64
60
|
userRequestId: string;
|
|
65
61
|
unsignedBase64Tx: string;
|
|
66
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Request to withdraw emissions from a bank
|
|
65
|
+
*/
|
|
66
|
+
export interface WithdrawEmissionsRequest {
|
|
67
|
+
owner: web3.PublicKey;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Response for withdraw emissions operation
|
|
71
|
+
*/
|
|
72
|
+
export interface WithdrawEmissionsResponse {
|
|
73
|
+
userRequestId: string;
|
|
74
|
+
unsignedBase64Tx: string;
|
|
75
|
+
}
|
|
67
76
|
export interface GetGroupsResponse {
|
|
68
77
|
groups: GroupAndBanks[];
|
|
69
78
|
}
|
|
@@ -102,6 +111,7 @@ export interface ClendAccount {
|
|
|
102
111
|
netValue: number;
|
|
103
112
|
netApy: number;
|
|
104
113
|
pnl: number;
|
|
114
|
+
totalEmissionsApy: number;
|
|
105
115
|
totalAssetValue: number;
|
|
106
116
|
totalLiabilityValue: number;
|
|
107
117
|
healthFactorNotional: number;
|
|
@@ -114,16 +124,18 @@ export interface ClendAccount {
|
|
|
114
124
|
export interface ClendAccountBalance {
|
|
115
125
|
mint: web3.PublicKey;
|
|
116
126
|
bank: web3.PublicKey;
|
|
127
|
+
tokenYieldApy: number;
|
|
117
128
|
assetBalance: BN;
|
|
118
129
|
assetBalanceUi: number;
|
|
119
130
|
assetValue: number;
|
|
120
|
-
|
|
121
|
-
assetYieldApy: number;
|
|
131
|
+
assetEmissionsApy: number;
|
|
122
132
|
liabilityBalance: BN;
|
|
123
133
|
liabilityBalanceUi: number;
|
|
124
134
|
liabilityValue: number;
|
|
125
|
-
liabilityBorrowCostBps: number;
|
|
126
135
|
liabilityBorrowCostApy: number;
|
|
136
|
+
liabilityEmissionsApy: number;
|
|
137
|
+
emissionsOutstandingAndUnclaimed: BN;
|
|
138
|
+
emissionsOutstandingAndUnclaimedUi: number;
|
|
127
139
|
price: number;
|
|
128
140
|
liquidation: ClendAccountAssetLiquidation | null;
|
|
129
141
|
}
|
|
@@ -138,6 +150,7 @@ export interface Bank {
|
|
|
138
150
|
group: web3.PublicKey;
|
|
139
151
|
key: web3.PublicKey;
|
|
140
152
|
mint: web3.PublicKey;
|
|
153
|
+
tokenYieldApy: number;
|
|
141
154
|
supplyApy: number;
|
|
142
155
|
borrowApy: number;
|
|
143
156
|
utilizationRate: number;
|
|
@@ -158,7 +171,17 @@ export interface Bank {
|
|
|
158
171
|
depositLimitUi: number;
|
|
159
172
|
borrowLimit: BN;
|
|
160
173
|
borrowLimitUi: number;
|
|
174
|
+
emissions: BankEmissions | null;
|
|
175
|
+
}
|
|
176
|
+
export interface BankEmissions {
|
|
177
|
+
emissionsMode: BankEmissionsMode;
|
|
178
|
+
emissionsApy: number;
|
|
179
|
+
emissionsMint: web3.PublicKey;
|
|
180
|
+
emissionsTokenPrice: number;
|
|
181
|
+
emissionsRate: BN;
|
|
182
|
+
emissionsRemainingUi: number;
|
|
161
183
|
}
|
|
184
|
+
export type BankEmissionsMode = "LENDING_ONLY" | "BORROW_ONLY" | "LENDING_AND_BORROWING";
|
|
162
185
|
export interface ClendAccountTxSummary {
|
|
163
186
|
txSig: string;
|
|
164
187
|
time: Date;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import { web3 } from "@coral-xyz/anchor";
|
|
2
2
|
import { ClendAccount } from "./types";
|
|
3
3
|
export declare function netValueInToken(clendAccount: ClendAccount, tokenMint: web3.PublicKey): number;
|
|
4
|
-
export declare function getProductionGroups(): web3.PublicKey[];
|
|
5
|
-
export declare function getStagingGroups(): web3.PublicKey[];
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.netValueInToken = netValueInToken;
|
|
4
|
-
exports.getProductionGroups = getProductionGroups;
|
|
5
|
-
exports.getStagingGroups = getStagingGroups;
|
|
6
|
-
const anchor_1 = require("@coral-xyz/anchor");
|
|
7
4
|
// returns the net value of the clend account in a given tokens price
|
|
8
5
|
function netValueInToken(clendAccount, tokenMint) {
|
|
9
6
|
const clendAccountTokenBalance = clendAccount.balances.find((balance) => balance.mint.equals(tokenMint));
|
|
@@ -12,9 +9,3 @@ function netValueInToken(clendAccount, tokenMint) {
|
|
|
12
9
|
}
|
|
13
10
|
return clendAccount.netValue / clendAccountTokenBalance.price;
|
|
14
11
|
}
|
|
15
|
-
function getProductionGroups() {
|
|
16
|
-
return [new anchor_1.web3.PublicKey("9bCWxAXFdWQ9GcZTSU3G636T6EyGXYMgaWR74yc7QZz8")];
|
|
17
|
-
}
|
|
18
|
-
function getStagingGroups() {
|
|
19
|
-
return [new anchor_1.web3.PublicKey("HKMDWLBK7yUmorSx9argg2rYcro6KoWf41N57FccKRP5")];
|
|
20
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carrot-protocol/boost-http-client",
|
|
3
|
-
"version": "0.2.15
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "HTTP client for Carrot Boost",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@coral-xyz/anchor": "^0.29.0",
|
|
17
|
-
"@carrot-protocol/clend-common": "0.1.8-group-refactor1-dev-
|
|
17
|
+
"@carrot-protocol/clend-common": "0.1.8-group-refactor1-dev-19efede",
|
|
18
18
|
"axios": "^1.8.3",
|
|
19
19
|
"bs58": "^6.0.0",
|
|
20
20
|
"decimal.js": "^10.5.0"
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
ClendAccountAssetLiquidation,
|
|
24
24
|
GetGroupsResponse,
|
|
25
25
|
GroupAndBanks,
|
|
26
|
+
BankEmissions,
|
|
27
|
+
BankEmissionsMode,
|
|
28
|
+
WithdrawEmissionsRequest,
|
|
29
|
+
WithdrawEmissionsResponse,
|
|
26
30
|
} from "./types";
|
|
27
31
|
import encode from "bs58";
|
|
28
32
|
|
|
@@ -102,177 +106,178 @@ export class Client {
|
|
|
102
106
|
return handleApiCall(() => this.http.get(""));
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
/**
|
|
106
|
-
* Get user details for a wallet
|
|
107
|
-
* @param user wallet public key
|
|
108
|
-
* @returns User details
|
|
109
|
-
*/
|
|
110
109
|
async getUser(
|
|
111
|
-
groups: web3.PublicKey[],
|
|
112
110
|
user: web3.PublicKey,
|
|
111
|
+
groups: web3.PublicKey[],
|
|
113
112
|
getClendAccountSummary: boolean,
|
|
114
113
|
): Promise<GetUserResponse> {
|
|
114
|
+
// Make the API call to fetch the raw user data as a string.
|
|
115
115
|
const body = await handleApiCall(() =>
|
|
116
116
|
this.http.get(
|
|
117
117
|
`/user?user=${user.toString()}&groups=${groups.map((g) => g.toString()).join(",")}&getClendAccountSummary=${getClendAccountSummary}`,
|
|
118
118
|
),
|
|
119
119
|
);
|
|
120
120
|
|
|
121
|
+
// Parse the raw string body into a JSON object.
|
|
121
122
|
const jsonRawResponse: any = JSON.parse(body);
|
|
122
|
-
console.log(JSON.stringify(jsonRawResponse, null, 2));
|
|
123
|
-
|
|
124
|
-
// parse balances
|
|
125
|
-
const walletBalances: UserBalance[] = [];
|
|
126
|
-
for (const b of jsonRawResponse.wallet.balances) {
|
|
127
|
-
walletBalances.push({
|
|
128
|
-
mint: new web3.PublicKey(b.mint),
|
|
129
|
-
balance: new BN(b.balance, "hex"),
|
|
130
|
-
balanceUi: Number(b.balanceUi),
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
123
|
|
|
134
|
-
//
|
|
124
|
+
// 1. Parse Wallet Balances
|
|
125
|
+
// This section correctly iterates through the wallet balances and creates typed objects.
|
|
126
|
+
const walletBalances: UserBalance[] = (
|
|
127
|
+
jsonRawResponse.wallet.balances || []
|
|
128
|
+
).map((b: any) => ({
|
|
129
|
+
mint: new web3.PublicKey(b.mint),
|
|
130
|
+
balance: new BN(b.balance, "hex"),
|
|
131
|
+
balanceUi: Number(b.balanceUi),
|
|
132
|
+
}));
|
|
133
|
+
|
|
135
134
|
const wallet: UserWallet = {
|
|
136
135
|
balances: walletBalances,
|
|
137
136
|
};
|
|
138
137
|
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
138
|
+
// 2. Parse Clend Accounts and their Summaries
|
|
139
|
+
// This is the main refactored section. It iterates through the clendAccounts array
|
|
140
|
+
// from the response, which contains both the account data and its summary.
|
|
141
|
+
const clendAccounts = (jsonRawResponse.clendAccounts || []).map(
|
|
142
|
+
(accountData: any) => {
|
|
143
|
+
// A. Parse the main ClendAccount object
|
|
144
|
+
const rawClendAccount = accountData.clendAccount;
|
|
145
|
+
const clendAccountBalances: ClendAccountBalance[] = (
|
|
146
|
+
rawClendAccount.balances || []
|
|
147
|
+
).map((b: any) => {
|
|
148
|
+
const liquidation: ClendAccountAssetLiquidation | null = b.liquidation
|
|
149
|
+
? {
|
|
150
|
+
price: Number(b.liquidation.price),
|
|
151
|
+
changePercentage: Number(b.liquidation.changePercentage),
|
|
152
|
+
}
|
|
153
|
+
: null;
|
|
154
|
+
|
|
155
|
+
const emissionsOutstandingAndUnclaimed = new BN(
|
|
156
|
+
b.emissionsOutstandingAndUnclaimed,
|
|
157
|
+
"hex",
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
mint: new web3.PublicKey(b.mint),
|
|
162
|
+
bank: new web3.PublicKey(b.bank),
|
|
163
|
+
tokenYieldApy: Number(b.tokenYieldApy),
|
|
164
|
+
assetBalance: new BN(b.assetBalance, "hex"),
|
|
165
|
+
assetBalanceUi: Number(b.assetBalanceUi),
|
|
166
|
+
assetValue: Number(b.assetValue),
|
|
167
|
+
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
168
|
+
liabilityBalance: new BN(b.liabilityBalance, "hex"),
|
|
169
|
+
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
170
|
+
liabilityValue: Number(b.liabilityValue),
|
|
171
|
+
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
172
|
+
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
173
|
+
emissionsOutstandingAndUnclaimed,
|
|
174
|
+
emissionsOutstandingAndUnclaimedUi: Number(
|
|
175
|
+
b.emissionsOutstandingAndUnclaimedUi,
|
|
176
|
+
),
|
|
177
|
+
price: Number(b.price),
|
|
178
|
+
liquidation,
|
|
179
|
+
};
|
|
180
|
+
});
|
|
147
181
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
182
|
+
const clendAccount: ClendAccount = {
|
|
183
|
+
key: new web3.PublicKey(rawClendAccount.key),
|
|
184
|
+
group: new web3.PublicKey(rawClendAccount.group),
|
|
185
|
+
balances: clendAccountBalances,
|
|
186
|
+
netValue: Number(rawClendAccount.netValue),
|
|
187
|
+
netApy: Number(rawClendAccount.netApy),
|
|
188
|
+
pnl: Number(rawClendAccount.pnl),
|
|
189
|
+
totalEmissionsApy: Number(rawClendAccount.totalEmissionsApy),
|
|
190
|
+
totalAssetValue: Number(rawClendAccount.totalAssetValue),
|
|
191
|
+
totalLiabilityValue: Number(rawClendAccount.totalLiabilityValue),
|
|
192
|
+
healthFactorNotional: Number(rawClendAccount.healthFactorNotional),
|
|
193
|
+
healthFactorRiskAdjusted: Number(
|
|
194
|
+
rawClendAccount.healthFactorRiskAdjusted,
|
|
195
|
+
),
|
|
196
|
+
notionalLeverage: Number(rawClendAccount.notionalLeverage),
|
|
197
|
+
riskAdjustedLeverage: Number(rawClendAccount.riskAdjustedLeverage),
|
|
198
|
+
notionalLtv: Number(rawClendAccount.notionalLtv),
|
|
199
|
+
riskAdjustedLtv: Number(rawClendAccount.riskAdjustedLtv),
|
|
157
200
|
};
|
|
158
201
|
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
202
|
+
// B. Parse the associated Summary array for the account
|
|
203
|
+
let summary: ClendAccountTxSummary[] = [];
|
|
204
|
+
if (getClendAccountSummary && accountData.summary) {
|
|
205
|
+
summary = accountData.summary.map((s: any) => {
|
|
206
|
+
let input: UserRequest | undefined = undefined;
|
|
207
|
+
if (s.input) {
|
|
208
|
+
input = {
|
|
209
|
+
apiPath: s.input.apiPath,
|
|
210
|
+
selectedTokenMint: s.input.selectedTokenMint
|
|
211
|
+
? new web3.PublicKey(s.input.selectedTokenMint)
|
|
212
|
+
: null,
|
|
213
|
+
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
214
|
+
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
215
|
+
slippageBps: s.input.slippageBps
|
|
216
|
+
? Number(s.input.slippageBps)
|
|
217
|
+
: null,
|
|
218
|
+
openPosition:
|
|
219
|
+
s.input.openPosition != null
|
|
220
|
+
? Boolean(s.input.openPosition)
|
|
221
|
+
: null,
|
|
222
|
+
closePosition:
|
|
223
|
+
s.input.closePosition != null
|
|
224
|
+
? Boolean(s.input.closePosition)
|
|
225
|
+
: null,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
180
228
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
229
|
+
const events: ClendAccountEvent[] = (s.events || []).map(
|
|
230
|
+
(event: any) => {
|
|
231
|
+
let closeBalance: boolean | null = null;
|
|
232
|
+
// Only convert to boolean if the value is not null/undefined to preserve the null state.
|
|
233
|
+
if (
|
|
234
|
+
event.closeBalance !== null &&
|
|
235
|
+
event.closeBalance !== undefined
|
|
236
|
+
) {
|
|
237
|
+
closeBalance = Boolean(event.closeBalance);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
eventIndex: event.eventIndex,
|
|
242
|
+
eventName: event.eventName,
|
|
243
|
+
bank: event.bank ? new web3.PublicKey(event.bank) : null,
|
|
244
|
+
mint: event.mint ? new web3.PublicKey(event.mint) : null,
|
|
245
|
+
amount: event.amount ? new BN(event.amount, "hex") : null,
|
|
246
|
+
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
247
|
+
value: event.value ? Number(event.value) : null,
|
|
248
|
+
price: event.price ? Number(event.price) : null,
|
|
249
|
+
closeBalance,
|
|
250
|
+
};
|
|
251
|
+
},
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
const txSummary: ClendAccountTxSummary = {
|
|
255
|
+
txSig: s.txSig,
|
|
256
|
+
time: s.time,
|
|
257
|
+
clendAccount: new web3.PublicKey(s.clendAccount),
|
|
258
|
+
clendAccountAuthority: new web3.PublicKey(
|
|
259
|
+
s.clendAccountAuthority,
|
|
260
|
+
),
|
|
261
|
+
clendGroup: new web3.PublicKey(s.clendGroup),
|
|
262
|
+
action: s.action,
|
|
263
|
+
input,
|
|
264
|
+
events,
|
|
265
|
+
};
|
|
266
|
+
return txSummary;
|
|
267
|
+
});
|
|
201
268
|
}
|
|
202
269
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// if no clend accounts, return empty array
|
|
208
|
-
const clendAccounts: {
|
|
209
|
-
clendAccount: ClendAccount;
|
|
210
|
-
summary: ClendAccountTxSummary[];
|
|
211
|
-
}[] = [];
|
|
212
|
-
for (const accountAndSumary of jsonRawResponse.clendAccounts) {
|
|
213
|
-
const clendAccountBalances: ClendAccountBalance[] = [];
|
|
214
|
-
const ca = accountAndSumary.clendAccount;
|
|
215
|
-
for (const b of ca.balances) {
|
|
216
|
-
// parse liquidation data if exists
|
|
217
|
-
const liquidation: ClendAccountAssetLiquidation | null = b.liquidation
|
|
218
|
-
? {
|
|
219
|
-
price: Number(b.liquidation.price),
|
|
220
|
-
changePercentage: Number(b.liquidation.changePercentage),
|
|
221
|
-
}
|
|
222
|
-
: null;
|
|
223
|
-
|
|
224
|
-
// create clend account balance
|
|
225
|
-
clendAccountBalances.push({
|
|
226
|
-
mint: new web3.PublicKey(b.mint),
|
|
227
|
-
bank: new web3.PublicKey(b.bank),
|
|
228
|
-
assetBalance: new BN(b.assetBalance, "hex"),
|
|
229
|
-
assetBalanceUi: Number(b.assetBalanceUi),
|
|
230
|
-
assetValue: Number(b.assetValue),
|
|
231
|
-
assetYieldBps: Number(b.assetYieldBps),
|
|
232
|
-
assetYieldApy: Number(b.assetYieldApy),
|
|
233
|
-
liabilityBalance: new BN(b.liabilityBalance, "hex"),
|
|
234
|
-
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
235
|
-
liabilityValue: Number(b.liabilityValue),
|
|
236
|
-
liabilityBorrowCostBps: Number(b.liabilityBorrowCostBps),
|
|
237
|
-
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
238
|
-
price: Number(b.price),
|
|
239
|
-
liquidation,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// create clend account
|
|
244
|
-
const clendAccountAddress = new web3.PublicKey(
|
|
245
|
-
accountAndSumary.clendAccount.key,
|
|
246
|
-
);
|
|
247
|
-
const clendAccount: ClendAccount = {
|
|
248
|
-
key: clendAccountAddress,
|
|
249
|
-
group: new web3.PublicKey(ca.group),
|
|
250
|
-
balances: clendAccountBalances,
|
|
251
|
-
netValue: Number(ca.netValue),
|
|
252
|
-
netApy: Number(ca.netApy),
|
|
253
|
-
pnl: Number(ca.pnl),
|
|
254
|
-
totalAssetValue: Number(ca.totalAssetValue),
|
|
255
|
-
totalLiabilityValue: Number(ca.totalLiabilityValue),
|
|
256
|
-
healthFactorNotional: Number(ca.healthFactorNotional),
|
|
257
|
-
healthFactorRiskAdjusted: Number(ca.healthFactorRiskAdjusted),
|
|
258
|
-
notionalLeverage: Number(ca.notionalLeverage),
|
|
259
|
-
riskAdjustedLeverage: Number(ca.riskAdjustedLeverage),
|
|
260
|
-
notionalLtv: Number(ca.notionalLtv),
|
|
261
|
-
riskAdjustedLtv: Number(ca.riskAdjustedLtv),
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// find corresponding tx summary for account
|
|
265
|
-
const summary =
|
|
266
|
-
summaryByAccount.get(clendAccountAddress.toString()) || [];
|
|
267
|
-
clendAccounts.push({ clendAccount, summary });
|
|
268
|
-
}
|
|
270
|
+
// C. Combine the parsed account and its summary
|
|
271
|
+
return { clendAccount, summary };
|
|
272
|
+
},
|
|
273
|
+
);
|
|
269
274
|
|
|
275
|
+
// 3. Return the final, correctly structured response object.
|
|
270
276
|
return {
|
|
271
277
|
wallet,
|
|
272
278
|
clendAccounts,
|
|
273
279
|
};
|
|
274
280
|
}
|
|
275
|
-
|
|
276
281
|
/**
|
|
277
282
|
* Get all groups
|
|
278
283
|
* @param includeBankData Whether to include bank data in the response, if not strictly necessary keep false
|
|
@@ -406,16 +411,13 @@ export class Client {
|
|
|
406
411
|
* @returns Adjust leverage operation result
|
|
407
412
|
*/
|
|
408
413
|
async adjustLeverage(
|
|
409
|
-
clendGroup: web3.PublicKey,
|
|
410
414
|
clendAccount: web3.PublicKey,
|
|
411
415
|
assetTokenMint: web3.PublicKey,
|
|
412
416
|
liabilityTokenMint: web3.PublicKey,
|
|
413
417
|
leverage: number,
|
|
414
418
|
slippageBps: number,
|
|
415
|
-
): Promise<
|
|
419
|
+
): Promise<string> {
|
|
416
420
|
const req: AdjustLeverageRequest = {
|
|
417
|
-
owner: this.address(),
|
|
418
|
-
clendGroup,
|
|
419
421
|
clendAccount,
|
|
420
422
|
assetTokenMint,
|
|
421
423
|
liabilityTokenMint,
|
|
@@ -442,7 +444,6 @@ export class Client {
|
|
|
442
444
|
* @returns Withdraw leverage operation result
|
|
443
445
|
*/
|
|
444
446
|
async withdrawLeverage(
|
|
445
|
-
clendGroup: web3.PublicKey,
|
|
446
447
|
clendAccount: web3.PublicKey,
|
|
447
448
|
outputTokenMint: web3.PublicKey,
|
|
448
449
|
assetTokenMint: web3.PublicKey,
|
|
@@ -450,10 +451,8 @@ export class Client {
|
|
|
450
451
|
uiAmount: number,
|
|
451
452
|
slippageBps: number,
|
|
452
453
|
withdrawAll: boolean,
|
|
453
|
-
): Promise<
|
|
454
|
+
): Promise<string> {
|
|
454
455
|
const req: WithdrawLeverageRequest = {
|
|
455
|
-
owner: this.address(),
|
|
456
|
-
clendGroup,
|
|
457
456
|
clendAccount,
|
|
458
457
|
outputTokenMint,
|
|
459
458
|
assetTokenMint,
|
|
@@ -475,6 +474,30 @@ export class Client {
|
|
|
475
474
|
|
|
476
475
|
return txSig;
|
|
477
476
|
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Withdraw emissions from a bank
|
|
480
|
+
* @returns Withdraw emissions operation result
|
|
481
|
+
*/
|
|
482
|
+
async withdrawEmissions(): Promise<string> {
|
|
483
|
+
const req: WithdrawEmissionsRequest = {
|
|
484
|
+
owner: this.address(),
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
const body = await handleApiCall(() =>
|
|
488
|
+
this.http.post("emissions/withdraw", JSON.stringify(req)),
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
const withdrawEmissionsResponse: WithdrawEmissionsResponse =
|
|
492
|
+
JSON.parse(body);
|
|
493
|
+
|
|
494
|
+
const txSig = await this.send(
|
|
495
|
+
withdrawEmissionsResponse.unsignedBase64Tx,
|
|
496
|
+
withdrawEmissionsResponse.userRequestId,
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
return txSig;
|
|
500
|
+
}
|
|
478
501
|
}
|
|
479
502
|
|
|
480
503
|
type ApiErrorPayload = {
|
|
@@ -484,15 +507,6 @@ type ApiErrorPayload = {
|
|
|
484
507
|
timestamp: string;
|
|
485
508
|
};
|
|
486
509
|
|
|
487
|
-
function handleStatusCode(statusCode: number): void {
|
|
488
|
-
switch (statusCode) {
|
|
489
|
-
case 200:
|
|
490
|
-
break;
|
|
491
|
-
default:
|
|
492
|
-
throw new Error(`unexpected status code: ${statusCode}`);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
|
|
496
510
|
// Helper function to handle API calls
|
|
497
511
|
async function handleApiCall<T>(
|
|
498
512
|
call: () => Promise<AxiosResponse<T>>,
|
|
@@ -526,6 +540,18 @@ function getDummyProvider(): AnchorProvider {
|
|
|
526
540
|
}
|
|
527
541
|
|
|
528
542
|
function parseBank(bankJson: any): Bank {
|
|
543
|
+
let bankEmissions: BankEmissions | null = null;
|
|
544
|
+
if (bankJson.emissions) {
|
|
545
|
+
bankEmissions = {
|
|
546
|
+
emissionsMode: bankJson.emissions.emissionsMode as BankEmissionsMode,
|
|
547
|
+
emissionsApy: Number(bankJson.emissions.emissionsApy),
|
|
548
|
+
emissionsMint: new web3.PublicKey(bankJson.emissions.emissionsMint),
|
|
549
|
+
emissionsTokenPrice: Number(bankJson.emissions.emissionsTokenPrice),
|
|
550
|
+
emissionsRate: new BN(bankJson.emissions.emissionsRate, "hex"),
|
|
551
|
+
emissionsRemainingUi: Number(bankJson.emissions.emissionsRemainingUi),
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
529
555
|
return {
|
|
530
556
|
mint: new web3.PublicKey(bankJson.mint),
|
|
531
557
|
key: new web3.PublicKey(bankJson.key),
|
|
@@ -539,6 +565,7 @@ function parseBank(bankJson: any): Bank {
|
|
|
539
565
|
assetMaintWeight: Number(bankJson.assetMaintWeight),
|
|
540
566
|
totalAssetShares: Number(bankJson.totalAssetShares),
|
|
541
567
|
assetShareValue: Number(bankJson.assetShareValue),
|
|
568
|
+
tokenYieldApy: Number(bankJson.tokenYieldApy),
|
|
542
569
|
liabilityAmount: new BN(bankJson.liabilityAmount, "hex"),
|
|
543
570
|
liabilityAmountUi: Number(bankJson.liabilityAmountUi),
|
|
544
571
|
liabilityInitWeight: Number(bankJson.liabilityInitWeight),
|
|
@@ -550,5 +577,6 @@ function parseBank(bankJson: any): Bank {
|
|
|
550
577
|
depositLimitUi: Number(bankJson.depositLimitUi),
|
|
551
578
|
borrowLimit: new BN(bankJson.borrowLimit, "hex"),
|
|
552
579
|
borrowLimitUi: Number(bankJson.borrowLimitUi),
|
|
580
|
+
emissions: bankEmissions,
|
|
553
581
|
};
|
|
554
582
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BN, web3 } from "@coral-xyz/anchor";
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Send a tx
|
|
4
4
|
export interface SendRequest {
|
|
5
5
|
userRequestId: string;
|
|
6
6
|
txns: string[];
|
|
@@ -33,8 +33,6 @@ export interface DepositLeverageResponse {
|
|
|
33
33
|
* Request to adjust the leverage of an existing position
|
|
34
34
|
*/
|
|
35
35
|
export interface AdjustLeverageRequest {
|
|
36
|
-
owner: web3.PublicKey;
|
|
37
|
-
clendGroup: web3.PublicKey;
|
|
38
36
|
clendAccount: web3.PublicKey;
|
|
39
37
|
assetTokenMint: web3.PublicKey;
|
|
40
38
|
liabilityTokenMint: web3.PublicKey;
|
|
@@ -54,8 +52,6 @@ export interface AdjustLeverageResponse {
|
|
|
54
52
|
* Request to withdraw from a leveraged position
|
|
55
53
|
*/
|
|
56
54
|
export interface WithdrawLeverageRequest {
|
|
57
|
-
owner: web3.PublicKey;
|
|
58
|
-
clendGroup: web3.PublicKey;
|
|
59
55
|
clendAccount: web3.PublicKey;
|
|
60
56
|
outputTokenMint: web3.PublicKey;
|
|
61
57
|
assetTokenMint: web3.PublicKey;
|
|
@@ -73,6 +69,21 @@ export interface WithdrawLeverageResponse {
|
|
|
73
69
|
unsignedBase64Tx: string;
|
|
74
70
|
}
|
|
75
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Request to withdraw emissions from a bank
|
|
74
|
+
*/
|
|
75
|
+
export interface WithdrawEmissionsRequest {
|
|
76
|
+
owner: web3.PublicKey;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Response for withdraw emissions operation
|
|
81
|
+
*/
|
|
82
|
+
export interface WithdrawEmissionsResponse {
|
|
83
|
+
userRequestId: string;
|
|
84
|
+
unsignedBase64Tx: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
76
87
|
export interface GetGroupsResponse {
|
|
77
88
|
groups: GroupAndBanks[];
|
|
78
89
|
}
|
|
@@ -118,6 +129,7 @@ export interface ClendAccount {
|
|
|
118
129
|
netValue: number;
|
|
119
130
|
netApy: number;
|
|
120
131
|
pnl: number;
|
|
132
|
+
totalEmissionsApy: number;
|
|
121
133
|
totalAssetValue: number;
|
|
122
134
|
totalLiabilityValue: number;
|
|
123
135
|
healthFactorNotional: number;
|
|
@@ -131,16 +143,18 @@ export interface ClendAccount {
|
|
|
131
143
|
export interface ClendAccountBalance {
|
|
132
144
|
mint: web3.PublicKey;
|
|
133
145
|
bank: web3.PublicKey;
|
|
146
|
+
tokenYieldApy: number;
|
|
134
147
|
assetBalance: BN;
|
|
135
148
|
assetBalanceUi: number;
|
|
136
149
|
assetValue: number;
|
|
137
|
-
|
|
138
|
-
assetYieldApy: number;
|
|
150
|
+
assetEmissionsApy: number;
|
|
139
151
|
liabilityBalance: BN;
|
|
140
152
|
liabilityBalanceUi: number;
|
|
141
153
|
liabilityValue: number;
|
|
142
|
-
liabilityBorrowCostBps: number;
|
|
143
154
|
liabilityBorrowCostApy: number;
|
|
155
|
+
liabilityEmissionsApy: number;
|
|
156
|
+
emissionsOutstandingAndUnclaimed: BN;
|
|
157
|
+
emissionsOutstandingAndUnclaimedUi: number;
|
|
144
158
|
price: number;
|
|
145
159
|
liquidation: ClendAccountAssetLiquidation | null;
|
|
146
160
|
}
|
|
@@ -158,6 +172,7 @@ export interface Bank {
|
|
|
158
172
|
group: web3.PublicKey;
|
|
159
173
|
key: web3.PublicKey;
|
|
160
174
|
mint: web3.PublicKey;
|
|
175
|
+
tokenYieldApy: number;
|
|
161
176
|
supplyApy: number;
|
|
162
177
|
borrowApy: number;
|
|
163
178
|
utilizationRate: number;
|
|
@@ -178,8 +193,23 @@ export interface Bank {
|
|
|
178
193
|
depositLimitUi: number;
|
|
179
194
|
borrowLimit: BN;
|
|
180
195
|
borrowLimitUi: number;
|
|
196
|
+
emissions: BankEmissions | null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface BankEmissions {
|
|
200
|
+
emissionsMode: BankEmissionsMode;
|
|
201
|
+
emissionsApy: number;
|
|
202
|
+
emissionsMint: web3.PublicKey;
|
|
203
|
+
emissionsTokenPrice: number;
|
|
204
|
+
emissionsRate: BN;
|
|
205
|
+
emissionsRemainingUi: number;
|
|
181
206
|
}
|
|
182
207
|
|
|
208
|
+
export type BankEmissionsMode =
|
|
209
|
+
| "LENDING_ONLY"
|
|
210
|
+
| "BORROW_ONLY"
|
|
211
|
+
| "LENDING_AND_BORROWING";
|
|
212
|
+
|
|
183
213
|
export interface ClendAccountTxSummary {
|
|
184
214
|
txSig: string;
|
|
185
215
|
time: Date;
|
package/src/utils.ts
CHANGED
|
@@ -15,11 +15,3 @@ export function netValueInToken(
|
|
|
15
15
|
|
|
16
16
|
return clendAccount.netValue / clendAccountTokenBalance.price;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
export function getProductionGroups(): web3.PublicKey[] {
|
|
20
|
-
return [new web3.PublicKey("9bCWxAXFdWQ9GcZTSU3G636T6EyGXYMgaWR74yc7QZz8")];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function getStagingGroups(): web3.PublicKey[] {
|
|
24
|
-
return [new web3.PublicKey("HKMDWLBK7yUmorSx9argg2rYcro6KoWf41N57FccKRP5")];
|
|
25
|
-
}
|