@carrot-protocol/boost-http-client 0.3.1-feat-get-ohlc-endpoint-dev-43df047 → 0.3.1
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 +14 -8
- package/dist/index.js +150 -118
- package/dist/types.d.ts +35 -13
- package/package.json +1 -1
- package/src/index.ts +218 -147
- package/src/types.ts +41 -16
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnchorProvider, web3 } from "@coral-xyz/anchor";
|
|
2
|
-
import { GetBankResponse, GetUserResponse, GetGroupResponse, GetGroupsResponse,
|
|
2
|
+
import { GetBankResponse, GetUserResponse, GetGroupResponse, GetGroupsResponse, GetAccountResponse, GetAccountRequest } from "./types";
|
|
3
3
|
export * from "./types";
|
|
4
4
|
export * from "./utils";
|
|
5
5
|
export * as Common from "@carrot-protocol/clend-common";
|
|
@@ -10,11 +10,12 @@ export declare class Client {
|
|
|
10
10
|
private readonly baseUrl;
|
|
11
11
|
private readonly http;
|
|
12
12
|
private readonly provider;
|
|
13
|
+
private readonly dryRun;
|
|
13
14
|
/**
|
|
14
15
|
* Create a new Carrot Boost API client
|
|
15
16
|
* @param baseUrl Base URL for the API
|
|
16
17
|
*/
|
|
17
|
-
constructor(baseUrl: string, provider?: AnchorProvider);
|
|
18
|
+
constructor(baseUrl: string, provider?: AnchorProvider, dryRun?: boolean);
|
|
18
19
|
address(): web3.PublicKey;
|
|
19
20
|
private send;
|
|
20
21
|
/**
|
|
@@ -22,6 +23,15 @@ export declare class Client {
|
|
|
22
23
|
* @returns Index details
|
|
23
24
|
*/
|
|
24
25
|
index(): Promise<any>;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch and parse a single clend account by pubkey
|
|
28
|
+
*/
|
|
29
|
+
getAccount(account: GetAccountRequest["account"], getClendAccountSummary: GetAccountRequest["getClendAccountSummary"]): Promise<GetAccountResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Helper to parse a clend account summary array from API response
|
|
32
|
+
*/
|
|
33
|
+
private parseClendAccountSummary;
|
|
34
|
+
private parseClendAccountWithSummary;
|
|
25
35
|
getUser(user: web3.PublicKey, groups: web3.PublicKey[], getClendAccountSummary: boolean): Promise<GetUserResponse>;
|
|
26
36
|
/**
|
|
27
37
|
* Get all groups
|
|
@@ -41,12 +51,8 @@ export declare class Client {
|
|
|
41
51
|
* @returns Bank details
|
|
42
52
|
*/
|
|
43
53
|
getBank(bankAddress: web3.PublicKey): Promise<GetBankResponse>;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* @param vaultAddress vault public key
|
|
47
|
-
* @returns OHLC graph data
|
|
48
|
-
*/
|
|
49
|
-
getVaultOHLC(vaultAddress: GetVaultOHLCRequest["vault"]): Promise<GetVaultOHLCResponse>;
|
|
54
|
+
deposit(clendGroup: web3.PublicKey, clendAccount: web3.PublicKey | null, inputTokenMint: web3.PublicKey, uiAmount: number): Promise<string>;
|
|
55
|
+
withdraw(clendAccount: web3.PublicKey, outputTokenMint: web3.PublicKey, uiAmount: number, withdrawAll: boolean): Promise<string>;
|
|
50
56
|
/**
|
|
51
57
|
* Deposit collateral and create a leveraged position
|
|
52
58
|
* @param request Deposit leverage request parameters
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ class Client {
|
|
|
56
56
|
* Create a new Carrot Boost API client
|
|
57
57
|
* @param baseUrl Base URL for the API
|
|
58
58
|
*/
|
|
59
|
-
constructor(baseUrl, provider) {
|
|
59
|
+
constructor(baseUrl, provider, dryRun) {
|
|
60
60
|
this.baseUrl = new URL(baseUrl).toString();
|
|
61
61
|
this.http = axios_1.default.create({
|
|
62
62
|
baseURL: this.baseUrl,
|
|
@@ -67,6 +67,7 @@ class Client {
|
|
|
67
67
|
if (!provider) {
|
|
68
68
|
provider = getDummyProvider();
|
|
69
69
|
}
|
|
70
|
+
this.dryRun = dryRun ?? false;
|
|
70
71
|
this.provider = provider;
|
|
71
72
|
}
|
|
72
73
|
address() {
|
|
@@ -74,6 +75,10 @@ class Client {
|
|
|
74
75
|
}
|
|
75
76
|
// sign and send tx to api for sending to network
|
|
76
77
|
async send(unsignedBase64Tx, userRequestId) {
|
|
78
|
+
if (this.dryRun) {
|
|
79
|
+
// for debugging purposes only
|
|
80
|
+
console.log("unsigedBase64Tx", unsignedBase64Tx);
|
|
81
|
+
}
|
|
77
82
|
// deserialize into tx obj
|
|
78
83
|
const txBytes = Buffer.from(unsignedBase64Tx, "base64");
|
|
79
84
|
const tx = anchor_1.web3.VersionedTransaction.deserialize(new Uint8Array(txBytes));
|
|
@@ -88,7 +93,12 @@ class Client {
|
|
|
88
93
|
txns: [encodedAndSignedTx],
|
|
89
94
|
};
|
|
90
95
|
// send to api
|
|
91
|
-
|
|
96
|
+
if (!this.dryRun) {
|
|
97
|
+
await handleApiCall(() => this.http.post(`send`, sendRequest));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.warn("dry run enabled, did not send tx");
|
|
101
|
+
}
|
|
92
102
|
// return txsig
|
|
93
103
|
return bs58_1.default.encode(txSig);
|
|
94
104
|
}
|
|
@@ -99,6 +109,120 @@ class Client {
|
|
|
99
109
|
async index() {
|
|
100
110
|
return handleApiCall(() => this.http.get(""));
|
|
101
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Fetch and parse a single clend account by pubkey
|
|
114
|
+
*/
|
|
115
|
+
async getAccount(account, getClendAccountSummary) {
|
|
116
|
+
const body = await handleApiCall(() => this.http.get(`/account?account=${account.toString()}&getClendAccountSummary=${getClendAccountSummary}`));
|
|
117
|
+
const jsonRawResponse = JSON.parse(body);
|
|
118
|
+
return this.parseClendAccountWithSummary(jsonRawResponse, getClendAccountSummary);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Helper to parse a clend account summary array from API response
|
|
122
|
+
*/
|
|
123
|
+
parseClendAccountSummary(summaryArr) {
|
|
124
|
+
return summaryArr.map((s) => {
|
|
125
|
+
let input = undefined;
|
|
126
|
+
if (s.input) {
|
|
127
|
+
input = {
|
|
128
|
+
apiPath: s.input.apiPath,
|
|
129
|
+
selectedTokenMint: s.input.selectedTokenMint
|
|
130
|
+
? new anchor_1.web3.PublicKey(s.input.selectedTokenMint)
|
|
131
|
+
: null,
|
|
132
|
+
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
133
|
+
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
134
|
+
slippageBps: s.input.slippageBps ? Number(s.input.slippageBps) : null,
|
|
135
|
+
openPosition: s.input.openPosition != null ? Boolean(s.input.openPosition) : null,
|
|
136
|
+
closePosition: s.input.closePosition != null
|
|
137
|
+
? Boolean(s.input.closePosition)
|
|
138
|
+
: null,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const events = (s.events || []).map((event) => {
|
|
142
|
+
let closeBalance = null;
|
|
143
|
+
if (event.closeBalance !== null && event.closeBalance !== undefined) {
|
|
144
|
+
closeBalance = Boolean(event.closeBalance);
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
eventIndex: event.eventIndex,
|
|
148
|
+
eventName: event.eventName,
|
|
149
|
+
bank: event.bank ? new anchor_1.web3.PublicKey(event.bank) : null,
|
|
150
|
+
mint: event.mint ? new anchor_1.web3.PublicKey(event.mint) : null,
|
|
151
|
+
amount: event.amount ? new anchor_1.BN(event.amount, "hex") : null,
|
|
152
|
+
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
153
|
+
value: event.value ? Number(event.value) : null,
|
|
154
|
+
price: event.price ? Number(event.price) : null,
|
|
155
|
+
closeBalance,
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
const txSummary = {
|
|
159
|
+
txSig: s.txSig,
|
|
160
|
+
time: s.time,
|
|
161
|
+
clendAccount: new anchor_1.web3.PublicKey(s.clendAccount),
|
|
162
|
+
clendAccountAuthority: new anchor_1.web3.PublicKey(s.clendAccountAuthority),
|
|
163
|
+
clendGroup: new anchor_1.web3.PublicKey(s.clendGroup),
|
|
164
|
+
action: s.action,
|
|
165
|
+
input,
|
|
166
|
+
events,
|
|
167
|
+
};
|
|
168
|
+
return txSummary;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
parseClendAccountWithSummary(accountData, getClendAccountSummary) {
|
|
172
|
+
// A. Parse the main ClendAccount object
|
|
173
|
+
const rawClendAccount = accountData.clendAccount;
|
|
174
|
+
const clendAccountBalances = (rawClendAccount.balances || []).map((b) => {
|
|
175
|
+
const liquidation = b.liquidation
|
|
176
|
+
? {
|
|
177
|
+
price: Number(b.liquidation.price),
|
|
178
|
+
changePercentage: Number(b.liquidation.changePercentage),
|
|
179
|
+
}
|
|
180
|
+
: null;
|
|
181
|
+
const emissionsOutstandingAndUnclaimed = new anchor_1.BN(b.emissionsOutstandingAndUnclaimed, "hex");
|
|
182
|
+
return {
|
|
183
|
+
mint: new anchor_1.web3.PublicKey(b.mint),
|
|
184
|
+
bank: new anchor_1.web3.PublicKey(b.bank),
|
|
185
|
+
tokenYieldApy: Number(b.tokenYieldApy),
|
|
186
|
+
assetBalance: new anchor_1.BN(b.assetBalance, "hex"),
|
|
187
|
+
assetBalanceUi: Number(b.assetBalanceUi),
|
|
188
|
+
assetValue: Number(b.assetValue),
|
|
189
|
+
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
190
|
+
liabilityBalance: new anchor_1.BN(b.liabilityBalance, "hex"),
|
|
191
|
+
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
192
|
+
liabilityValue: Number(b.liabilityValue),
|
|
193
|
+
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
194
|
+
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
195
|
+
emissionsOutstandingAndUnclaimed,
|
|
196
|
+
emissionsOutstandingAndUnclaimedUi: Number(b.emissionsOutstandingAndUnclaimedUi),
|
|
197
|
+
price: Number(b.price),
|
|
198
|
+
liquidation,
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
const clendAccount = {
|
|
202
|
+
key: new anchor_1.web3.PublicKey(rawClendAccount.key),
|
|
203
|
+
group: new anchor_1.web3.PublicKey(rawClendAccount.group),
|
|
204
|
+
balances: clendAccountBalances,
|
|
205
|
+
netValue: Number(rawClendAccount.netValue),
|
|
206
|
+
netApy: Number(rawClendAccount.netApy),
|
|
207
|
+
pnl: Number(rawClendAccount.pnl),
|
|
208
|
+
totalEmissionsApy: Number(rawClendAccount.totalEmissionsApy),
|
|
209
|
+
totalAssetValue: Number(rawClendAccount.totalAssetValue),
|
|
210
|
+
totalLiabilityValue: Number(rawClendAccount.totalLiabilityValue),
|
|
211
|
+
healthFactorNotional: Number(rawClendAccount.healthFactorNotional),
|
|
212
|
+
healthFactorRiskAdjusted: Number(rawClendAccount.healthFactorRiskAdjusted),
|
|
213
|
+
notionalLeverage: Number(rawClendAccount.notionalLeverage),
|
|
214
|
+
riskAdjustedLeverage: Number(rawClendAccount.riskAdjustedLeverage),
|
|
215
|
+
notionalLtv: Number(rawClendAccount.notionalLtv),
|
|
216
|
+
riskAdjustedLtv: Number(rawClendAccount.riskAdjustedLtv),
|
|
217
|
+
};
|
|
218
|
+
// B. Parse the associated Summary array for the account
|
|
219
|
+
let summary = [];
|
|
220
|
+
if (getClendAccountSummary && accountData.summary) {
|
|
221
|
+
summary = this.parseClendAccountSummary(accountData.summary);
|
|
222
|
+
}
|
|
223
|
+
// C. Combine the parsed account and its summary
|
|
224
|
+
return { clendAccount, summary };
|
|
225
|
+
}
|
|
102
226
|
async getUser(user, groups, getClendAccountSummary) {
|
|
103
227
|
// Make the API call to fetch the raw user data as a string.
|
|
104
228
|
const body = await handleApiCall(() => this.http.get(`/user?user=${user.toString()}&groups=${groups.map((g) => g.toString()).join(",")}&getClendAccountSummary=${getClendAccountSummary}`));
|
|
@@ -117,112 +241,7 @@ class Client {
|
|
|
117
241
|
// 2. Parse Clend Accounts and their Summaries
|
|
118
242
|
// This is the main refactored section. It iterates through the clendAccounts array
|
|
119
243
|
// 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) => {
|
|
124
|
-
const liquidation = b.liquidation
|
|
125
|
-
? {
|
|
126
|
-
price: Number(b.liquidation.price),
|
|
127
|
-
changePercentage: Number(b.liquidation.changePercentage),
|
|
128
|
-
}
|
|
129
|
-
: null;
|
|
130
|
-
const emissionsOutstandingAndUnclaimed = new anchor_1.BN(b.emissionsOutstandingAndUnclaimed, "hex");
|
|
131
|
-
return {
|
|
132
|
-
mint: new anchor_1.web3.PublicKey(b.mint),
|
|
133
|
-
bank: new anchor_1.web3.PublicKey(b.bank),
|
|
134
|
-
tokenYieldApy: Number(b.tokenYieldApy),
|
|
135
|
-
assetBalance: new anchor_1.BN(b.assetBalance, "hex"),
|
|
136
|
-
assetBalanceUi: Number(b.assetBalanceUi),
|
|
137
|
-
assetValue: Number(b.assetValue),
|
|
138
|
-
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
139
|
-
liabilityBalance: new anchor_1.BN(b.liabilityBalance, "hex"),
|
|
140
|
-
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
141
|
-
liabilityValue: Number(b.liabilityValue),
|
|
142
|
-
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
143
|
-
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
144
|
-
emissionsOutstandingAndUnclaimed,
|
|
145
|
-
emissionsOutstandingAndUnclaimedUi: Number(b.emissionsOutstandingAndUnclaimedUi),
|
|
146
|
-
price: Number(b.price),
|
|
147
|
-
liquidation,
|
|
148
|
-
};
|
|
149
|
-
});
|
|
150
|
-
const clendAccount = {
|
|
151
|
-
key: new anchor_1.web3.PublicKey(rawClendAccount.key),
|
|
152
|
-
group: new anchor_1.web3.PublicKey(rawClendAccount.group),
|
|
153
|
-
balances: clendAccountBalances,
|
|
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),
|
|
166
|
-
};
|
|
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
|
-
});
|
|
244
|
+
const clendAccounts = (jsonRawResponse.clendAccounts || []).map((accountData) => this.parseClendAccountWithSummary(accountData, getClendAccountSummary));
|
|
226
245
|
// 3. Return the final, correctly structured response object.
|
|
227
246
|
return {
|
|
228
247
|
wallet,
|
|
@@ -289,17 +308,30 @@ class Client {
|
|
|
289
308
|
};
|
|
290
309
|
return response;
|
|
291
310
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const response = {
|
|
300
|
-
data: JSON.parse(body),
|
|
311
|
+
async deposit(clendGroup, clendAccount, inputTokenMint, uiAmount) {
|
|
312
|
+
const req = {
|
|
313
|
+
owner: this.address(),
|
|
314
|
+
clendGroup,
|
|
315
|
+
clendAccount,
|
|
316
|
+
inputTokenMint,
|
|
317
|
+
depositAmountUi: uiAmount,
|
|
301
318
|
};
|
|
302
|
-
|
|
319
|
+
const body = await handleApiCall(() => this.http.post("deposit", JSON.stringify(req)));
|
|
320
|
+
const depositResponse = JSON.parse(body);
|
|
321
|
+
const txSig = await this.send(depositResponse.unsignedBase64Tx, depositResponse.userRequestId);
|
|
322
|
+
return txSig;
|
|
323
|
+
}
|
|
324
|
+
async withdraw(clendAccount, outputTokenMint, uiAmount, withdrawAll) {
|
|
325
|
+
const req = {
|
|
326
|
+
clendAccount,
|
|
327
|
+
outputTokenMint,
|
|
328
|
+
withdrawAmountUi: uiAmount,
|
|
329
|
+
withdrawAll,
|
|
330
|
+
};
|
|
331
|
+
const body = await handleApiCall(() => this.http.post("withdraw", JSON.stringify(req)));
|
|
332
|
+
const withdrawResponse = JSON.parse(body);
|
|
333
|
+
const txSig = await this.send(withdrawResponse.unsignedBase64Tx, withdrawResponse.userRequestId);
|
|
334
|
+
return txSig;
|
|
303
335
|
}
|
|
304
336
|
/**
|
|
305
337
|
* Deposit collateral and create a leveraged position
|
package/dist/types.d.ts
CHANGED
|
@@ -3,6 +3,33 @@ export interface SendRequest {
|
|
|
3
3
|
userRequestId: string;
|
|
4
4
|
txns: string[];
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Request to deposit collateral
|
|
8
|
+
*/
|
|
9
|
+
export interface DepositRequest {
|
|
10
|
+
owner: web3.PublicKey;
|
|
11
|
+
clendGroup: web3.PublicKey;
|
|
12
|
+
clendAccount: web3.PublicKey | null;
|
|
13
|
+
inputTokenMint: web3.PublicKey;
|
|
14
|
+
depositAmountUi: number;
|
|
15
|
+
}
|
|
16
|
+
export interface DepositResponse {
|
|
17
|
+
userRequestId: string;
|
|
18
|
+
unsignedBase64Tx: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Request to withdraw collateral
|
|
22
|
+
*/
|
|
23
|
+
export interface WithdrawRequest {
|
|
24
|
+
clendAccount: web3.PublicKey;
|
|
25
|
+
outputTokenMint: web3.PublicKey;
|
|
26
|
+
withdrawAmountUi: number;
|
|
27
|
+
withdrawAll: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface WithdrawResponse {
|
|
30
|
+
userRequestId: string;
|
|
31
|
+
unsignedBase64Tx: string;
|
|
32
|
+
}
|
|
6
33
|
/**
|
|
7
34
|
* Request to deposit collateral and create a leveraged position
|
|
8
35
|
*/
|
|
@@ -84,6 +111,14 @@ export interface GroupAndBanks {
|
|
|
84
111
|
groupName: string;
|
|
85
112
|
banks: Bank[];
|
|
86
113
|
}
|
|
114
|
+
export interface GetAccountRequest {
|
|
115
|
+
account: web3.PublicKey;
|
|
116
|
+
getClendAccountSummary: boolean;
|
|
117
|
+
}
|
|
118
|
+
export interface GetAccountResponse {
|
|
119
|
+
clendAccount: ClendAccount;
|
|
120
|
+
summary: ClendAccountTxSummary[];
|
|
121
|
+
}
|
|
87
122
|
export interface GetUserRequest {
|
|
88
123
|
groups: web3.PublicKey[];
|
|
89
124
|
user: web3.PublicKey;
|
|
@@ -96,19 +131,6 @@ export interface GetUserResponse {
|
|
|
96
131
|
summary: ClendAccountTxSummary[];
|
|
97
132
|
}[];
|
|
98
133
|
}
|
|
99
|
-
export interface GetVaultOHLCRequest {
|
|
100
|
-
vault: web3.PublicKey;
|
|
101
|
-
}
|
|
102
|
-
export interface VaultOHLCDataPoint {
|
|
103
|
-
time: number;
|
|
104
|
-
open: number;
|
|
105
|
-
high: number;
|
|
106
|
-
low: number;
|
|
107
|
-
close: number;
|
|
108
|
-
}
|
|
109
|
-
export interface GetVaultOHLCResponse {
|
|
110
|
-
data: VaultOHLCDataPoint[];
|
|
111
|
-
}
|
|
112
134
|
export interface UserWallet {
|
|
113
135
|
balances: UserBalance[];
|
|
114
136
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -27,8 +27,12 @@ import {
|
|
|
27
27
|
BankEmissionsMode,
|
|
28
28
|
WithdrawEmissionsRequest,
|
|
29
29
|
WithdrawEmissionsResponse,
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
DepositRequest,
|
|
31
|
+
DepositResponse,
|
|
32
|
+
WithdrawRequest,
|
|
33
|
+
WithdrawResponse,
|
|
34
|
+
GetAccountResponse,
|
|
35
|
+
GetAccountRequest,
|
|
32
36
|
} from "./types";
|
|
33
37
|
import encode from "bs58";
|
|
34
38
|
|
|
@@ -46,12 +50,13 @@ export class Client {
|
|
|
46
50
|
private readonly baseUrl: string;
|
|
47
51
|
private readonly http: AxiosInstance;
|
|
48
52
|
private readonly provider: AnchorProvider;
|
|
53
|
+
private readonly dryRun: boolean;
|
|
49
54
|
|
|
50
55
|
/**
|
|
51
56
|
* Create a new Carrot Boost API client
|
|
52
57
|
* @param baseUrl Base URL for the API
|
|
53
58
|
*/
|
|
54
|
-
constructor(baseUrl: string, provider?: AnchorProvider) {
|
|
59
|
+
constructor(baseUrl: string, provider?: AnchorProvider, dryRun?: boolean) {
|
|
55
60
|
this.baseUrl = new URL(baseUrl).toString();
|
|
56
61
|
this.http = axios.create({
|
|
57
62
|
baseURL: this.baseUrl,
|
|
@@ -62,6 +67,7 @@ export class Client {
|
|
|
62
67
|
if (!provider) {
|
|
63
68
|
provider = getDummyProvider();
|
|
64
69
|
}
|
|
70
|
+
this.dryRun = dryRun ?? false;
|
|
65
71
|
this.provider = provider;
|
|
66
72
|
}
|
|
67
73
|
|
|
@@ -74,6 +80,11 @@ export class Client {
|
|
|
74
80
|
unsignedBase64Tx: string,
|
|
75
81
|
userRequestId: string,
|
|
76
82
|
): Promise<string> {
|
|
83
|
+
if (this.dryRun) {
|
|
84
|
+
// for debugging purposes only
|
|
85
|
+
console.log("unsigedBase64Tx", unsignedBase64Tx);
|
|
86
|
+
}
|
|
87
|
+
|
|
77
88
|
// deserialize into tx obj
|
|
78
89
|
const txBytes = Buffer.from(unsignedBase64Tx, "base64");
|
|
79
90
|
const tx = web3.VersionedTransaction.deserialize(new Uint8Array(txBytes));
|
|
@@ -94,7 +105,11 @@ export class Client {
|
|
|
94
105
|
};
|
|
95
106
|
|
|
96
107
|
// send to api
|
|
97
|
-
|
|
108
|
+
if (!this.dryRun) {
|
|
109
|
+
await handleApiCall(() => this.http.post(`send`, sendRequest));
|
|
110
|
+
} else {
|
|
111
|
+
console.warn("dry run enabled, did not send tx");
|
|
112
|
+
}
|
|
98
113
|
|
|
99
114
|
// return txsig
|
|
100
115
|
return encode.encode(txSig);
|
|
@@ -108,6 +123,155 @@ export class Client {
|
|
|
108
123
|
return handleApiCall(() => this.http.get(""));
|
|
109
124
|
}
|
|
110
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Fetch and parse a single clend account by pubkey
|
|
128
|
+
*/
|
|
129
|
+
async getAccount(
|
|
130
|
+
account: GetAccountRequest["account"],
|
|
131
|
+
getClendAccountSummary: GetAccountRequest["getClendAccountSummary"],
|
|
132
|
+
): Promise<GetAccountResponse> {
|
|
133
|
+
const body = await handleApiCall(() =>
|
|
134
|
+
this.http.get(
|
|
135
|
+
`/account?account=${account.toString()}&getClendAccountSummary=${getClendAccountSummary}`,
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
const jsonRawResponse: any = JSON.parse(body);
|
|
139
|
+
return this.parseClendAccountWithSummary(
|
|
140
|
+
jsonRawResponse,
|
|
141
|
+
getClendAccountSummary,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Helper to parse a clend account summary array from API response
|
|
147
|
+
*/
|
|
148
|
+
private parseClendAccountSummary(summaryArr: any[]): ClendAccountTxSummary[] {
|
|
149
|
+
return summaryArr.map((s: any) => {
|
|
150
|
+
let input: UserRequest | undefined = undefined;
|
|
151
|
+
if (s.input) {
|
|
152
|
+
input = {
|
|
153
|
+
apiPath: s.input.apiPath,
|
|
154
|
+
selectedTokenMint: s.input.selectedTokenMint
|
|
155
|
+
? new web3.PublicKey(s.input.selectedTokenMint)
|
|
156
|
+
: null,
|
|
157
|
+
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
158
|
+
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
159
|
+
slippageBps: s.input.slippageBps ? Number(s.input.slippageBps) : null,
|
|
160
|
+
openPosition:
|
|
161
|
+
s.input.openPosition != null ? Boolean(s.input.openPosition) : null,
|
|
162
|
+
closePosition:
|
|
163
|
+
s.input.closePosition != null
|
|
164
|
+
? Boolean(s.input.closePosition)
|
|
165
|
+
: null,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const events: ClendAccountEvent[] = (s.events || []).map((event: any) => {
|
|
170
|
+
let closeBalance: boolean | null = null;
|
|
171
|
+
if (event.closeBalance !== null && event.closeBalance !== undefined) {
|
|
172
|
+
closeBalance = Boolean(event.closeBalance);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
eventIndex: event.eventIndex,
|
|
177
|
+
eventName: event.eventName,
|
|
178
|
+
bank: event.bank ? new web3.PublicKey(event.bank) : null,
|
|
179
|
+
mint: event.mint ? new web3.PublicKey(event.mint) : null,
|
|
180
|
+
amount: event.amount ? new BN(event.amount, "hex") : null,
|
|
181
|
+
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
182
|
+
value: event.value ? Number(event.value) : null,
|
|
183
|
+
price: event.price ? Number(event.price) : null,
|
|
184
|
+
closeBalance,
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const txSummary: ClendAccountTxSummary = {
|
|
189
|
+
txSig: s.txSig,
|
|
190
|
+
time: s.time,
|
|
191
|
+
clendAccount: new web3.PublicKey(s.clendAccount),
|
|
192
|
+
clendAccountAuthority: new web3.PublicKey(s.clendAccountAuthority),
|
|
193
|
+
clendGroup: new web3.PublicKey(s.clendGroup),
|
|
194
|
+
action: s.action,
|
|
195
|
+
input,
|
|
196
|
+
events,
|
|
197
|
+
};
|
|
198
|
+
return txSummary;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private parseClendAccountWithSummary(
|
|
203
|
+
accountData: any,
|
|
204
|
+
getClendAccountSummary: boolean,
|
|
205
|
+
): GetAccountResponse {
|
|
206
|
+
// A. Parse the main ClendAccount object
|
|
207
|
+
const rawClendAccount = accountData.clendAccount;
|
|
208
|
+
const clendAccountBalances: ClendAccountBalance[] = (
|
|
209
|
+
rawClendAccount.balances || []
|
|
210
|
+
).map((b: any) => {
|
|
211
|
+
const liquidation: ClendAccountAssetLiquidation | null = b.liquidation
|
|
212
|
+
? {
|
|
213
|
+
price: Number(b.liquidation.price),
|
|
214
|
+
changePercentage: Number(b.liquidation.changePercentage),
|
|
215
|
+
}
|
|
216
|
+
: null;
|
|
217
|
+
|
|
218
|
+
const emissionsOutstandingAndUnclaimed = new BN(
|
|
219
|
+
b.emissionsOutstandingAndUnclaimed,
|
|
220
|
+
"hex",
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
mint: new web3.PublicKey(b.mint),
|
|
225
|
+
bank: new web3.PublicKey(b.bank),
|
|
226
|
+
tokenYieldApy: Number(b.tokenYieldApy),
|
|
227
|
+
assetBalance: new BN(b.assetBalance, "hex"),
|
|
228
|
+
assetBalanceUi: Number(b.assetBalanceUi),
|
|
229
|
+
assetValue: Number(b.assetValue),
|
|
230
|
+
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
231
|
+
liabilityBalance: new BN(b.liabilityBalance, "hex"),
|
|
232
|
+
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
233
|
+
liabilityValue: Number(b.liabilityValue),
|
|
234
|
+
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
235
|
+
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
236
|
+
emissionsOutstandingAndUnclaimed,
|
|
237
|
+
emissionsOutstandingAndUnclaimedUi: Number(
|
|
238
|
+
b.emissionsOutstandingAndUnclaimedUi,
|
|
239
|
+
),
|
|
240
|
+
price: Number(b.price),
|
|
241
|
+
liquidation,
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const clendAccount: ClendAccount = {
|
|
246
|
+
key: new web3.PublicKey(rawClendAccount.key),
|
|
247
|
+
group: new web3.PublicKey(rawClendAccount.group),
|
|
248
|
+
balances: clendAccountBalances,
|
|
249
|
+
netValue: Number(rawClendAccount.netValue),
|
|
250
|
+
netApy: Number(rawClendAccount.netApy),
|
|
251
|
+
pnl: Number(rawClendAccount.pnl),
|
|
252
|
+
totalEmissionsApy: Number(rawClendAccount.totalEmissionsApy),
|
|
253
|
+
totalAssetValue: Number(rawClendAccount.totalAssetValue),
|
|
254
|
+
totalLiabilityValue: Number(rawClendAccount.totalLiabilityValue),
|
|
255
|
+
healthFactorNotional: Number(rawClendAccount.healthFactorNotional),
|
|
256
|
+
healthFactorRiskAdjusted: Number(
|
|
257
|
+
rawClendAccount.healthFactorRiskAdjusted,
|
|
258
|
+
),
|
|
259
|
+
notionalLeverage: Number(rawClendAccount.notionalLeverage),
|
|
260
|
+
riskAdjustedLeverage: Number(rawClendAccount.riskAdjustedLeverage),
|
|
261
|
+
notionalLtv: Number(rawClendAccount.notionalLtv),
|
|
262
|
+
riskAdjustedLtv: Number(rawClendAccount.riskAdjustedLtv),
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// B. Parse the associated Summary array for the account
|
|
266
|
+
let summary: ClendAccountTxSummary[] = [];
|
|
267
|
+
if (getClendAccountSummary && accountData.summary) {
|
|
268
|
+
summary = this.parseClendAccountSummary(accountData.summary);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// C. Combine the parsed account and its summary
|
|
272
|
+
return { clendAccount, summary };
|
|
273
|
+
}
|
|
274
|
+
|
|
111
275
|
async getUser(
|
|
112
276
|
user: web3.PublicKey,
|
|
113
277
|
groups: web3.PublicKey[],
|
|
@@ -141,137 +305,8 @@ export class Client {
|
|
|
141
305
|
// This is the main refactored section. It iterates through the clendAccounts array
|
|
142
306
|
// from the response, which contains both the account data and its summary.
|
|
143
307
|
const clendAccounts = (jsonRawResponse.clendAccounts || []).map(
|
|
144
|
-
(accountData: any) =>
|
|
145
|
-
|
|
146
|
-
const rawClendAccount = accountData.clendAccount;
|
|
147
|
-
const clendAccountBalances: ClendAccountBalance[] = (
|
|
148
|
-
rawClendAccount.balances || []
|
|
149
|
-
).map((b: any) => {
|
|
150
|
-
const liquidation: ClendAccountAssetLiquidation | null = b.liquidation
|
|
151
|
-
? {
|
|
152
|
-
price: Number(b.liquidation.price),
|
|
153
|
-
changePercentage: Number(b.liquidation.changePercentage),
|
|
154
|
-
}
|
|
155
|
-
: null;
|
|
156
|
-
|
|
157
|
-
const emissionsOutstandingAndUnclaimed = new BN(
|
|
158
|
-
b.emissionsOutstandingAndUnclaimed,
|
|
159
|
-
"hex",
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
mint: new web3.PublicKey(b.mint),
|
|
164
|
-
bank: new web3.PublicKey(b.bank),
|
|
165
|
-
tokenYieldApy: Number(b.tokenYieldApy),
|
|
166
|
-
assetBalance: new BN(b.assetBalance, "hex"),
|
|
167
|
-
assetBalanceUi: Number(b.assetBalanceUi),
|
|
168
|
-
assetValue: Number(b.assetValue),
|
|
169
|
-
assetEmissionsApy: Number(b.assetEmissionsApy),
|
|
170
|
-
liabilityBalance: new BN(b.liabilityBalance, "hex"),
|
|
171
|
-
liabilityBalanceUi: Number(b.liabilityBalanceUi),
|
|
172
|
-
liabilityValue: Number(b.liabilityValue),
|
|
173
|
-
liabilityBorrowCostApy: Number(b.liabilityBorrowCostApy),
|
|
174
|
-
liabilityEmissionsApy: Number(b.liabilityEmissionsApy),
|
|
175
|
-
emissionsOutstandingAndUnclaimed,
|
|
176
|
-
emissionsOutstandingAndUnclaimedUi: Number(
|
|
177
|
-
b.emissionsOutstandingAndUnclaimedUi,
|
|
178
|
-
),
|
|
179
|
-
price: Number(b.price),
|
|
180
|
-
liquidation,
|
|
181
|
-
};
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const clendAccount: ClendAccount = {
|
|
185
|
-
key: new web3.PublicKey(rawClendAccount.key),
|
|
186
|
-
group: new web3.PublicKey(rawClendAccount.group),
|
|
187
|
-
balances: clendAccountBalances,
|
|
188
|
-
netValue: Number(rawClendAccount.netValue),
|
|
189
|
-
netApy: Number(rawClendAccount.netApy),
|
|
190
|
-
pnl: Number(rawClendAccount.pnl),
|
|
191
|
-
totalEmissionsApy: Number(rawClendAccount.totalEmissionsApy),
|
|
192
|
-
totalAssetValue: Number(rawClendAccount.totalAssetValue),
|
|
193
|
-
totalLiabilityValue: Number(rawClendAccount.totalLiabilityValue),
|
|
194
|
-
healthFactorNotional: Number(rawClendAccount.healthFactorNotional),
|
|
195
|
-
healthFactorRiskAdjusted: Number(
|
|
196
|
-
rawClendAccount.healthFactorRiskAdjusted,
|
|
197
|
-
),
|
|
198
|
-
notionalLeverage: Number(rawClendAccount.notionalLeverage),
|
|
199
|
-
riskAdjustedLeverage: Number(rawClendAccount.riskAdjustedLeverage),
|
|
200
|
-
notionalLtv: Number(rawClendAccount.notionalLtv),
|
|
201
|
-
riskAdjustedLtv: Number(rawClendAccount.riskAdjustedLtv),
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// B. Parse the associated Summary array for the account
|
|
205
|
-
let summary: ClendAccountTxSummary[] = [];
|
|
206
|
-
if (getClendAccountSummary && accountData.summary) {
|
|
207
|
-
summary = accountData.summary.map((s: any) => {
|
|
208
|
-
let input: UserRequest | undefined = undefined;
|
|
209
|
-
if (s.input) {
|
|
210
|
-
input = {
|
|
211
|
-
apiPath: s.input.apiPath,
|
|
212
|
-
selectedTokenMint: s.input.selectedTokenMint
|
|
213
|
-
? new web3.PublicKey(s.input.selectedTokenMint)
|
|
214
|
-
: null,
|
|
215
|
-
amountUi: s.input.amountUi ? Number(s.input.amountUi) : null,
|
|
216
|
-
leverage: s.input.leverage ? Number(s.input.leverage) : null,
|
|
217
|
-
slippageBps: s.input.slippageBps
|
|
218
|
-
? Number(s.input.slippageBps)
|
|
219
|
-
: null,
|
|
220
|
-
openPosition:
|
|
221
|
-
s.input.openPosition != null
|
|
222
|
-
? Boolean(s.input.openPosition)
|
|
223
|
-
: null,
|
|
224
|
-
closePosition:
|
|
225
|
-
s.input.closePosition != null
|
|
226
|
-
? Boolean(s.input.closePosition)
|
|
227
|
-
: null,
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const events: ClendAccountEvent[] = (s.events || []).map(
|
|
232
|
-
(event: any) => {
|
|
233
|
-
let closeBalance: boolean | null = null;
|
|
234
|
-
// Only convert to boolean if the value is not null/undefined to preserve the null state.
|
|
235
|
-
if (
|
|
236
|
-
event.closeBalance !== null &&
|
|
237
|
-
event.closeBalance !== undefined
|
|
238
|
-
) {
|
|
239
|
-
closeBalance = Boolean(event.closeBalance);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
eventIndex: event.eventIndex,
|
|
244
|
-
eventName: event.eventName,
|
|
245
|
-
bank: event.bank ? new web3.PublicKey(event.bank) : null,
|
|
246
|
-
mint: event.mint ? new web3.PublicKey(event.mint) : null,
|
|
247
|
-
amount: event.amount ? new BN(event.amount, "hex") : null,
|
|
248
|
-
amountUi: event.amountUi ? Number(event.amountUi) : null,
|
|
249
|
-
value: event.value ? Number(event.value) : null,
|
|
250
|
-
price: event.price ? Number(event.price) : null,
|
|
251
|
-
closeBalance,
|
|
252
|
-
};
|
|
253
|
-
},
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
const txSummary: ClendAccountTxSummary = {
|
|
257
|
-
txSig: s.txSig,
|
|
258
|
-
time: s.time,
|
|
259
|
-
clendAccount: new web3.PublicKey(s.clendAccount),
|
|
260
|
-
clendAccountAuthority: new web3.PublicKey(
|
|
261
|
-
s.clendAccountAuthority,
|
|
262
|
-
),
|
|
263
|
-
clendGroup: new web3.PublicKey(s.clendGroup),
|
|
264
|
-
action: s.action,
|
|
265
|
-
input,
|
|
266
|
-
events,
|
|
267
|
-
};
|
|
268
|
-
return txSummary;
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// C. Combine the parsed account and its summary
|
|
273
|
-
return { clendAccount, summary };
|
|
274
|
-
},
|
|
308
|
+
(accountData: any) =>
|
|
309
|
+
this.parseClendAccountWithSummary(accountData, getClendAccountSummary),
|
|
275
310
|
);
|
|
276
311
|
|
|
277
312
|
// 3. Return the final, correctly structured response object.
|
|
@@ -358,23 +393,59 @@ export class Client {
|
|
|
358
393
|
return response;
|
|
359
394
|
}
|
|
360
395
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
396
|
+
async deposit(
|
|
397
|
+
clendGroup: web3.PublicKey,
|
|
398
|
+
clendAccount: web3.PublicKey | null,
|
|
399
|
+
inputTokenMint: web3.PublicKey,
|
|
400
|
+
uiAmount: number,
|
|
401
|
+
): Promise<string> {
|
|
402
|
+
const req: DepositRequest = {
|
|
403
|
+
owner: this.address(),
|
|
404
|
+
clendGroup,
|
|
405
|
+
clendAccount,
|
|
406
|
+
inputTokenMint,
|
|
407
|
+
depositAmountUi: uiAmount,
|
|
408
|
+
};
|
|
409
|
+
|
|
369
410
|
const body = await handleApiCall(() =>
|
|
370
|
-
this.http.
|
|
411
|
+
this.http.post("deposit", JSON.stringify(req)),
|
|
371
412
|
);
|
|
372
413
|
|
|
373
|
-
const
|
|
374
|
-
|
|
414
|
+
const depositResponse: DepositResponse = JSON.parse(body);
|
|
415
|
+
|
|
416
|
+
const txSig = await this.send(
|
|
417
|
+
depositResponse.unsignedBase64Tx,
|
|
418
|
+
depositResponse.userRequestId,
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
return txSig;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
async withdraw(
|
|
425
|
+
clendAccount: web3.PublicKey,
|
|
426
|
+
outputTokenMint: web3.PublicKey,
|
|
427
|
+
uiAmount: number,
|
|
428
|
+
withdrawAll: boolean,
|
|
429
|
+
): Promise<string> {
|
|
430
|
+
const req: WithdrawRequest = {
|
|
431
|
+
clendAccount,
|
|
432
|
+
outputTokenMint,
|
|
433
|
+
withdrawAmountUi: uiAmount,
|
|
434
|
+
withdrawAll,
|
|
375
435
|
};
|
|
376
436
|
|
|
377
|
-
|
|
437
|
+
const body = await handleApiCall(() =>
|
|
438
|
+
this.http.post("withdraw", JSON.stringify(req)),
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
const withdrawResponse: WithdrawResponse = JSON.parse(body);
|
|
442
|
+
|
|
443
|
+
const txSig = await this.send(
|
|
444
|
+
withdrawResponse.unsignedBase64Tx,
|
|
445
|
+
withdrawResponse.userRequestId,
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
return txSig;
|
|
378
449
|
}
|
|
379
450
|
|
|
380
451
|
/**
|
package/src/types.ts
CHANGED
|
@@ -6,6 +6,37 @@ export interface SendRequest {
|
|
|
6
6
|
txns: string[];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Request to deposit collateral
|
|
11
|
+
*/
|
|
12
|
+
export interface DepositRequest {
|
|
13
|
+
owner: web3.PublicKey;
|
|
14
|
+
clendGroup: web3.PublicKey;
|
|
15
|
+
clendAccount: web3.PublicKey | null;
|
|
16
|
+
inputTokenMint: web3.PublicKey;
|
|
17
|
+
depositAmountUi: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DepositResponse {
|
|
21
|
+
userRequestId: string;
|
|
22
|
+
unsignedBase64Tx: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Request to withdraw collateral
|
|
27
|
+
*/
|
|
28
|
+
export interface WithdrawRequest {
|
|
29
|
+
clendAccount: web3.PublicKey;
|
|
30
|
+
outputTokenMint: web3.PublicKey;
|
|
31
|
+
withdrawAmountUi: number;
|
|
32
|
+
withdrawAll: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WithdrawResponse {
|
|
36
|
+
userRequestId: string;
|
|
37
|
+
unsignedBase64Tx: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
9
40
|
/**
|
|
10
41
|
* Request to deposit collateral and create a leveraged position
|
|
11
42
|
*/
|
|
@@ -98,6 +129,16 @@ export interface GroupAndBanks {
|
|
|
98
129
|
banks: Bank[];
|
|
99
130
|
}
|
|
100
131
|
|
|
132
|
+
export interface GetAccountRequest {
|
|
133
|
+
account: web3.PublicKey;
|
|
134
|
+
getClendAccountSummary: boolean;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface GetAccountResponse {
|
|
138
|
+
clendAccount: ClendAccount;
|
|
139
|
+
summary: ClendAccountTxSummary[];
|
|
140
|
+
}
|
|
141
|
+
|
|
101
142
|
export interface GetUserRequest {
|
|
102
143
|
groups: web3.PublicKey[];
|
|
103
144
|
user: web3.PublicKey;
|
|
@@ -112,22 +153,6 @@ export interface GetUserResponse {
|
|
|
112
153
|
}[];
|
|
113
154
|
}
|
|
114
155
|
|
|
115
|
-
export interface GetVaultOHLCRequest {
|
|
116
|
-
vault: web3.PublicKey;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export interface VaultOHLCDataPoint {
|
|
120
|
-
time: number;
|
|
121
|
-
open: number;
|
|
122
|
-
high: number;
|
|
123
|
-
low: number;
|
|
124
|
-
close: number;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface GetVaultOHLCResponse {
|
|
128
|
-
data: VaultOHLCDataPoint[];
|
|
129
|
-
}
|
|
130
|
-
|
|
131
156
|
export interface UserWallet {
|
|
132
157
|
balances: UserBalance[];
|
|
133
158
|
}
|