@haven-fi/solauto-sdk 1.0.8 → 1.0.10
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/clients/index.d.ts +1 -0
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +1 -0
- package/dist/clients/solautoClient.d.ts +3 -3
- package/dist/clients/solautoClient.d.ts.map +1 -1
- package/dist/clients/solautoClient.js +15 -46
- package/dist/clients/solautoMarginfiClient.d.ts +1 -1
- package/dist/clients/solautoMarginfiClient.d.ts.map +1 -1
- package/dist/clients/solautoMarginfiClient.js +4 -5
- package/dist/constants/solautoConstants.d.ts +0 -3
- package/dist/constants/solautoConstants.d.ts.map +1 -1
- package/dist/constants/solautoConstants.js +1 -8
- package/dist/transactions/transactionUtils.d.ts +2 -2
- package/dist/transactions/transactionUtils.d.ts.map +1 -1
- package/dist/transactions/transactionUtils.js +9 -10
- package/dist/transactions/transactionsManager.d.ts.map +1 -1
- package/dist/transactions/transactionsManager.js +6 -7
- package/dist/utils/generalUtils.d.ts +2 -2
- package/dist/utils/generalUtils.d.ts.map +1 -1
- package/dist/utils/generalUtils.js +3 -3
- package/dist/utils/marginfiUtils.d.ts +4 -3
- package/dist/utils/marginfiUtils.d.ts.map +1 -1
- package/dist/utils/marginfiUtils.js +17 -16
- package/dist/utils/solanaUtils.d.ts +6 -7
- package/dist/utils/solanaUtils.d.ts.map +1 -1
- package/dist/utils/solanaUtils.js +20 -21
- package/dist/utils/solauto/generalUtils.d.ts +4 -4
- package/dist/utils/solauto/generalUtils.d.ts.map +1 -1
- package/dist/utils/solauto/generalUtils.js +50 -7
- package/package.json +1 -1
- package/src/clients/index.ts +2 -1
- package/src/clients/solautoClient.ts +39 -73
- package/src/clients/solautoMarginfiClient.ts +5 -8
- package/src/constants/solautoConstants.ts +1 -11
- package/src/transactions/transactionUtils.ts +11 -11
- package/src/transactions/transactionsManager.ts +11 -7
- package/src/utils/generalUtils.ts +5 -5
- package/src/utils/marginfiUtils.ts +28 -12
- package/src/utils/solanaUtils.ts +28 -23
- package/src/utils/solauto/generalUtils.ts +91 -14
- package/tests/transactions/solautoMarginfi.ts +2 -1
@@ -10,16 +10,15 @@ const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters"
|
|
10
10
|
const web3_js_1 = require("@solana/web3.js");
|
11
11
|
const spl_token_1 = require("@solana/spl-token");
|
12
12
|
const accountUtils_1 = require("./accountUtils");
|
13
|
-
const solautoConstants_1 = require("../constants/solautoConstants");
|
14
13
|
const generalUtils_1 = require("./generalUtils");
|
15
14
|
const marginfi_sdk_1 = require("../marginfi-sdk");
|
16
|
-
async function currentUnixSecondsSolana() {
|
15
|
+
async function currentUnixSecondsSolana(umi) {
|
17
16
|
return await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
18
|
-
const blockTime = await
|
17
|
+
const blockTime = await umi.rpc.getBlockTime(await umi.rpc.getSlot());
|
19
18
|
if (blockTime === null) {
|
20
19
|
throw new Error("Unable to retrieve block time");
|
21
20
|
}
|
22
|
-
return blockTime;
|
21
|
+
return Number(blockTime);
|
23
22
|
});
|
24
23
|
}
|
25
24
|
exports.currentUnixSecondsSolana = currentUnixSecondsSolana;
|
@@ -63,8 +62,8 @@ function splTokenTransferUmiIx(signer, fromTa, toTa, authority, amount) {
|
|
63
62
|
return getWrappedInstruction(signer, (0, spl_token_1.createTransferInstruction)(fromTa, toTa, authority, amount));
|
64
63
|
}
|
65
64
|
exports.splTokenTransferUmiIx = splTokenTransferUmiIx;
|
66
|
-
async function getAdressLookupInputs(lookupTableAddresses) {
|
67
|
-
const addressLookupTableAccountInfos = await
|
65
|
+
async function getAdressLookupInputs(umi, lookupTableAddresses) {
|
66
|
+
const addressLookupTableAccountInfos = await umi.rpc.getAccounts(lookupTableAddresses.map((key) => (0, umi_1.publicKey)(key)));
|
68
67
|
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
|
69
68
|
const addressLookupTableAddress = lookupTableAddresses[index];
|
70
69
|
if (accountInfo.exists) {
|
@@ -119,8 +118,8 @@ function assembleFinalTransaction(signer, tx, computeUnitPrice, computeUnitLimit
|
|
119
118
|
return tx;
|
120
119
|
}
|
121
120
|
exports.assembleFinalTransaction = assembleFinalTransaction;
|
122
|
-
async function simulateTransaction(transaction) {
|
123
|
-
const simulationResult = await
|
121
|
+
async function simulateTransaction(connection, transaction) {
|
122
|
+
const simulationResult = await connection.simulateTransaction(transaction, {
|
124
123
|
sigVerify: true,
|
125
124
|
});
|
126
125
|
if (simulationResult.value.err) {
|
@@ -131,10 +130,10 @@ async function simulateTransaction(transaction) {
|
|
131
130
|
}
|
132
131
|
return simulationResult;
|
133
132
|
}
|
134
|
-
async function getComputeUnitPriceEstimate(tx, attemptNum) {
|
135
|
-
const web3Transaction = (0, umi_web3js_adapters_1.toWeb3JsTransaction)((await tx.setLatestBlockhash(
|
133
|
+
async function getComputeUnitPriceEstimate(umi, tx, attemptNum) {
|
134
|
+
const web3Transaction = (0, umi_web3js_adapters_1.toWeb3JsTransaction)((await tx.setLatestBlockhash(umi, { commitment: "finalized" })).build(umi));
|
136
135
|
const serializedTransaction = bs58_1.default.encode(web3Transaction.serialize());
|
137
|
-
const resp = await
|
136
|
+
const resp = await umi.rpc.call("getPriorityFeeEstimate", [
|
138
137
|
{
|
139
138
|
transaction: serializedTransaction,
|
140
139
|
options: { priorityLevel: attemptNum && attemptNum > 0 ? "VeryHigh" : "High" },
|
@@ -144,24 +143,24 @@ async function getComputeUnitPriceEstimate(tx, attemptNum) {
|
|
144
143
|
return feeEstimate;
|
145
144
|
}
|
146
145
|
exports.getComputeUnitPriceEstimate = getComputeUnitPriceEstimate;
|
147
|
-
async function sendSingleOptimizedTransaction(
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
const feeEstimate = await getComputeUnitPriceEstimate(tx, attemptNum);
|
152
|
-
|
153
|
-
const simulationResult = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await simulateTransaction((0, umi_web3js_adapters_1.toWeb3JsTransaction)(await (await assembleFinalTransaction(
|
146
|
+
async function sendSingleOptimizedTransaction(umi, connection, tx, simulateOnly, attemptNum) {
|
147
|
+
console.log("Sending single optimized transaction...");
|
148
|
+
console.log("Instructions: ", tx.getInstructions().length);
|
149
|
+
console.log("Serialized transaction size: ", tx.getTransactionSize(umi));
|
150
|
+
const feeEstimate = await getComputeUnitPriceEstimate(umi, tx, attemptNum);
|
151
|
+
console.log("Compute unit price: ", feeEstimate);
|
152
|
+
const simulationResult = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await simulateTransaction(connection, (0, umi_web3js_adapters_1.toWeb3JsTransaction)(await (await assembleFinalTransaction(umi.identity, tx, feeEstimate, 1400000).setLatestBlockhash(umi)).buildAndSign(umi))));
|
154
153
|
const computeUnitLimit = Math.round(simulationResult.value.unitsConsumed * 1.15);
|
155
|
-
|
154
|
+
console.log("Compute unit limit: ", computeUnitLimit);
|
156
155
|
if (!simulateOnly) {
|
157
|
-
const result = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await assembleFinalTransaction(
|
156
|
+
const result = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => await assembleFinalTransaction(umi.identity, tx, feeEstimate, computeUnitLimit).sendAndConfirm(umi, {
|
158
157
|
send: {
|
159
158
|
skipPreflight: true,
|
160
159
|
commitment: "finalized",
|
161
160
|
},
|
162
161
|
confirm: { commitment: "finalized" },
|
163
162
|
}));
|
164
|
-
|
163
|
+
console.log(`https://solscan.io/tx/${bs58_1.default.encode(result.signature)}`);
|
165
164
|
if (result.result.value.err !== null) {
|
166
165
|
throw new Error(result.result.value.err.toString());
|
167
166
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { PublicKey } from "@metaplex-foundation/umi";
|
1
|
+
import { PublicKey, Umi } from "@metaplex-foundation/umi";
|
2
2
|
import { AutomationSettings, DCASettings, DCASettingsInpArgs, FeeType, LendingPlatform, PositionState, SolautoSettingsParameters, SolautoSettingsParametersInpArgs } from "../../generated";
|
3
3
|
export declare function nextAutomationPeriodTimestamp(automation: AutomationSettings): number;
|
4
4
|
export declare function eligibleForNextAutomationPeriod(automation: AutomationSettings): boolean;
|
@@ -14,13 +14,13 @@ export declare function maxRepayFrom(maxLtvBps: number, liqThresholdBps: number)
|
|
14
14
|
export declare function maxRepayTo(maxLtvBps: number, liqThresholdBps: number): number;
|
15
15
|
export declare function eligibileForRebalance(positionState: PositionState, positionSettings: SolautoSettingsParameters, positionDca: DCASettings): boolean;
|
16
16
|
export declare function eligibleForRefresh(positionState: PositionState, positionSettings: SolautoSettingsParameters): boolean;
|
17
|
-
export declare function getSolautoManagedPositions(authority?: PublicKey): Promise<{
|
17
|
+
export declare function getSolautoManagedPositions(umi: Umi, authority?: PublicKey): Promise<{
|
18
18
|
authority: PublicKey;
|
19
19
|
positionId: number;
|
20
20
|
lendingPlatform: LendingPlatform;
|
21
21
|
}[]>;
|
22
|
-
export declare function getAllReferralStates(): Promise<PublicKey[]>;
|
23
|
-
export declare function getReferralsByUser(user: PublicKey): Promise<PublicKey[]>;
|
22
|
+
export declare function getAllReferralStates(umi: Umi): Promise<PublicKey[]>;
|
23
|
+
export declare function getReferralsByUser(umi: Umi, user: PublicKey): Promise<PublicKey[]>;
|
24
24
|
type PositionAdjustment = {
|
25
25
|
type: "supply";
|
26
26
|
value: bigint;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
1
|
+
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,SAAS,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,aAAa,EAEb,yBAAyB,EACzB,gCAAgC,EAIjC,MAAM,iBAAiB,CAAC;AA6BzB,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,kBAAkB,GAC7B,MAAM,CAKR;AAED,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAET;AAED,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,kBAAkB,EAC9B,oBAAoB,EAAE,MAAM,UAY7B;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,yBAAyB,EACnC,kBAAkB,EAAE,MAAM,GACzB,yBAAyB,CAgB3B;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,OAAO,GACf;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAYA;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,MAAM,CAER;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKtE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKpE;AAED,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,yBAAyB,EAC3C,WAAW,EAAE,WAAW,GACvB,OAAO,CA+BT;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,yBAAyB,GAC1C,OAAO,CAST;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CACR;IACE,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,eAAe,CAAC;CAClC,EAAE,CACJ,CAkDA;AAED,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAezE;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,SAAS,EAAE,CAAC,CA2BtB;AA4DD,KAAK,kBAAkB,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,gCAAgC,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE/C,qBAAa,mBAAmB;IACvB,gBAAgB,EAAE,MAAM,CAAa;IACrC,cAAc,EAAE,MAAM,CAAa;IACnC,uBAAuB,EAAE,MAAM,CAAa;IAC5C,QAAQ,EAAE,yBAAyB,GAAG,SAAS,CAAa;IAC5D,SAAS,EAAE,WAAW,GAAG,SAAS,CAAa;IAEtD,GAAG,CAAC,MAAM,EAAE,kBAAkB;IAyD9B,KAAK;IAQL,UAAU,IAAI,OAAO;CAQtB"}
|
@@ -8,6 +8,8 @@ const numberUtils_1 = require("../numberUtils");
|
|
8
8
|
const solautoConstants_1 = require("../../constants/solautoConstants");
|
9
9
|
const accountUtils_1 = require("../accountUtils");
|
10
10
|
const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters");
|
11
|
+
const constants_1 = require("../../constants");
|
12
|
+
const marginfiUtils_1 = require("../marginfiUtils");
|
11
13
|
function newPeriodsPassed(automation, currentUnixTimestamp) {
|
12
14
|
return Math.min(automation.targetPeriods, automation.periodsPassed +
|
13
15
|
Math.floor((currentUnixTimestamp - Number(automation.unixStartDate)) /
|
@@ -95,18 +97,19 @@ function eligibleForRefresh(positionState, positionSettings) {
|
|
95
97
|
return eligibleForNextAutomationPeriod(positionSettings.automation);
|
96
98
|
}
|
97
99
|
else {
|
98
|
-
return (0, generalUtils_1.currentUnixSeconds)() - Number(positionState.lastUpdated) >
|
100
|
+
return ((0, generalUtils_1.currentUnixSeconds)() - Number(positionState.lastUpdated) >
|
101
|
+
60 * 60 * 24 * 7);
|
99
102
|
}
|
100
103
|
}
|
101
104
|
exports.eligibleForRefresh = eligibleForRefresh;
|
102
|
-
async function getSolautoManagedPositions(authority) {
|
105
|
+
async function getSolautoManagedPositions(umi, authority) {
|
103
106
|
// bump: [u8; 1]
|
104
107
|
// position_id: [u8; 1]
|
105
108
|
// self_managed: u8 - (1 for true, 0 for false)
|
106
109
|
// padding: [u8; 5]
|
107
110
|
// authority: Pubkey
|
108
111
|
// lending_platform: u8
|
109
|
-
const accounts = await
|
112
|
+
const accounts = await umi.rpc.getProgramAccounts(generated_1.SOLAUTO_PROGRAM_ID, {
|
110
113
|
commitment: "finalized",
|
111
114
|
dataSlice: {
|
112
115
|
offset: 0,
|
@@ -147,8 +150,8 @@ async function getSolautoManagedPositions(authority) {
|
|
147
150
|
});
|
148
151
|
}
|
149
152
|
exports.getSolautoManagedPositions = getSolautoManagedPositions;
|
150
|
-
async function getAllReferralStates() {
|
151
|
-
const accounts = await
|
153
|
+
async function getAllReferralStates(umi) {
|
154
|
+
const accounts = await umi.rpc.getProgramAccounts(generated_1.SOLAUTO_PROGRAM_ID, {
|
152
155
|
commitment: "finalized",
|
153
156
|
dataSlice: {
|
154
157
|
offset: 0,
|
@@ -163,13 +166,13 @@ async function getAllReferralStates() {
|
|
163
166
|
return accounts.map((x) => x.publicKey);
|
164
167
|
}
|
165
168
|
exports.getAllReferralStates = getAllReferralStates;
|
166
|
-
async function getReferralsByUser(user) {
|
169
|
+
async function getReferralsByUser(umi, user) {
|
167
170
|
// bump: [u8; 1],
|
168
171
|
// padding: [u8; 7],
|
169
172
|
// authority: Pubkey,
|
170
173
|
// referred_by_state: Pubkey,
|
171
174
|
const userReferralState = await (0, accountUtils_1.getReferralState)((0, umi_web3js_adapters_1.toWeb3JsPublicKey)(user));
|
172
|
-
const accounts = await
|
175
|
+
const accounts = await umi.rpc.getProgramAccounts(generated_1.SOLAUTO_PROGRAM_ID, {
|
173
176
|
commitment: "finalized",
|
174
177
|
dataSlice: {
|
175
178
|
offset: 0,
|
@@ -190,6 +193,46 @@ async function getReferralsByUser(user) {
|
|
190
193
|
return accounts.map((x) => x.publicKey);
|
191
194
|
}
|
192
195
|
exports.getReferralsByUser = getReferralsByUser;
|
196
|
+
async function positionStateWithLatestPrices(umi, state, protocolAccount, lendingPlatform) {
|
197
|
+
if ((0, generalUtils_1.currentUnixSeconds)() - Number(state.lastUpdated) > 60 * 60 * 24 * 7) {
|
198
|
+
if (lendingPlatform === generated_1.LendingPlatform.Marginfi) {
|
199
|
+
return await (0, marginfiUtils_1.getMarginfiAccountPositionState)(umi, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.supply.mint), (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.debt.mint), (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(protocolAccount));
|
200
|
+
}
|
201
|
+
else {
|
202
|
+
throw new Error("Lending platorm not yet supported");
|
203
|
+
}
|
204
|
+
}
|
205
|
+
const [supplyPrice, debtPrice] = await (0, generalUtils_1.getTokenPrices)([
|
206
|
+
(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.supply.mint),
|
207
|
+
(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(state.debt.mint),
|
208
|
+
]);
|
209
|
+
const supplyUsd = (0, numberUtils_1.fromBaseUnit)(state.supply.amountUsed.baseUnit, state.supply.decimals) *
|
210
|
+
supplyPrice;
|
211
|
+
const debtUsd = (0, numberUtils_1.fromBaseUnit)(state.debt.amountUsed.baseUnit, state.debt.decimals) *
|
212
|
+
debtPrice;
|
213
|
+
return {
|
214
|
+
...state,
|
215
|
+
liqUtilizationRateBps: (0, numberUtils_1.getLiqUtilzationRateBps)(supplyUsd, debtUsd, state.liqThresholdBps),
|
216
|
+
netWorth: {
|
217
|
+
...state.netWorth,
|
218
|
+
baseAmountUsdValue: (0, numberUtils_1.toBaseUnit)(supplyUsd - debtUsd, constants_1.USD_DECIMALS),
|
219
|
+
},
|
220
|
+
supply: {
|
221
|
+
...state.supply,
|
222
|
+
amountUsed: {
|
223
|
+
...state.supply.amountUsed,
|
224
|
+
baseAmountUsdValue: (0, numberUtils_1.toBaseUnit)(supplyUsd, constants_1.USD_DECIMALS),
|
225
|
+
},
|
226
|
+
},
|
227
|
+
debt: {
|
228
|
+
...state.debt,
|
229
|
+
amountUsed: {
|
230
|
+
...state.debt.amountUsed,
|
231
|
+
baseAmountUsdValue: (0, numberUtils_1.toBaseUnit)(debtUsd, constants_1.USD_DECIMALS),
|
232
|
+
},
|
233
|
+
},
|
234
|
+
};
|
235
|
+
}
|
193
236
|
class LivePositionUpdates {
|
194
237
|
constructor() {
|
195
238
|
this.supplyAdjustment = BigInt(0);
|
package/package.json
CHANGED
package/src/clients/index.ts
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
export * from './solautoMarginfiClient';
|
1
|
+
export * from './solautoMarginfiClient';
|
2
|
+
export * from './solautoClient';
|
@@ -1,5 +1,9 @@
|
|
1
1
|
import "rpc-websockets/dist/lib/client";
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
AddressLookupTableProgram,
|
4
|
+
Connection,
|
5
|
+
PublicKey,
|
6
|
+
} from "@solana/web3.js";
|
3
7
|
import {
|
4
8
|
Signer,
|
5
9
|
TransactionBuilder,
|
@@ -13,7 +17,10 @@ import {
|
|
13
17
|
some,
|
14
18
|
} from "@metaplex-foundation/umi";
|
15
19
|
import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
16
|
-
import {
|
20
|
+
import {
|
21
|
+
WalletAdapter,
|
22
|
+
walletAdapterIdentity,
|
23
|
+
} from "@metaplex-foundation/umi-signer-wallet-adapters";
|
17
24
|
import {
|
18
25
|
DCASettings,
|
19
26
|
DCASettingsInpArgs,
|
@@ -29,6 +36,7 @@ import {
|
|
29
36
|
cancelDCA,
|
30
37
|
claimReferralFees,
|
31
38
|
closePosition,
|
39
|
+
createSolautoProgram,
|
32
40
|
safeFetchReferralState,
|
33
41
|
safeFetchSolautoPosition,
|
34
42
|
updatePosition,
|
@@ -39,10 +47,7 @@ import {
|
|
39
47
|
getSolautoPositionAccount,
|
40
48
|
getTokenAccount,
|
41
49
|
} from "../utils/accountUtils";
|
42
|
-
import {
|
43
|
-
SOLAUTO_FEES_WALLET,
|
44
|
-
USD_DECIMALS,
|
45
|
-
} from "../constants/generalAccounts";
|
50
|
+
import { SOLAUTO_FEES_WALLET } from "../constants/generalAccounts";
|
46
51
|
import { JupSwapDetails } from "../utils/jupiterUtils";
|
47
52
|
import {
|
48
53
|
getWrappedInstruction,
|
@@ -50,18 +55,10 @@ import {
|
|
50
55
|
} from "../utils/solanaUtils";
|
51
56
|
import { FlashLoanDetails } from "../utils/solauto/rebalanceUtils";
|
52
57
|
import { NATIVE_MINT } from "@solana/spl-token";
|
53
|
-
import {
|
54
|
-
|
55
|
-
MIN_POSITION_STATE_FRESHNESS_SECS,
|
56
|
-
UMI,
|
57
|
-
} from "../constants/solautoConstants";
|
58
|
-
import { currentUnixSeconds, getTokenPrices } from "../utils/generalUtils";
|
58
|
+
import { MIN_POSITION_STATE_FRESHNESS_SECS } from "../constants/solautoConstants";
|
59
|
+
import { currentUnixSeconds } from "../utils/generalUtils";
|
59
60
|
import { LivePositionUpdates } from "../utils/solauto/generalUtils";
|
60
|
-
import {
|
61
|
-
fromBaseUnit,
|
62
|
-
getLiqUtilzationRateBps,
|
63
|
-
toBaseUnit,
|
64
|
-
} from "../utils/numberUtils";
|
61
|
+
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
65
62
|
|
66
63
|
export interface SolautoClientArgs {
|
67
64
|
authority?: PublicKey;
|
@@ -80,6 +77,7 @@ export abstract class SolautoClient {
|
|
80
77
|
public localTest: boolean;
|
81
78
|
|
82
79
|
public umi!: Umi;
|
80
|
+
public connection!: Connection;
|
83
81
|
public lendingPlatform!: LendingPlatform;
|
84
82
|
|
85
83
|
public authority!: PublicKey;
|
@@ -120,15 +118,32 @@ export abstract class SolautoClient {
|
|
120
118
|
this.localTest = Boolean(localTest);
|
121
119
|
}
|
122
120
|
|
123
|
-
async
|
124
|
-
|
121
|
+
async baseInitialize(
|
122
|
+
args: SolautoClientArgs,
|
123
|
+
lendingPlatform: LendingPlatform,
|
124
|
+
heliusApiKey: string
|
125
|
+
) {
|
126
|
+
this.connection = new Connection(
|
127
|
+
`https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`,
|
128
|
+
"finalized"
|
129
|
+
);
|
130
|
+
this.umi = createUmi(this.connection).use({
|
131
|
+
install(umi) {
|
132
|
+
umi.programs.add(createSolautoProgram(), false);
|
133
|
+
},
|
134
|
+
});
|
125
135
|
if (!args.signer && !args.wallet) {
|
126
136
|
throw new Error("Signer or wallet must be provided");
|
127
137
|
}
|
128
|
-
this.umi =
|
129
|
-
|
138
|
+
this.umi = this.umi.use(
|
139
|
+
args.signer
|
140
|
+
? signerIdentity(args.signer)
|
141
|
+
: walletAdapterIdentity(args.wallet!, true)
|
142
|
+
);
|
143
|
+
|
130
144
|
this.signer = this.umi.identity;
|
131
|
-
this.authority =
|
145
|
+
this.authority =
|
146
|
+
args.authority ?? toWeb3JsPublicKey(this.umi.identity.publicKey);
|
132
147
|
|
133
148
|
this.positionId = args.positionId;
|
134
149
|
this.selfManaged = this.positionId === 0;
|
@@ -282,7 +297,7 @@ export abstract class SolautoClient {
|
|
282
297
|
|
283
298
|
async fetchExistingAuthorityLutAccounts(): Promise<PublicKey[]> {
|
284
299
|
const lookupTable = this.authorityLutAddress
|
285
|
-
? await
|
300
|
+
? await this.connection.getAddressLookupTable(this.authorityLutAddress)
|
286
301
|
: null;
|
287
302
|
if (lookupTable === null) {
|
288
303
|
this.authorityLutAddress = undefined;
|
@@ -312,7 +327,7 @@ export abstract class SolautoClient {
|
|
312
327
|
AddressLookupTableProgram.createLookupTable({
|
313
328
|
authority: this.authority,
|
314
329
|
payer: toWeb3JsPublicKey(this.signer.publicKey),
|
315
|
-
recentSlot: await
|
330
|
+
recentSlot: await this.umi.rpc.getSlot({ commitment: "finalized" }),
|
316
331
|
});
|
317
332
|
this.authorityLutAddress = lookupTableAddress;
|
318
333
|
tx = tx.add(getWrappedInstruction(this.signer, createLookupTableInst));
|
@@ -626,55 +641,6 @@ export abstract class SolautoClient {
|
|
626
641
|
limitGapBps?: number
|
627
642
|
): TransactionBuilder;
|
628
643
|
|
629
|
-
async positionStateWithLatestPrices(): Promise<PositionState | undefined> {
|
630
|
-
if (!this.solautoPositionData) {
|
631
|
-
return undefined;
|
632
|
-
}
|
633
|
-
|
634
|
-
const state = this.solautoPositionState ?? this.solautoPositionData.state;
|
635
|
-
if (currentUnixSeconds() - Number(state.lastUpdated) > 60 * 60 * 24 * 7) {
|
636
|
-
return this.getFreshPositionState();
|
637
|
-
}
|
638
|
-
|
639
|
-
const [supplyPrice, debtPrice] = await getTokenPrices([
|
640
|
-
toWeb3JsPublicKey(state.supply.mint),
|
641
|
-
toWeb3JsPublicKey(state.debt.mint),
|
642
|
-
]);
|
643
|
-
|
644
|
-
const supplyUsd =
|
645
|
-
fromBaseUnit(state.supply.amountUsed.baseUnit, state.supply.decimals) *
|
646
|
-
supplyPrice;
|
647
|
-
const debtUsd =
|
648
|
-
fromBaseUnit(state.debt.amountUsed.baseUnit, state.debt.decimals) *
|
649
|
-
debtPrice;
|
650
|
-
return {
|
651
|
-
...state,
|
652
|
-
liqUtilizationRateBps: getLiqUtilzationRateBps(
|
653
|
-
supplyUsd,
|
654
|
-
debtUsd,
|
655
|
-
state.liqThresholdBps
|
656
|
-
),
|
657
|
-
netWorth: {
|
658
|
-
...state.netWorth,
|
659
|
-
baseAmountUsdValue: toBaseUnit(supplyUsd - debtUsd, USD_DECIMALS),
|
660
|
-
},
|
661
|
-
supply: {
|
662
|
-
...state.supply,
|
663
|
-
amountUsed: {
|
664
|
-
...state.supply.amountUsed,
|
665
|
-
baseAmountUsdValue: toBaseUnit(supplyUsd, USD_DECIMALS),
|
666
|
-
},
|
667
|
-
},
|
668
|
-
debt: {
|
669
|
-
...state.debt,
|
670
|
-
amountUsed: {
|
671
|
-
...state.debt.amountUsed,
|
672
|
-
baseAmountUsdValue: toBaseUnit(debtUsd, USD_DECIMALS),
|
673
|
-
},
|
674
|
-
},
|
675
|
-
};
|
676
|
-
}
|
677
|
-
|
678
644
|
async getFreshPositionState(): Promise<PositionState | undefined> {
|
679
645
|
if (
|
680
646
|
Boolean(this.solautoPositionState) &&
|
@@ -98,12 +98,12 @@ export class SolautoMarginfiClient extends SolautoClient {
|
|
98
98
|
public intermediaryMarginfiAccountPk!: PublicKey;
|
99
99
|
public intermediaryMarginfiAccount?: MarginfiAccount;
|
100
100
|
|
101
|
-
async initialize(args: SolautoMarginfiClientArgs) {
|
101
|
+
async initialize(args: SolautoMarginfiClientArgs, heliusApiKey: string) {
|
102
102
|
if (args.marginfiAccount) {
|
103
103
|
this.marginfiAccount = args.marginfiAccount;
|
104
104
|
}
|
105
105
|
|
106
|
-
await
|
106
|
+
await this.baseInitialize(args, LendingPlatform.Marginfi, heliusApiKey);
|
107
107
|
|
108
108
|
this.marginfiAccountSeedIdx = args.marginfiAccountSeedIdx;
|
109
109
|
this.marginfiAccount =
|
@@ -135,6 +135,7 @@ export class SolautoMarginfiClient extends SolautoClient {
|
|
135
135
|
})!;
|
136
136
|
|
137
137
|
const existingMarginfiAccounts = await getAllMarginfiAccountsByAuthority(
|
138
|
+
this.umi,
|
138
139
|
toWeb3JsPublicKey(this.signer.publicKey)
|
139
140
|
);
|
140
141
|
const emptyMarginfiAccounts = existingMarginfiAccounts.filter(
|
@@ -481,15 +482,11 @@ export class SolautoMarginfiClient extends SolautoClient {
|
|
481
482
|
return state;
|
482
483
|
}
|
483
484
|
|
484
|
-
const marginfiAccount = await safeFetchMarginfiAccount(
|
485
|
-
this.umi,
|
486
|
-
publicKey(this.marginfiAccountPk)
|
487
|
-
);
|
488
|
-
|
489
485
|
const freshState = await getMarginfiAccountPositionState(
|
486
|
+
this.umi,
|
490
487
|
this.supplyLiquidityMint,
|
491
488
|
this.debtLiquidityMint,
|
492
|
-
|
489
|
+
this.marginfiAccountPk,
|
493
490
|
this.livePositionUpdates
|
494
491
|
);
|
495
492
|
this.log(freshState);
|
@@ -12,7 +12,7 @@ import {
|
|
12
12
|
TOKEN_PROGRAM_ID,
|
13
13
|
} from "@solana/spl-token";
|
14
14
|
// import { JitoRpcConnection } from "jito-ts";
|
15
|
-
import {
|
15
|
+
import { SOLAUTO_PROGRAM_ID } from "../generated";
|
16
16
|
import { SOLAUTO_MANAGER } from "./generalAccounts";
|
17
17
|
|
18
18
|
export const DEFAULT_RISK_AVERSION_BPS = 1500;
|
@@ -20,21 +20,11 @@ export const DEFAULT_LIMIT_GAP_BPS = 1000;
|
|
20
20
|
export const MIN_POSITION_STATE_FRESHNESS_SECS = 5;
|
21
21
|
export const MAX_REPAY_GAP_BPS = 100;
|
22
22
|
|
23
|
-
export const CONNECTION = new Connection(
|
24
|
-
`https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`,
|
25
|
-
"finalized"
|
26
|
-
);
|
27
|
-
|
28
23
|
// export const JITO_BLOCK_ENGINE = "ny.mainnet.block-engine.jito.wtf";
|
29
24
|
// export const JITO_CONNECTION = new JitoRpcConnection(
|
30
25
|
// `https://${JITO_BLOCK_ENGINE}`,
|
31
26
|
// "finalized"
|
32
27
|
// );
|
33
|
-
export const UMI = createUmi(CONNECTION).use({
|
34
|
-
install(umi) {
|
35
|
-
umi.programs.add(createSolautoProgram(), false);
|
36
|
-
},
|
37
|
-
});
|
38
28
|
|
39
29
|
export const PRICES: { [key: string]: { price: number; time: number; } } = {};
|
40
30
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import {
|
2
2
|
Signer,
|
3
3
|
TransactionBuilder,
|
4
|
+
Umi,
|
4
5
|
publicKey,
|
5
6
|
transactionBuilder,
|
6
7
|
} from "@metaplex-foundation/umi";
|
@@ -39,7 +40,6 @@ import {
|
|
39
40
|
rpcAccountCreated,
|
40
41
|
} from "../utils/generalUtils";
|
41
42
|
import { SolautoMarginfiClient } from "../clients/solautoMarginfiClient";
|
42
|
-
import { UMI } from "../constants/solautoConstants";
|
43
43
|
import { uint8ArrayToBigInt } from "../utils/numberUtils";
|
44
44
|
import {
|
45
45
|
eligibileForRebalance,
|
@@ -121,7 +121,7 @@ async function transactionChoresBefore(
|
|
121
121
|
undefined
|
122
122
|
);
|
123
123
|
if (wSolUsage !== undefined) {
|
124
|
-
if (!getSolanaAccountCreated(wSolUsage.wSolTokenAccount)) {
|
124
|
+
if (!getSolanaAccountCreated(client.umi, wSolUsage.wSolTokenAccount)) {
|
125
125
|
client.log(`Closing signer wSol TA`);
|
126
126
|
chores = chores.add(
|
127
127
|
closeTokenAccountUmiIx(
|
@@ -150,7 +150,7 @@ async function transactionChoresBefore(
|
|
150
150
|
if (amountToTransfer > 0) {
|
151
151
|
const amount =
|
152
152
|
amountToTransfer +
|
153
|
-
(await
|
153
|
+
(await client.umi.rpc.getRent(TOKEN_ACCOUNT_SIZE)).basisPoints;
|
154
154
|
client.log(`Transferring ${amount} lamports to signer wSol TA`);
|
155
155
|
chores = chores.add(
|
156
156
|
systemTransferUmiIx(client.signer, wSolUsage.wSolTokenAccount, amount)
|
@@ -183,7 +183,7 @@ async function transactionChoresBefore(
|
|
183
183
|
continue;
|
184
184
|
}
|
185
185
|
|
186
|
-
if (!getSolanaAccountCreated(tokenAccount)) {
|
186
|
+
if (!getSolanaAccountCreated(client.umi, tokenAccount)) {
|
187
187
|
chores = chores.add(
|
188
188
|
createAssociatedTokenAccountUmiIx(
|
189
189
|
client.signer,
|
@@ -229,7 +229,7 @@ export async function rebalanceChoresBefore(
|
|
229
229
|
];
|
230
230
|
|
231
231
|
const [referredBySupplyTa, solautoFeesSupplyTa, intermediaryMarginfiAccount] =
|
232
|
-
await
|
232
|
+
await client.umi.rpc.getAccounts(
|
233
233
|
accountsNeeded.map((x) => publicKey(x ?? PublicKey.default))
|
234
234
|
);
|
235
235
|
|
@@ -482,12 +482,12 @@ export async function buildSolautoRebalanceTransaction(
|
|
482
482
|
}
|
483
483
|
|
484
484
|
export async function convertReferralFeesToDestination(
|
485
|
+
umi: Umi,
|
485
486
|
referralState: ReferralState,
|
486
487
|
tokenAccount: SplTokenAccount,
|
487
|
-
signer: Signer
|
488
488
|
): Promise<[TransactionBuilder, string[]]> {
|
489
489
|
const { lookupTableAddresses, setupInstructions, swapIx } =
|
490
|
-
await getJupSwapTransaction(
|
490
|
+
await getJupSwapTransaction(umi.identity, {
|
491
491
|
amount: tokenAccount.amount,
|
492
492
|
destinationWallet: toWeb3JsPublicKey(referralState.publicKey),
|
493
493
|
inputMint: tokenAccount.mint,
|
@@ -499,12 +499,12 @@ export async function convertReferralFeesToDestination(
|
|
499
499
|
let tx = transactionBuilder()
|
500
500
|
.add(setupInstructions)
|
501
501
|
.add(
|
502
|
-
convertReferralFees(
|
503
|
-
signer,
|
502
|
+
convertReferralFees(umi, {
|
503
|
+
signer: umi.identity,
|
504
504
|
intermediaryTa: publicKey(
|
505
505
|
getTokenAccount(
|
506
|
-
toWeb3JsPublicKey(
|
507
|
-
|
506
|
+
toWeb3JsPublicKey(umi.identity.publicKey),
|
507
|
+
tokenAccount.mint
|
508
508
|
)
|
509
509
|
),
|
510
510
|
ixsSysvar: publicKey(SYSVAR_INSTRUCTIONS_PUBKEY),
|
@@ -9,7 +9,6 @@ import {
|
|
9
9
|
getAdressLookupInputs,
|
10
10
|
sendSingleOptimizedTransaction,
|
11
11
|
} from "../utils/solanaUtils";
|
12
|
-
import { UMI } from "../constants/solautoConstants";
|
13
12
|
import { retryWithExponentialBackoff } from "../utils/generalUtils";
|
14
13
|
import { getTransactionChores } from "./transactionUtils";
|
15
14
|
// import { sendJitoBundledTransactions } from "../utils/jitoUtils";
|
@@ -35,7 +34,10 @@ class LookupTables {
|
|
35
34
|
(x) => !currentCacheAddresses.includes(x)
|
36
35
|
);
|
37
36
|
if (missingAddresses) {
|
38
|
-
const additionalInputs = await getAdressLookupInputs(
|
37
|
+
const additionalInputs = await getAdressLookupInputs(
|
38
|
+
this.client.umi,
|
39
|
+
missingAddresses
|
40
|
+
);
|
39
41
|
this.cache.push(...additionalInputs);
|
40
42
|
}
|
41
43
|
|
@@ -110,7 +112,7 @@ class TransactionSet {
|
|
110
112
|
...item.lookupTableAddresses,
|
111
113
|
])
|
112
114
|
)
|
113
|
-
.fitsInOneTransaction(
|
115
|
+
.fitsInOneTransaction(this.client.umi);
|
114
116
|
}
|
115
117
|
|
116
118
|
add(...items: TransactionItem[]) {
|
@@ -202,9 +204,9 @@ export class TransactionsManager {
|
|
202
204
|
const transaction = item.tx.setAddressLookupTables(
|
203
205
|
await this.lookupTables.getLutInputs(item.lookupTableAddresses)
|
204
206
|
);
|
205
|
-
if (!transaction.fitsInOneTransaction(
|
207
|
+
if (!transaction.fitsInOneTransaction(this.client.umi)) {
|
206
208
|
throw new Error(
|
207
|
-
`Transaction exceeds max transaction size (${transaction.getTransactionSize(
|
209
|
+
`Transaction exceeds max transaction size (${transaction.getTransactionSize(this.client.umi)})`
|
208
210
|
);
|
209
211
|
} else {
|
210
212
|
let newSet = new TransactionSet(this.client, this.lookupTables, [item]);
|
@@ -246,7 +248,8 @@ export class TransactionsManager {
|
|
246
248
|
await retryWithExponentialBackoff(
|
247
249
|
async (attemptNum) =>
|
248
250
|
await sendSingleOptimizedTransaction(
|
249
|
-
this.client,
|
251
|
+
this.client.umi,
|
252
|
+
this.client.connection,
|
250
253
|
updateLookupTable.updateLutTx,
|
251
254
|
this.simulateOnly,
|
252
255
|
attemptNum
|
@@ -353,7 +356,8 @@ export class TransactionsManager {
|
|
353
356
|
} else {
|
354
357
|
this.updateStatus(itemSet.name(), TransactionStatus.Processing);
|
355
358
|
const txSig = await sendSingleOptimizedTransaction(
|
356
|
-
this.client,
|
359
|
+
this.client.umi,
|
360
|
+
this.client.connection,
|
357
361
|
tx,
|
358
362
|
this.simulateOnly,
|
359
363
|
attemptNum
|