@haven-fi/solauto-sdk 1.0.310 → 1.0.312
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/constants/solautoConstants.d.ts +1 -0
- package/dist/constants/solautoConstants.d.ts.map +1 -1
- package/dist/constants/solautoConstants.js +2 -7
- package/dist/transactions/transactionUtils.d.ts.map +1 -1
- package/dist/transactions/transactionUtils.js +4 -2
- package/dist/transactions/transactionsManager.d.ts +3 -1
- package/dist/transactions/transactionsManager.d.ts.map +1 -1
- package/dist/transactions/transactionsManager.js +35 -7
- package/dist/utils/jitoUtils.d.ts +5 -0
- package/dist/utils/jitoUtils.d.ts.map +1 -1
- package/dist/utils/jitoUtils.js +98 -151
- package/dist/utils/jupiterUtils.d.ts.map +1 -1
- package/dist/utils/jupiterUtils.js +0 -6
- package/dist/utils/priceUtils.d.ts +1 -6
- package/dist/utils/priceUtils.d.ts.map +1 -1
- package/dist/utils/priceUtils.js +3 -17
- package/dist/utils/solauto/generalUtils.d.ts +1 -1
- package/dist/utils/solauto/generalUtils.d.ts.map +1 -1
- package/dist/utils/solauto/generalUtils.js +10 -2
- package/dist/utils/switchboardUtils.d.ts +6 -0
- package/dist/utils/switchboardUtils.d.ts.map +1 -1
- package/dist/utils/switchboardUtils.js +27 -2
- package/package.json +2 -1
- package/src/constants/solautoConstants.ts +1 -6
- package/src/transactions/transactionUtils.ts +9 -3
- package/src/transactions/transactionsManager.ts +74 -7
- package/src/utils/jitoUtils.ts +166 -166
- package/src/utils/jupiterUtils.ts +0 -6
- package/src/utils/priceUtils.ts +5 -32
- package/src/utils/solauto/generalUtils.ts +23 -1
- package/src/utils/switchboardUtils.ts +58 -3
- package/tests/transactions/solautoMarginfi.ts +27 -26
package/src/utils/priceUtils.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
2
2
|
import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
|
3
3
|
import { PYTH_PRICE_FEED_IDS } from "../constants/pythConstants";
|
4
4
|
import { fromBaseUnit, toBaseUnit } from "./numberUtils";
|
@@ -9,7 +9,7 @@ import {
|
|
9
9
|
retryWithExponentialBackoff,
|
10
10
|
zip,
|
11
11
|
} from "./generalUtils";
|
12
|
-
import {
|
12
|
+
import { getSwitchboardPrices } from "./switchboardUtils";
|
13
13
|
|
14
14
|
export async function fetchTokenPrices(
|
15
15
|
mints: PublicKey[]
|
@@ -32,7 +32,7 @@ export async function fetchTokenPrices(
|
|
32
32
|
|
33
33
|
const [pythData, switchboardData] = await Promise.all([
|
34
34
|
zip(pythMints, await getPythPrices(pythMints)),
|
35
|
-
zip(switchboardMints, await
|
35
|
+
zip(switchboardMints, await getSwitchboardPrices(switchboardMints)),
|
36
36
|
]);
|
37
37
|
|
38
38
|
const prices = mints.map((mint) => {
|
@@ -94,34 +94,6 @@ export async function getPythPrices(mints: PublicKey[]) {
|
|
94
94
|
return prices;
|
95
95
|
}
|
96
96
|
|
97
|
-
export async function getSwitchboardPrices(
|
98
|
-
conn: Connection,
|
99
|
-
mints: PublicKey[]
|
100
|
-
): Promise<{ mint: PublicKey; price: number; stale: boolean }[]> {
|
101
|
-
if (mints.length === 0) {
|
102
|
-
return [];
|
103
|
-
}
|
104
|
-
|
105
|
-
const currSlot = await retryWithExponentialBackoff(
|
106
|
-
async () => await conn.getSlot("confirmed"),
|
107
|
-
5
|
108
|
-
);
|
109
|
-
|
110
|
-
const results = await Promise.all(
|
111
|
-
mints.map(async (mint) => {
|
112
|
-
const feed = getPullFeed(conn, mint);
|
113
|
-
const result = await feed.loadData();
|
114
|
-
const price = Number(result.result.value) / Math.pow(10, 18);
|
115
|
-
const stale =
|
116
|
-
currSlot > result.result.slot.toNumber() + result.maxStaleness;
|
117
|
-
|
118
|
-
return { mint, price, stale };
|
119
|
-
})
|
120
|
-
);
|
121
|
-
|
122
|
-
return results;
|
123
|
-
}
|
124
|
-
|
125
97
|
export function safeGetPrice(
|
126
98
|
mint: PublicKey | UmiPublicKey | undefined
|
127
99
|
): number | undefined {
|
@@ -131,6 +103,7 @@ export function safeGetPrice(
|
|
131
103
|
return undefined;
|
132
104
|
}
|
133
105
|
|
106
|
+
// LEGACY, NOT USED
|
134
107
|
export async function getJupTokenPrices(mints: PublicKey[]) {
|
135
108
|
if (mints.length == 0) {
|
136
109
|
return [];
|
@@ -140,7 +113,7 @@ export async function getJupTokenPrices(mints: PublicKey[]) {
|
|
140
113
|
const res = (
|
141
114
|
await fetch(
|
142
115
|
"https://api.jup.ag/price/v2?ids=" +
|
143
|
-
mints.map((x) => x.toString()).join(",")
|
116
|
+
mints.map((x) => x.toString()).join(",") + "&showExtraInfo=true"
|
144
117
|
)
|
145
118
|
).json();
|
146
119
|
return res;
|
@@ -41,6 +41,7 @@ import {
|
|
41
41
|
} from "../marginfiUtils";
|
42
42
|
import { RebalanceAction, SolautoPositionDetails } from "../../types/solauto";
|
43
43
|
import { fetchTokenPrices } from "../priceUtils";
|
44
|
+
import { getRebalanceValues } from "./rebalanceUtils";
|
44
45
|
|
45
46
|
export function createDynamicSolautoProgram(programId: PublicKey): Program {
|
46
47
|
return {
|
@@ -132,6 +133,8 @@ export function eligibleForRebalance(
|
|
132
133
|
positionSettings: SolautoSettingsParameters | undefined,
|
133
134
|
positionDca: DCASettings | undefined,
|
134
135
|
currentUnixTime: number,
|
136
|
+
supplyMintPrice: number,
|
137
|
+
debtMintPrice: number,
|
135
138
|
bpsDistanceThreshold = 0
|
136
139
|
): RebalanceAction | undefined {
|
137
140
|
if (!positionSettings) {
|
@@ -167,7 +170,26 @@ export function eligibleForRebalance(
|
|
167
170
|
Math.max(0, positionState.liqUtilizationRateBps - boostFrom) <=
|
168
171
|
bpsDistanceThreshold
|
169
172
|
) {
|
170
|
-
|
173
|
+
const values = getRebalanceValues(
|
174
|
+
positionState!,
|
175
|
+
positionSettings,
|
176
|
+
positionDca,
|
177
|
+
currentUnixSeconds(),
|
178
|
+
supplyMintPrice,
|
179
|
+
debtMintPrice
|
180
|
+
);
|
181
|
+
const sufficientLiquidity =
|
182
|
+
fromBaseUnit(
|
183
|
+
positionState.debt.amountCanBeUsed.baseAmountUsdValue,
|
184
|
+
USD_DECIMALS
|
185
|
+
) *
|
186
|
+
0.95 >
|
187
|
+
values.debtAdjustmentUsd;
|
188
|
+
if (!sufficientLiquidity) {
|
189
|
+
console.log("Insufficient debt liquidity to further boost");
|
190
|
+
}
|
191
|
+
|
192
|
+
return sufficientLiquidity ? "boost" : undefined;
|
171
193
|
} else if (
|
172
194
|
Math.max(0, repayFrom - positionState.liqUtilizationRateBps) <=
|
173
195
|
bpsDistanceThreshold
|
@@ -14,6 +14,7 @@ import {
|
|
14
14
|
fromWeb3JsInstruction,
|
15
15
|
toWeb3JsPublicKey,
|
16
16
|
} from "@metaplex-foundation/umi-web3js-adapters";
|
17
|
+
import { retryWithExponentialBackoff } from "./generalUtils";
|
17
18
|
|
18
19
|
export function getPullFeed(
|
19
20
|
conn: Connection,
|
@@ -49,9 +50,14 @@ export async function buildSwbSubmitResponseTx(
|
|
49
50
|
): Promise<TransactionItemInputs | undefined> {
|
50
51
|
const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz");
|
51
52
|
const feed = getPullFeed(conn, mint, toWeb3JsPublicKey(signer.publicKey));
|
52
|
-
const [pullIx, responses] = await
|
53
|
-
|
54
|
-
|
53
|
+
const [pullIx, responses] = await retryWithExponentialBackoff(
|
54
|
+
async () =>
|
55
|
+
await feed.fetchUpdateIx({
|
56
|
+
crossbarClient: crossbar,
|
57
|
+
}),
|
58
|
+
8,
|
59
|
+
200
|
60
|
+
);
|
55
61
|
|
56
62
|
return {
|
57
63
|
tx: transactionBuilder().add({
|
@@ -64,3 +70,52 @@ export async function buildSwbSubmitResponseTx(
|
|
64
70
|
.map((x) => x.oracle.lut!.key.toString()),
|
65
71
|
};
|
66
72
|
}
|
73
|
+
|
74
|
+
export async function getSwitchboardFeedData(
|
75
|
+
conn: Connection,
|
76
|
+
mints: PublicKey[]
|
77
|
+
): Promise<{ mint: PublicKey; price: number; stale: boolean }[]> {
|
78
|
+
if (mints.length === 0) {
|
79
|
+
return [];
|
80
|
+
}
|
81
|
+
|
82
|
+
const currSlot = await retryWithExponentialBackoff(
|
83
|
+
async () => await conn.getSlot("confirmed"),
|
84
|
+
5
|
85
|
+
);
|
86
|
+
|
87
|
+
const results = await Promise.all(
|
88
|
+
mints.map(async (mint) => {
|
89
|
+
const feed = getPullFeed(conn, mint);
|
90
|
+
const result = await feed.loadData();
|
91
|
+
const price = Number(result.result.value) / Math.pow(10, 18);
|
92
|
+
const stale =
|
93
|
+
currSlot > result.result.slot.toNumber() + result.maxStaleness;
|
94
|
+
|
95
|
+
return { mint, price, stale };
|
96
|
+
})
|
97
|
+
);
|
98
|
+
|
99
|
+
return results;
|
100
|
+
}
|
101
|
+
|
102
|
+
export async function getSwitchboardPrices(
|
103
|
+
mints: PublicKey[]
|
104
|
+
): Promise<number[]> {
|
105
|
+
if (mints.length === 0) {
|
106
|
+
return [];
|
107
|
+
}
|
108
|
+
|
109
|
+
const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz");
|
110
|
+
const results = await retryWithExponentialBackoff(
|
111
|
+
async () =>
|
112
|
+
await crossbar.simulateSolanaFeeds(
|
113
|
+
"mainnet",
|
114
|
+
mints.map((x) => SWITCHBOARD_PRICE_FEED_IDS[x.toString()])
|
115
|
+
),
|
116
|
+
8,
|
117
|
+
200
|
118
|
+
);
|
119
|
+
|
120
|
+
return results.flatMap((x) => x.results[0]);
|
121
|
+
}
|
@@ -27,7 +27,7 @@ import {
|
|
27
27
|
SOLAUTO_TEST_PROGRAM,
|
28
28
|
USDC,
|
29
29
|
} from "../../src/constants";
|
30
|
-
import { buildHeliusApiUrl
|
30
|
+
import { buildHeliusApiUrl } from "../../src/utils";
|
31
31
|
import { PriorityFeeSetting } from "../../src/types";
|
32
32
|
|
33
33
|
describe("Solauto Marginfi tests", async () => {
|
@@ -41,8 +41,8 @@ describe("Solauto Marginfi tests", async () => {
|
|
41
41
|
it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => {
|
42
42
|
const client = new SolautoMarginfiClient(
|
43
43
|
buildHeliusApiUrl(process.env.HELIUS_API_KEY!),
|
44
|
-
true
|
45
|
-
|
44
|
+
true,
|
45
|
+
testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM
|
46
46
|
);
|
47
47
|
|
48
48
|
const supply = NATIVE_MINT;
|
@@ -52,7 +52,7 @@ describe("Solauto Marginfi tests", async () => {
|
|
52
52
|
await client.initialize({
|
53
53
|
signer,
|
54
54
|
positionId,
|
55
|
-
authority: new PublicKey("rC5dMP5dmSsfQ66rynzfFzuc122Eex9h1RJHVDkeH6D"),
|
55
|
+
authority: new PublicKey("rC5dMP5dmSsfQ66rynzfFzuc122Eex9h1RJHVDkeH6D"), // positions 1 & 3 are taken
|
56
56
|
// new: true,
|
57
57
|
// marginfiAccount: new PublicKey(
|
58
58
|
// "4nNvUXF5YqHFcH2nGweSiuvy1ct7V5FXfoCLKFYUN36z"
|
@@ -63,20 +63,20 @@ describe("Solauto Marginfi tests", async () => {
|
|
63
63
|
});
|
64
64
|
|
65
65
|
const transactionItems: TransactionItem[] = [];
|
66
|
-
const settingParams: SolautoSettingsParametersInpArgs = {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
};
|
66
|
+
// const settingParams: SolautoSettingsParametersInpArgs = {
|
67
|
+
// boostToBps: maxBoostToBps(
|
68
|
+
// client.solautoPositionState?.maxLtvBps ?? 0,
|
69
|
+
// client.solautoPositionState?.liqThresholdBps ?? 0
|
70
|
+
// ),
|
71
|
+
// boostGap: 50,
|
72
|
+
// repayToBps: maxRepayToBps(
|
73
|
+
// client.solautoPositionState?.maxLtvBps ?? 0,
|
74
|
+
// client.solautoPositionState?.liqThresholdBps ?? 0
|
75
|
+
// ),
|
76
|
+
// repayGap: 50,
|
77
|
+
// automation: none(),
|
78
|
+
// targetBoostToBps: none(),
|
79
|
+
// };
|
80
80
|
|
81
81
|
// if (client.solautoPositionData === null) {
|
82
82
|
// transactionItems.push(
|
@@ -123,7 +123,7 @@ describe("Solauto Marginfi tests", async () => {
|
|
123
123
|
transactionItems.push(
|
124
124
|
new TransactionItem(
|
125
125
|
async (attemptNum) =>
|
126
|
-
await buildSolautoRebalanceTransaction(client,
|
126
|
+
await buildSolautoRebalanceTransaction(client, 5000, attemptNum),
|
127
127
|
"rebalance"
|
128
128
|
)
|
129
129
|
);
|
@@ -156,13 +156,14 @@ describe("Solauto Marginfi tests", async () => {
|
|
156
156
|
// )
|
157
157
|
// );
|
158
158
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
159
|
+
const statuses = await new TransactionsManager(
|
160
|
+
client,
|
161
|
+
undefined,
|
162
|
+
!payForTransactions ? "only-simulate" : "normal",
|
163
|
+
PriorityFeeSetting.Low,
|
164
|
+
true
|
165
|
+
).clientSend(transactionItems);
|
165
166
|
|
166
|
-
|
167
|
+
console.log(statuses);
|
167
168
|
});
|
168
169
|
});
|