@haven-fi/solauto-sdk 1.0.32 → 1.0.33
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/solautoMarginfiClient.d.ts +3 -3
- package/dist/clients/solautoMarginfiClient.d.ts.map +1 -1
- package/dist/clients/solautoMarginfiClient.js +29 -28
- package/dist/transactions/transactionUtils.d.ts.map +1 -1
- package/dist/transactions/transactionUtils.js +44 -9
- package/dist/utils/deleteme.js +1 -1
- package/dist/utils/marginfiUtils.d.ts +1 -1
- package/dist/utils/marginfiUtils.d.ts.map +1 -1
- package/dist/utils/marginfiUtils.js +30 -21
- package/dist/utils/solauto/generalUtils.d.ts.map +1 -1
- package/dist/utils/solauto/generalUtils.js +3 -0
- package/package.json +1 -1
- package/src/clients/solautoMarginfiClient.ts +39 -52
- package/src/transactions/transactionUtils.ts +65 -13
- package/src/utils/deleteme.ts +2 -2
- package/src/utils/marginfiUtils.ts +40 -29
- package/src/utils/solauto/generalUtils.ts +4 -0
- package/tests/transactions/solautoMarginfi.ts +0 -8
- package/tests/unit/rebalanceCalculations.ts +20 -23
|
@@ -6,16 +6,15 @@ import { DCASettingsInpArgs, PositionState, SolautoActionArgs, SolautoRebalanceT
|
|
|
6
6
|
import { MarginfiAccount } from "../marginfi-sdk";
|
|
7
7
|
import { JupSwapDetails } from "../utils/jupiterUtils";
|
|
8
8
|
import { FlashLoanDetails } from "../utils/solauto/rebalanceUtils";
|
|
9
|
-
import { WalletAdapter } from "@metaplex-foundation/umi-signer-wallet-adapters";
|
|
10
9
|
export interface SolautoMarginfiClientArgs extends SolautoClientArgs {
|
|
11
10
|
marginfiAccount?: PublicKey | Signer;
|
|
12
11
|
marginfiAccountSeedIdx?: bigint;
|
|
13
12
|
marginfiGroup?: PublicKey;
|
|
14
13
|
}
|
|
15
|
-
export declare function newSolautoMarginfiPositionArgs(positionId: number, signer: Signer | undefined, wallet: WalletAdapter | undefined, supplyMint: PublicKey, debtMint: PublicKey, referredByAuthority?: PublicKey): SolautoMarginfiClientArgs;
|
|
16
14
|
export declare class SolautoMarginfiClient extends SolautoClient {
|
|
15
|
+
private initialized;
|
|
17
16
|
marginfiProgram: PublicKey;
|
|
18
|
-
marginfiAccountSeedIdx
|
|
17
|
+
marginfiAccountSeedIdx: bigint;
|
|
19
18
|
marginfiAccount: PublicKey | Signer;
|
|
20
19
|
marginfiAccountPk: PublicKey;
|
|
21
20
|
marginfiGroup: PublicKey;
|
|
@@ -25,6 +24,7 @@ export declare class SolautoMarginfiClient extends SolautoClient {
|
|
|
25
24
|
intermediaryMarginfiAccountPk: PublicKey;
|
|
26
25
|
intermediaryMarginfiAccount?: MarginfiAccount;
|
|
27
26
|
initialize(args: SolautoMarginfiClientArgs): Promise<void>;
|
|
27
|
+
setIntermediaryMarginfiDetails(): Promise<void>;
|
|
28
28
|
defaultLookupTables(): string[];
|
|
29
29
|
lutAccountsToAdd(): PublicKey[];
|
|
30
30
|
marginfiAccountInitialize(): TransactionBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solautoMarginfiClient.d.ts","sourceRoot":"","sources":["../../src/clients/solautoMarginfiClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"solautoMarginfiClient.d.ts","sourceRoot":"","sources":["../../src/clients/solautoMarginfiClient.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,MAAM,EACN,kBAAkB,EAMnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EAEV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAK1D,OAAO,EACL,kBAAkB,EAElB,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,gCAAgC,EAKjC,MAAM,cAAc,CAAC;AAGtB,OAAO,EAEL,eAAe,EAUhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAQnE,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,eAAe,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,OAAO,CAAC,WAAW,CAAkB;IAE9B,eAAe,EAAG,SAAS,CAAC;IAE5B,sBAAsB,EAAE,MAAM,CAAa;IAC3C,eAAe,EAAG,SAAS,GAAG,MAAM,CAAC;IACrC,iBAAiB,EAAG,SAAS,CAAC;IAC9B,aAAa,EAAG,SAAS,CAAC;IAE1B,0BAA0B,EAAG,qBAAqB,CAAC;IACnD,wBAAwB,EAAG,qBAAqB,CAAC;IAGjD,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,6BAA6B,EAAG,SAAS,CAAC;IAC1C,2BAA2B,CAAC,EAAE,eAAe,CAAC;IAE/C,UAAU,CAAC,IAAI,EAAE,yBAAyB;IA0C1C,8BAA8B;IAsCpC,mBAAmB,IAAI,MAAM,EAAE;IAI/B,gBAAgB,IAAI,SAAS,EAAE;IAQ/B,yBAAyB,IAAI,kBAAkB;IAS/C,YAAY,CACV,aAAa,CAAC,EAAE,gCAAgC,EAChD,GAAG,CAAC,EAAE,kBAAkB,GACvB,kBAAkB;IAMrB,OAAO,CAAC,sBAAsB;IA2C9B,OAAO,IAAI,kBAAkB;IAc7B,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,kBAAkB;IAUhE,OAAO,CAAC,6BAA6B;IAoErC,OAAO,CAAC,oCAAoC;IA8D5C,SAAS,CACP,aAAa,EAAE,GAAG,GAAG,GAAG,EACxB,WAAW,EAAE,cAAc,EAC3B,aAAa,EAAE,wBAAwB,EACvC,2BAA2B,CAAC,EAAE,MAAM,EACpC,WAAW,CAAC,EAAE,MAAM,GACnB,kBAAkB;IAgDrB,WAAW,CACT,gBAAgB,EAAE,gBAAgB,EAClC,uBAAuB,EAAE,SAAS,GACjC,kBAAkB;IA2BrB,UAAU,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,kBAAkB;IA8ElE,iCAAiC,IAAI,kBAAkB;IASjD,qBAAqB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAiBlE"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SolautoMarginfiClient =
|
|
3
|
+
exports.SolautoMarginfiClient = void 0;
|
|
4
4
|
const umi_web3js_adapters_1 = require("@metaplex-foundation/umi-web3js-adapters");
|
|
5
5
|
const umi_1 = require("@metaplex-foundation/umi");
|
|
6
|
-
const umi_bundle_defaults_1 = require("@metaplex-foundation/umi-bundle-defaults");
|
|
7
6
|
const web3_js_1 = require("@solana/web3.js");
|
|
8
7
|
const solautoClient_1 = require("./solautoClient");
|
|
9
8
|
const marginfiAccounts_1 = require("../constants/marginfiAccounts");
|
|
@@ -13,31 +12,25 @@ const generalUtils_1 = require("../utils/generalUtils");
|
|
|
13
12
|
const marginfi_sdk_1 = require("../marginfi-sdk");
|
|
14
13
|
const marginfiUtils_1 = require("../utils/marginfiUtils");
|
|
15
14
|
const numberUtils_1 = require("../utils/numberUtils");
|
|
16
|
-
function newSolautoMarginfiPositionArgs(positionId, signer, wallet, supplyMint, debtMint, referredByAuthority) {
|
|
17
|
-
const umi = (0, umi_bundle_defaults_1.createUmi)((0, web3_js_1.clusterApiUrl)("mainnet-beta"));
|
|
18
|
-
return {
|
|
19
|
-
positionId,
|
|
20
|
-
signer,
|
|
21
|
-
wallet,
|
|
22
|
-
marginfiAccount: positionId === 0
|
|
23
|
-
? (0, umi_1.createSignerFromKeypair)(umi, umi.eddsa.generateKeypair())
|
|
24
|
-
: undefined,
|
|
25
|
-
marginfiAccountSeedIdx: positionId > 0 ? (0, generalUtils_1.generateRandomU64)() : undefined,
|
|
26
|
-
supplyMint: supplyMint,
|
|
27
|
-
debtMint: debtMint,
|
|
28
|
-
referredByAuthority,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
exports.newSolautoMarginfiPositionArgs = newSolautoMarginfiPositionArgs;
|
|
32
15
|
class SolautoMarginfiClient extends solautoClient_1.SolautoClient {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.initialized = false;
|
|
19
|
+
this.marginfiAccountSeedIdx = BigInt(0);
|
|
20
|
+
}
|
|
33
21
|
async initialize(args) {
|
|
34
22
|
await super.initialize(args, generated_1.LendingPlatform.Marginfi);
|
|
35
|
-
this.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
23
|
+
if (this.selfManaged) {
|
|
24
|
+
this.marginfiAccount =
|
|
25
|
+
args.marginfiAccount ??
|
|
26
|
+
(0, umi_1.createSignerFromKeypair)(this.umi, this.umi.eddsa.generateKeypair());
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.marginfiAccountSeedIdx = (0, generalUtils_1.generateRandomU64)();
|
|
30
|
+
this.marginfiAccount = this.solautoPositionData
|
|
31
|
+
? (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.solautoPositionData.position.protocolAccount)
|
|
32
|
+
: await (0, accountUtils_1.getMarginfiAccountPDA)(this.solautoPosition, this.marginfiAccountSeedIdx);
|
|
33
|
+
}
|
|
41
34
|
this.marginfiAccountPk =
|
|
42
35
|
"publicKey" in this.marginfiAccount
|
|
43
36
|
? (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.marginfiAccount.publicKey)
|
|
@@ -52,10 +45,18 @@ class SolautoMarginfiClient extends solautoClient_1.SolautoClient {
|
|
|
52
45
|
this.marginfiDebtBankAccounts = (0, marginfiUtils_1.findMarginfiBankAccounts)({
|
|
53
46
|
mint: this.debtMint.toString(),
|
|
54
47
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
if (!this.initialized) {
|
|
49
|
+
await this.setIntermediaryMarginfiDetails();
|
|
50
|
+
}
|
|
51
|
+
this.initialized = true;
|
|
52
|
+
}
|
|
53
|
+
async setIntermediaryMarginfiDetails() {
|
|
54
|
+
const existingMarginfiAccounts = (await (0, marginfiUtils_1.getAllMarginfiAccountsByAuthority)(this.umi, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(this.signer.publicKey), false)).filter((x) => !x.marginfiAccount.equals(this.marginfiAccountPk));
|
|
55
|
+
const emptyMarginfiAccounts = existingMarginfiAccounts.length > 0
|
|
56
|
+
? (await (0, marginfi_sdk_1.safeFetchAllMarginfiAccount)(this.umi, existingMarginfiAccounts.map((x) => (0, umi_1.publicKey)(x.marginfiAccount)))).filter((x) => x.lendingAccount.balances.find((y) => y.bankPk.toString() !== web3_js_1.PublicKey.default.toString() &&
|
|
57
|
+
(Math.round((0, numberUtils_1.bytesToI80F48)(y.assetShares.value)) != 0 ||
|
|
58
|
+
Math.round((0, numberUtils_1.bytesToI80F48)(y.liabilityShares.value)) != 0)) === undefined)
|
|
59
|
+
: [];
|
|
59
60
|
this.intermediaryMarginfiAccountSigner =
|
|
60
61
|
emptyMarginfiAccounts.length > 0
|
|
61
62
|
? undefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,EAClB,GAAG,EAGJ,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAGL,OAAO,IAAI,eAAe,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,aAAa,EASd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAqMzD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA8F7B;AAmLD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CA0BnD;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CACN;IACE,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GACD,SAAS,CACZ,CA4GA;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CA8BzC"}
|
|
@@ -112,13 +112,18 @@ async function transactionChoresBefore(client, solautoActions, initiatingDcaIn)
|
|
|
112
112
|
return chores;
|
|
113
113
|
}
|
|
114
114
|
async function rebalanceChoresBefore(client, tx) {
|
|
115
|
-
const
|
|
116
|
-
|
|
115
|
+
const rebalanceInstructions = getRebalanceInstructions(tx);
|
|
116
|
+
if (rebalanceInstructions.length === 0) {
|
|
117
|
+
return (0, umi_1.transactionBuilder)();
|
|
118
|
+
}
|
|
119
|
+
const usesAccount = (key) => rebalanceInstructions
|
|
117
120
|
.some((t) => t.keys.some((k) => (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(k.pubkey).equals(key)));
|
|
118
121
|
const checkReferralSupplyTa = client.referredBySupplyTa && usesAccount(client.referredBySupplyTa);
|
|
119
122
|
const checkSolautoFeesTa = usesAccount(client.solautoFeesSupplyTa);
|
|
120
123
|
const checkIntermediaryMfiAccount = client.lendingPlatform === generated_1.LendingPlatform.Marginfi &&
|
|
121
124
|
usesAccount(client.intermediaryMarginfiAccountPk);
|
|
125
|
+
const checkSignerSupplyTa = client.selfManaged && usesAccount(client.signerSupplyTa);
|
|
126
|
+
const checkSignerDebtTa = client.selfManaged && usesAccount(client.signerSupplyTa);
|
|
122
127
|
const accountsNeeded = [
|
|
123
128
|
...[checkReferralSupplyTa ? client.referredBySupplyTa : web3_js_1.PublicKey.default],
|
|
124
129
|
...[checkSolautoFeesTa ? client.solautoFeesSupplyTa : web3_js_1.PublicKey.default],
|
|
@@ -127,8 +132,10 @@ async function rebalanceChoresBefore(client, tx) {
|
|
|
127
132
|
? client.intermediaryMarginfiAccountPk
|
|
128
133
|
: web3_js_1.PublicKey.default,
|
|
129
134
|
],
|
|
135
|
+
...[checkSignerSupplyTa ? client.signerSupplyTa : web3_js_1.PublicKey.default],
|
|
136
|
+
...[checkSignerDebtTa ? client.signerDebtTa : web3_js_1.PublicKey.default],
|
|
130
137
|
];
|
|
131
|
-
const [referredBySupplyTa, solautoFeesSupplyTa, intermediaryMarginfiAccount] = await client.umi.rpc.getAccounts(accountsNeeded.map((x) => (0, umi_1.publicKey)(x ?? web3_js_1.PublicKey.default)));
|
|
138
|
+
const [referredBySupplyTa, solautoFeesSupplyTa, intermediaryMarginfiAccount, signerSupplyTa, signerDebtTa] = await client.umi.rpc.getAccounts(accountsNeeded.map((x) => (0, umi_1.publicKey)(x ?? web3_js_1.PublicKey.default)));
|
|
132
139
|
let chores = (0, umi_1.transactionBuilder)();
|
|
133
140
|
if (checkReferralSupplyTa && !(0, generalUtils_1.rpcAccountCreated)(referredBySupplyTa)) {
|
|
134
141
|
client.log("Creating referred-by TA for ", client.supplyMint.toString());
|
|
@@ -142,6 +149,14 @@ async function rebalanceChoresBefore(client, tx) {
|
|
|
142
149
|
!(0, generalUtils_1.rpcAccountCreated)(intermediaryMarginfiAccount)) {
|
|
143
150
|
chores = chores.add(client.createIntermediaryMarginfiAccount());
|
|
144
151
|
}
|
|
152
|
+
if (checkSignerSupplyTa && !(0, generalUtils_1.rpcAccountCreated)(signerSupplyTa)) {
|
|
153
|
+
client.log("Creating signer supply token account");
|
|
154
|
+
chores = chores.add((0, solanaUtils_1.createAssociatedTokenAccountUmiIx)(client.signer, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(client.signer.publicKey), client.supplyMint));
|
|
155
|
+
}
|
|
156
|
+
if (checkSignerDebtTa && !(0, generalUtils_1.rpcAccountCreated)(signerDebtTa)) {
|
|
157
|
+
client.log("Creating signer debt token account");
|
|
158
|
+
chores = chores.add((0, solanaUtils_1.createAssociatedTokenAccountUmiIx)(client.signer, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(client.signer.publicKey), client.debtMint));
|
|
159
|
+
}
|
|
145
160
|
return chores;
|
|
146
161
|
}
|
|
147
162
|
exports.rebalanceChoresBefore = rebalanceChoresBefore;
|
|
@@ -153,6 +168,26 @@ function transactionChoresAfter(client, solautoActions, cancellingDcaIn) {
|
|
|
153
168
|
}
|
|
154
169
|
return chores;
|
|
155
170
|
}
|
|
171
|
+
function getRebalanceInstructions(tx) {
|
|
172
|
+
return tx.getInstructions().filter((x) => {
|
|
173
|
+
if (x.programId === generated_1.SOLAUTO_PROGRAM_ID) {
|
|
174
|
+
try {
|
|
175
|
+
const serializer = (0, generated_1.getMarginfiRebalanceInstructionDataSerializer)();
|
|
176
|
+
const discriminator = serializer.serialize({
|
|
177
|
+
limitGapBps: 0,
|
|
178
|
+
rebalanceType: generated_1.SolautoRebalanceType.None,
|
|
179
|
+
targetLiqUtilizationRateBps: 0
|
|
180
|
+
})[0];
|
|
181
|
+
const [data, _] = serializer.deserialize(x.data);
|
|
182
|
+
if (data.discriminator === discriminator) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch { }
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
156
191
|
function getSolautoActions(tx) {
|
|
157
192
|
let solautoActions = [];
|
|
158
193
|
tx.getInstructions().forEach((x) => {
|
|
@@ -162,8 +197,7 @@ function getSolautoActions(tx) {
|
|
|
162
197
|
const discriminator = serializer
|
|
163
198
|
.serialize({
|
|
164
199
|
solautoAction: (0, generated_1.solautoAction)("Deposit", [BigInt(0)]),
|
|
165
|
-
})
|
|
166
|
-
.slice(0, 1)[0];
|
|
200
|
+
})[0];
|
|
167
201
|
const [data, _] = serializer.deserialize(x.data);
|
|
168
202
|
if (data.discriminator === discriminator) {
|
|
169
203
|
solautoActions?.push(data.solautoAction);
|
|
@@ -281,10 +315,11 @@ async function getTransactionChores(client, tx) {
|
|
|
281
315
|
exports.getTransactionChores = getTransactionChores;
|
|
282
316
|
async function buildSolautoRebalanceTransaction(client, targetLiqUtilizationRateBps, attemptNum) {
|
|
283
317
|
client.solautoPositionState = await client.getFreshPositionState();
|
|
284
|
-
if (
|
|
285
|
-
|
|
286
|
-
client.
|
|
287
|
-
|
|
318
|
+
if (client.solautoPositionState?.supply.amountUsed.baseUnit === BigInt(0) ||
|
|
319
|
+
(targetLiqUtilizationRateBps === undefined &&
|
|
320
|
+
!(0, generalUtils_2.eligibileForRebalance)(client.solautoPositionState, client.livePositionUpdates.settings ??
|
|
321
|
+
client.solautoPositionData?.position.settingParams, client.livePositionUpdates.activeDca ??
|
|
322
|
+
client.solautoPositionData?.position.dca))) {
|
|
288
323
|
client.log("Not eligible for a rebalance");
|
|
289
324
|
return undefined;
|
|
290
325
|
}
|
package/dist/utils/deleteme.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const numberUtils_1 = require("./numberUtils");
|
|
4
4
|
// TODO delete this file
|
|
5
|
-
function check() {
|
|
5
|
+
async function check() {
|
|
6
6
|
let supply = 458948;
|
|
7
7
|
let debt = 212846;
|
|
8
8
|
let supply_weight = 0.899999976158142;
|
|
@@ -8,7 +8,7 @@ export declare function findMarginfiBankAccounts({ mint, bank, }: {
|
|
|
8
8
|
mint?: string;
|
|
9
9
|
bank?: string;
|
|
10
10
|
}): MarginfiTokenAccounts;
|
|
11
|
-
export declare function getMaxLtvAndLiqThreshold(supplyBank: Bank, debtBank: Bank, supplyPrice?: number): Promise<[number, number]>;
|
|
11
|
+
export declare function getMaxLtvAndLiqThreshold(supplyBank: Bank, debtBank: Bank | null, supplyPrice?: number): Promise<[number, number]>;
|
|
12
12
|
export declare function getAllMarginfiAccountsByAuthority(umi: Umi, authority: PublicKey, compatibleWithSolauto?: boolean): Promise<{
|
|
13
13
|
marginfiAccount: PublicKey;
|
|
14
14
|
supplyMint?: PublicKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marginfiUtils.d.ts","sourceRoot":"","sources":["../../src/utils/marginfiUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAa,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACL,IAAI,EAKL,MAAM,iBAAiB,CAAC;AAUzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,wBAAgB,wBAAwB,CAAC,EACvC,IAAI,EACJ,IAAI,GACL,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,qBAAqB,CAWxB;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,IAAI,EAChB,QAAQ,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"marginfiUtils.d.ts","sourceRoot":"","sources":["../../src/utils/marginfiUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAa,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACL,IAAI,EAKL,MAAM,iBAAiB,CAAC;AAUzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,wBAAgB,wBAAwB,CAAC,EACvC,IAAI,EACJ,IAAI,GACL,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,qBAAqB,CAWxB;AAED,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,IAAI,EAChB,QAAQ,EAAE,IAAI,GAAG,IAAI,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsC3B;AAED,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,SAAS,EACpB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CACR;IAAE,eAAe,EAAE,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,EAAE,CAC/E,CA8CA;AA0DD,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,GAAG,EACR,iBAAiB,EAAE,SAAS,EAC5B,UAAU,CAAC,EAAE,SAAS,EACtB,QAAQ,CAAC,EAAE,SAAS,EACpB,mBAAmB,CAAC,EAAE,mBAAmB,GACxC,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CA4IpC;AA+DD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA0B3B"}
|
|
@@ -29,6 +29,9 @@ async function getMaxLtvAndLiqThreshold(supplyBank, debtBank, supplyPrice) {
|
|
|
29
29
|
const [price] = await (0, generalUtils_1.getTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(supplyBank.mint)]);
|
|
30
30
|
supplyPrice = price;
|
|
31
31
|
}
|
|
32
|
+
if (debtBank === null) {
|
|
33
|
+
return [0, 0];
|
|
34
|
+
}
|
|
32
35
|
let maxLtv = (0, numberUtils_1.bytesToI80F48)(supplyBank.config.assetWeightInit.value) /
|
|
33
36
|
(0, numberUtils_1.bytesToI80F48)(debtBank.config.liabilityWeightInit.value);
|
|
34
37
|
const liqThreshold = (0, numberUtils_1.bytesToI80F48)(supplyBank.config.assetWeightMaint.value) /
|
|
@@ -64,6 +67,7 @@ async function getAllMarginfiAccountsByAuthority(umi, authority, compatibleWithS
|
|
|
64
67
|
],
|
|
65
68
|
});
|
|
66
69
|
if (compatibleWithSolauto) {
|
|
70
|
+
console.log(marginfiAccounts);
|
|
67
71
|
const positionStates = await Promise.all(marginfiAccounts.map(async (x) => ({
|
|
68
72
|
publicKey: x.publicKey,
|
|
69
73
|
state: await getMarginfiAccountPositionState(umi, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(x.publicKey)),
|
|
@@ -84,27 +88,32 @@ async function getAllMarginfiAccountsByAuthority(umi, authority, compatibleWithS
|
|
|
84
88
|
}
|
|
85
89
|
exports.getAllMarginfiAccountsByAuthority = getAllMarginfiAccountsByAuthority;
|
|
86
90
|
async function getTokenUsage(umi, bank, isAsset, shares, amountUsedAdjustment) {
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
?
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
let amountUsed = 0;
|
|
92
|
+
let amountCanBeUsed = 0;
|
|
93
|
+
let marketPrice = 0;
|
|
94
|
+
if (bank !== null) {
|
|
95
|
+
[marketPrice] = await (0, generalUtils_1.getTokenPrices)([(0, umi_web3js_adapters_1.toWeb3JsPublicKey)(bank.mint)]);
|
|
96
|
+
const [assetShareValue, liabilityShareValue] = await getUpToDateShareValues(umi, bank);
|
|
97
|
+
const shareValue = isAsset ? assetShareValue : liabilityShareValue;
|
|
98
|
+
amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0);
|
|
99
|
+
const totalDeposited = (0, numberUtils_1.bytesToI80F48)(bank.totalAssetShares.value) * assetShareValue;
|
|
100
|
+
amountCanBeUsed = isAsset
|
|
101
|
+
? Number(bank.config.depositLimit) - totalDeposited
|
|
102
|
+
: totalDeposited -
|
|
103
|
+
(0, numberUtils_1.bytesToI80F48)(bank.totalLiabilityShares.value) * liabilityShareValue;
|
|
104
|
+
}
|
|
96
105
|
return {
|
|
97
|
-
mint: bank
|
|
98
|
-
decimals: bank
|
|
106
|
+
mint: bank?.mint ?? (0, umi_1.publicKey)(web3_js_1.PublicKey.default),
|
|
107
|
+
decimals: bank?.mintDecimals ?? 0,
|
|
99
108
|
amountUsed: {
|
|
100
109
|
baseUnit: BigInt(Math.round(amountUsed)),
|
|
101
|
-
baseAmountUsdValue: (0, numberUtils_1.toBaseUnit)((0, numberUtils_1.fromBaseUnit)(BigInt(Math.round(amountUsed)), bank.mintDecimals) *
|
|
102
|
-
marketPrice, generalAccounts_1.USD_DECIMALS),
|
|
110
|
+
baseAmountUsdValue: bank ? (0, numberUtils_1.toBaseUnit)((0, numberUtils_1.fromBaseUnit)(BigInt(Math.round(amountUsed)), bank.mintDecimals) *
|
|
111
|
+
marketPrice, generalAccounts_1.USD_DECIMALS) : BigInt(0),
|
|
103
112
|
},
|
|
104
113
|
amountCanBeUsed: {
|
|
105
|
-
baseUnit: BigInt(Math.round(
|
|
106
|
-
baseAmountUsdValue: (0, numberUtils_1.toBaseUnit)((0, numberUtils_1.fromBaseUnit)(BigInt(Math.round(
|
|
107
|
-
marketPrice, generalAccounts_1.USD_DECIMALS),
|
|
114
|
+
baseUnit: BigInt(Math.round(amountCanBeUsed)),
|
|
115
|
+
baseAmountUsdValue: bank ? (0, numberUtils_1.toBaseUnit)((0, numberUtils_1.fromBaseUnit)(BigInt(Math.round(amountCanBeUsed)), bank.mintDecimals) *
|
|
116
|
+
marketPrice, generalAccounts_1.USD_DECIMALS) : BigInt(0),
|
|
108
117
|
},
|
|
109
118
|
baseAmountMarketPriceUsd: (0, numberUtils_1.toBaseUnit)(marketPrice, generalAccounts_1.USD_DECIMALS),
|
|
110
119
|
flashLoanFeeBps: 0,
|
|
@@ -151,15 +160,15 @@ async function getMarginfiAccountPositionState(umi, marginfiAccountPk, supplyMin
|
|
|
151
160
|
debtUsage = await getTokenUsage(umi, debtBank, false, (0, numberUtils_1.bytesToI80F48)(debtBalances[0].liabilityShares.value), livePositionUpdates?.debtAdjustment);
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
|
-
if (supplyBank
|
|
163
|
+
if (supplyBank === null) {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
if (!supplyUsage) {
|
|
155
167
|
supplyUsage = await getTokenUsage(umi, supplyBank, true, 0, livePositionUpdates?.supplyAdjustment);
|
|
156
168
|
}
|
|
157
|
-
if (
|
|
169
|
+
if (!debtUsage) {
|
|
158
170
|
debtUsage = await getTokenUsage(umi, debtBank, false, 0, livePositionUpdates?.debtAdjustment);
|
|
159
171
|
}
|
|
160
|
-
if (supplyBank === null || debtBank === null) {
|
|
161
|
-
return undefined;
|
|
162
|
-
}
|
|
163
172
|
const supplyPrice = solautoConstants_1.PRICES[supplyMint.toString()].price;
|
|
164
173
|
let [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold(supplyBank, debtBank, supplyPrice);
|
|
165
174
|
const supplyUsd = (0, numberUtils_1.fromBaseUnit)(supplyUsage.amountUsed.baseAmountUsdValue, generalAccounts_1.USD_DECIMALS);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAoB,GAAG,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,aAAa,EAEb,yBAAyB,EACzB,gCAAgC,EAIjC,MAAM,iBAAiB,CAAC;AAczB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAgB7D,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,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,yBAAyB,EAC3C,WAAW,EAAE,WAAW,GACvB,OAAO,
|
|
1
|
+
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAoB,GAAG,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,eAAe,EACf,aAAa,EAEb,yBAAyB,EACzB,gCAAgC,EAIjC,MAAM,iBAAiB,CAAC;AAczB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAgB7D,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,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,yBAAyB,EAC3C,WAAW,EAAE,WAAW,GACvB,OAAO,CAmCT;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;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,sBAAsB,EAAE,CAAC,CA6BnC;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"}
|
|
@@ -63,6 +63,9 @@ function eligibileForRebalance(positionState, positionSettings, positionDca) {
|
|
|
63
63
|
eligibleForNextAutomationPeriod(positionDca.automation)) {
|
|
64
64
|
return true;
|
|
65
65
|
}
|
|
66
|
+
if (positionState.supply.amountUsed.baseUnit === BigInt(0)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
66
69
|
const boostToBps = eligibleForRefresh(positionState, positionSettings) &&
|
|
67
70
|
positionSettings.automation.targetPeriods > 0
|
|
68
71
|
? getUpdatedValueFromAutomation(positionSettings.boostToBps, positionSettings.targetBoostToBps, positionSettings.automation, (0, generalUtils_1.currentUnixSeconds)())
|
package/package.json
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
fromWeb3JsKeypair,
|
|
3
2
|
fromWeb3JsPublicKey,
|
|
4
3
|
toWeb3JsPublicKey,
|
|
5
4
|
} from "@metaplex-foundation/umi-web3js-adapters";
|
|
@@ -12,10 +11,7 @@ import {
|
|
|
12
11
|
createSignerFromKeypair,
|
|
13
12
|
AccountMeta,
|
|
14
13
|
} from "@metaplex-foundation/umi";
|
|
15
|
-
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
|
16
14
|
import {
|
|
17
|
-
clusterApiUrl,
|
|
18
|
-
Keypair,
|
|
19
15
|
PublicKey,
|
|
20
16
|
SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
21
17
|
} from "@solana/web3.js";
|
|
@@ -60,7 +56,6 @@ import {
|
|
|
60
56
|
getMarginfiAccountPositionState,
|
|
61
57
|
} from "../utils/marginfiUtils";
|
|
62
58
|
import { bytesToI80F48 } from "../utils/numberUtils";
|
|
63
|
-
import { WalletAdapter } from "@metaplex-foundation/umi-signer-wallet-adapters";
|
|
64
59
|
|
|
65
60
|
export interface SolautoMarginfiClientArgs extends SolautoClientArgs {
|
|
66
61
|
marginfiAccount?: PublicKey | Signer;
|
|
@@ -68,34 +63,12 @@ export interface SolautoMarginfiClientArgs extends SolautoClientArgs {
|
|
|
68
63
|
marginfiGroup?: PublicKey;
|
|
69
64
|
}
|
|
70
65
|
|
|
71
|
-
export function newSolautoMarginfiPositionArgs(
|
|
72
|
-
positionId: number,
|
|
73
|
-
signer: Signer | undefined,
|
|
74
|
-
wallet: WalletAdapter | undefined,
|
|
75
|
-
supplyMint: PublicKey,
|
|
76
|
-
debtMint: PublicKey,
|
|
77
|
-
referredByAuthority?: PublicKey
|
|
78
|
-
): SolautoMarginfiClientArgs {
|
|
79
|
-
const umi = createUmi(clusterApiUrl("mainnet-beta"));
|
|
80
|
-
return {
|
|
81
|
-
positionId,
|
|
82
|
-
signer,
|
|
83
|
-
wallet,
|
|
84
|
-
marginfiAccount:
|
|
85
|
-
positionId === 0
|
|
86
|
-
? createSignerFromKeypair(umi, umi.eddsa.generateKeypair())
|
|
87
|
-
: undefined,
|
|
88
|
-
marginfiAccountSeedIdx: positionId > 0 ? generateRandomU64() : undefined,
|
|
89
|
-
supplyMint: supplyMint,
|
|
90
|
-
debtMint: debtMint,
|
|
91
|
-
referredByAuthority,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
66
|
export class SolautoMarginfiClient extends SolautoClient {
|
|
67
|
+
private initialized: boolean = false;
|
|
68
|
+
|
|
96
69
|
public marginfiProgram!: PublicKey;
|
|
97
70
|
|
|
98
|
-
public marginfiAccountSeedIdx
|
|
71
|
+
public marginfiAccountSeedIdx: bigint = BigInt(0);
|
|
99
72
|
public marginfiAccount!: PublicKey | Signer;
|
|
100
73
|
public marginfiAccountPk!: PublicKey;
|
|
101
74
|
public marginfiGroup!: PublicKey;
|
|
@@ -111,15 +84,19 @@ export class SolautoMarginfiClient extends SolautoClient {
|
|
|
111
84
|
async initialize(args: SolautoMarginfiClientArgs) {
|
|
112
85
|
await super.initialize(args, LendingPlatform.Marginfi);
|
|
113
86
|
|
|
114
|
-
this.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
87
|
+
if (this.selfManaged) {
|
|
88
|
+
this.marginfiAccount =
|
|
89
|
+
args.marginfiAccount ??
|
|
90
|
+
createSignerFromKeypair(this.umi, this.umi.eddsa.generateKeypair());
|
|
91
|
+
} else {
|
|
92
|
+
this.marginfiAccountSeedIdx = generateRandomU64();
|
|
93
|
+
this.marginfiAccount = this.solautoPositionData
|
|
94
|
+
? toWeb3JsPublicKey(this.solautoPositionData.position.protocolAccount)
|
|
95
|
+
: await getMarginfiAccountPDA(
|
|
118
96
|
this.solautoPosition,
|
|
119
97
|
this.marginfiAccountSeedIdx
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
toWeb3JsPublicKey(this.solautoPositionData!.position.protocolAccount);
|
|
98
|
+
);
|
|
99
|
+
}
|
|
123
100
|
this.marginfiAccountPk =
|
|
124
101
|
"publicKey" in this.marginfiAccount
|
|
125
102
|
? toWeb3JsPublicKey(this.marginfiAccount.publicKey)
|
|
@@ -140,27 +117,37 @@ export class SolautoMarginfiClient extends SolautoClient {
|
|
|
140
117
|
mint: this.debtMint.toString(),
|
|
141
118
|
})!;
|
|
142
119
|
|
|
120
|
+
if (!this.initialized) {
|
|
121
|
+
await this.setIntermediaryMarginfiDetails();
|
|
122
|
+
}
|
|
123
|
+
this.initialized = true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async setIntermediaryMarginfiDetails() {
|
|
143
127
|
const existingMarginfiAccounts = (
|
|
144
128
|
await getAllMarginfiAccountsByAuthority(
|
|
145
129
|
this.umi,
|
|
146
130
|
toWeb3JsPublicKey(this.signer.publicKey),
|
|
147
131
|
false
|
|
148
132
|
)
|
|
149
|
-
).filter((x) => x.marginfiAccount.equals(this.marginfiAccountPk));
|
|
150
|
-
const emptyMarginfiAccounts =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
133
|
+
).filter((x) => !x.marginfiAccount.equals(this.marginfiAccountPk));
|
|
134
|
+
const emptyMarginfiAccounts =
|
|
135
|
+
existingMarginfiAccounts.length > 0
|
|
136
|
+
? (
|
|
137
|
+
await safeFetchAllMarginfiAccount(
|
|
138
|
+
this.umi,
|
|
139
|
+
existingMarginfiAccounts.map((x) => publicKey(x.marginfiAccount))
|
|
140
|
+
)
|
|
141
|
+
).filter(
|
|
142
|
+
(x) =>
|
|
143
|
+
x.lendingAccount.balances.find(
|
|
144
|
+
(y) =>
|
|
145
|
+
y.bankPk.toString() !== PublicKey.default.toString() &&
|
|
146
|
+
(Math.round(bytesToI80F48(y.assetShares.value)) != 0 ||
|
|
147
|
+
Math.round(bytesToI80F48(y.liabilityShares.value)) != 0)
|
|
148
|
+
) === undefined
|
|
149
|
+
)
|
|
150
|
+
: [];
|
|
164
151
|
|
|
165
152
|
this.intermediaryMarginfiAccountSigner =
|
|
166
153
|
emptyMarginfiAccounts.length > 0
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Instruction,
|
|
2
3
|
Signer,
|
|
3
4
|
TransactionBuilder,
|
|
4
5
|
Umi,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
SolautoRebalanceType,
|
|
21
22
|
convertReferralFees,
|
|
22
23
|
getMarginfiProtocolInteractionInstructionDataSerializer,
|
|
24
|
+
getMarginfiRebalanceInstructionDataSerializer,
|
|
23
25
|
isSolautoAction,
|
|
24
26
|
solautoAction,
|
|
25
27
|
} from "../generated";
|
|
@@ -224,9 +226,13 @@ export async function rebalanceChoresBefore(
|
|
|
224
226
|
client: SolautoClient,
|
|
225
227
|
tx: TransactionBuilder
|
|
226
228
|
): Promise<TransactionBuilder> {
|
|
229
|
+
const rebalanceInstructions = getRebalanceInstructions(tx);
|
|
230
|
+
if (rebalanceInstructions.length === 0) {
|
|
231
|
+
return transactionBuilder();
|
|
232
|
+
}
|
|
233
|
+
|
|
227
234
|
const usesAccount = (key: PublicKey) =>
|
|
228
|
-
|
|
229
|
-
.getInstructions()
|
|
235
|
+
rebalanceInstructions
|
|
230
236
|
.some((t) => t.keys.some((k) => toWeb3JsPublicKey(k.pubkey).equals(key)));
|
|
231
237
|
|
|
232
238
|
const checkReferralSupplyTa =
|
|
@@ -237,6 +243,8 @@ export async function rebalanceChoresBefore(
|
|
|
237
243
|
usesAccount(
|
|
238
244
|
(client as SolautoMarginfiClient).intermediaryMarginfiAccountPk
|
|
239
245
|
);
|
|
246
|
+
const checkSignerSupplyTa = client.selfManaged && usesAccount(client.signerSupplyTa);
|
|
247
|
+
const checkSignerDebtTa = client.selfManaged && usesAccount(client.signerSupplyTa);
|
|
240
248
|
|
|
241
249
|
const accountsNeeded = [
|
|
242
250
|
...[checkReferralSupplyTa ? client.referredBySupplyTa : PublicKey.default],
|
|
@@ -246,9 +254,11 @@ export async function rebalanceChoresBefore(
|
|
|
246
254
|
? (client as SolautoMarginfiClient).intermediaryMarginfiAccountPk
|
|
247
255
|
: PublicKey.default,
|
|
248
256
|
],
|
|
257
|
+
...[checkSignerSupplyTa ? client.signerSupplyTa : PublicKey.default],
|
|
258
|
+
...[checkSignerDebtTa ? client.signerDebtTa : PublicKey.default],
|
|
249
259
|
];
|
|
250
260
|
|
|
251
|
-
const [referredBySupplyTa, solautoFeesSupplyTa, intermediaryMarginfiAccount] =
|
|
261
|
+
const [referredBySupplyTa, solautoFeesSupplyTa, intermediaryMarginfiAccount, signerSupplyTa, signerDebtTa] =
|
|
252
262
|
await client.umi.rpc.getAccounts(
|
|
253
263
|
accountsNeeded.map((x) => publicKey(x ?? PublicKey.default))
|
|
254
264
|
);
|
|
@@ -286,6 +296,28 @@ export async function rebalanceChoresBefore(
|
|
|
286
296
|
);
|
|
287
297
|
}
|
|
288
298
|
|
|
299
|
+
if (checkSignerSupplyTa && !rpcAccountCreated(signerSupplyTa)) {
|
|
300
|
+
client.log("Creating signer supply token account");
|
|
301
|
+
chores = chores.add(
|
|
302
|
+
createAssociatedTokenAccountUmiIx(
|
|
303
|
+
client.signer,
|
|
304
|
+
toWeb3JsPublicKey(client.signer.publicKey),
|
|
305
|
+
client.supplyMint
|
|
306
|
+
)
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (checkSignerDebtTa && !rpcAccountCreated(signerDebtTa)) {
|
|
311
|
+
client.log("Creating signer debt token account");
|
|
312
|
+
chores = chores.add(
|
|
313
|
+
createAssociatedTokenAccountUmiIx(
|
|
314
|
+
client.signer,
|
|
315
|
+
toWeb3JsPublicKey(client.signer.publicKey),
|
|
316
|
+
client.debtMint
|
|
317
|
+
)
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
289
321
|
return chores;
|
|
290
322
|
}
|
|
291
323
|
|
|
@@ -315,6 +347,26 @@ function transactionChoresAfter(
|
|
|
315
347
|
return chores;
|
|
316
348
|
}
|
|
317
349
|
|
|
350
|
+
function getRebalanceInstructions(tx: TransactionBuilder): Instruction[] {
|
|
351
|
+
return tx.getInstructions().filter((x) => {
|
|
352
|
+
if (x.programId === SOLAUTO_PROGRAM_ID) {
|
|
353
|
+
try {
|
|
354
|
+
const serializer = getMarginfiRebalanceInstructionDataSerializer();
|
|
355
|
+
const discriminator = serializer.serialize({
|
|
356
|
+
limitGapBps: 0,
|
|
357
|
+
rebalanceType: SolautoRebalanceType.None,
|
|
358
|
+
targetLiqUtilizationRateBps: 0
|
|
359
|
+
})[0];
|
|
360
|
+
const [data, _] = serializer.deserialize(x.data);
|
|
361
|
+
if (data.discriminator === discriminator) {
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
} catch {}
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
|
|
318
370
|
function getSolautoActions(tx: TransactionBuilder): SolautoAction[] {
|
|
319
371
|
let solautoActions: SolautoAction[] = [];
|
|
320
372
|
|
|
@@ -326,8 +378,7 @@ function getSolautoActions(tx: TransactionBuilder): SolautoAction[] {
|
|
|
326
378
|
const discriminator = serializer
|
|
327
379
|
.serialize({
|
|
328
380
|
solautoAction: solautoAction("Deposit", [BigInt(0)]),
|
|
329
|
-
})
|
|
330
|
-
.slice(0, 1)[0];
|
|
381
|
+
})[0];
|
|
331
382
|
const [data, _] = serializer.deserialize(x.data);
|
|
332
383
|
if (data.discriminator === discriminator) {
|
|
333
384
|
solautoActions?.push(data.solautoAction);
|
|
@@ -491,14 +542,15 @@ export async function buildSolautoRebalanceTransaction(
|
|
|
491
542
|
> {
|
|
492
543
|
client.solautoPositionState = await client.getFreshPositionState();
|
|
493
544
|
if (
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
client.
|
|
499
|
-
|
|
500
|
-
client.
|
|
501
|
-
|
|
545
|
+
client.solautoPositionState?.supply.amountUsed.baseUnit === BigInt(0) ||
|
|
546
|
+
(targetLiqUtilizationRateBps === undefined &&
|
|
547
|
+
!eligibileForRebalance(
|
|
548
|
+
client.solautoPositionState!,
|
|
549
|
+
client.livePositionUpdates.settings ??
|
|
550
|
+
client.solautoPositionData?.position.settingParams!,
|
|
551
|
+
client.livePositionUpdates.activeDca ??
|
|
552
|
+
client.solautoPositionData?.position.dca!
|
|
553
|
+
))
|
|
502
554
|
) {
|
|
503
555
|
client.log("Not eligible for a rebalance");
|
|
504
556
|
return undefined;
|
package/src/utils/deleteme.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getDebtAdjustmentUsd, getLiqUtilzationRateBps } from "./numberUtils";
|
|
2
2
|
|
|
3
3
|
// TODO delete this file
|
|
4
|
-
function check() {
|
|
4
|
+
async function check() {
|
|
5
5
|
let supply = 458948;
|
|
6
6
|
let debt = 212846;
|
|
7
7
|
let supply_weight = 0.899999976158142;
|
|
@@ -37,4 +37,4 @@ function check() {
|
|
|
37
37
|
console.log!(liq_utilization_rate);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
check();
|
|
40
|
+
check();
|
|
@@ -44,7 +44,7 @@ export function findMarginfiBankAccounts({
|
|
|
44
44
|
|
|
45
45
|
export async function getMaxLtvAndLiqThreshold(
|
|
46
46
|
supplyBank: Bank,
|
|
47
|
-
debtBank: Bank,
|
|
47
|
+
debtBank: Bank | null,
|
|
48
48
|
supplyPrice?: number
|
|
49
49
|
): Promise<[number, number]> {
|
|
50
50
|
if (!supplyPrice) {
|
|
@@ -52,6 +52,10 @@ export async function getMaxLtvAndLiqThreshold(
|
|
|
52
52
|
supplyPrice = price;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
if (debtBank === null) {
|
|
56
|
+
return [0, 0];
|
|
57
|
+
}
|
|
58
|
+
|
|
55
59
|
let maxLtv =
|
|
56
60
|
bytesToI80F48(supplyBank.config.assetWeightInit.value) /
|
|
57
61
|
bytesToI80F48(debtBank.config.liabilityWeightInit.value);
|
|
@@ -112,6 +116,7 @@ export async function getAllMarginfiAccountsByAuthority(
|
|
|
112
116
|
);
|
|
113
117
|
|
|
114
118
|
if (compatibleWithSolauto) {
|
|
119
|
+
console.log(marginfiAccounts);
|
|
115
120
|
const positionStates = await Promise.all(
|
|
116
121
|
marginfiAccounts.map(async (x) => ({
|
|
117
122
|
publicKey: x.publicKey,
|
|
@@ -137,44 +142,50 @@ export async function getAllMarginfiAccountsByAuthority(
|
|
|
137
142
|
|
|
138
143
|
async function getTokenUsage(
|
|
139
144
|
umi: Umi,
|
|
140
|
-
bank: Bank,
|
|
145
|
+
bank: Bank | null,
|
|
141
146
|
isAsset: boolean,
|
|
142
147
|
shares: number,
|
|
143
148
|
amountUsedAdjustment?: bigint
|
|
144
149
|
): Promise<PositionTokenUsage> {
|
|
145
|
-
let
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
bank
|
|
149
|
-
);
|
|
150
|
-
const shareValue = isAsset ? assetShareValue : liabilityShareValue;
|
|
151
|
-
const amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0);
|
|
150
|
+
let amountUsed = 0;
|
|
151
|
+
let amountCanBeUsed = 0;
|
|
152
|
+
let marketPrice = 0;
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
if (bank !== null) {
|
|
155
|
+
[marketPrice] = await getTokenPrices([toWeb3JsPublicKey(bank.mint)]);
|
|
156
|
+
const [assetShareValue, liabilityShareValue] = await getUpToDateShareValues(
|
|
157
|
+
umi,
|
|
158
|
+
bank
|
|
159
|
+
);
|
|
160
|
+
const shareValue = isAsset ? assetShareValue : liabilityShareValue;
|
|
161
|
+
amountUsed = shares * shareValue + Number(amountUsedAdjustment ?? 0);
|
|
162
|
+
|
|
163
|
+
const totalDeposited =
|
|
164
|
+
bytesToI80F48(bank.totalAssetShares.value) * assetShareValue;
|
|
165
|
+
amountCanBeUsed = isAsset
|
|
166
|
+
? Number(bank.config.depositLimit) - totalDeposited
|
|
167
|
+
: totalDeposited -
|
|
168
|
+
bytesToI80F48(bank.totalLiabilityShares.value) * liabilityShareValue;
|
|
169
|
+
}
|
|
159
170
|
|
|
160
171
|
return {
|
|
161
|
-
mint: bank.
|
|
162
|
-
decimals: bank
|
|
172
|
+
mint: bank?.mint ?? publicKey(PublicKey.default),
|
|
173
|
+
decimals: bank?.mintDecimals ?? 0,
|
|
163
174
|
amountUsed: {
|
|
164
175
|
baseUnit: BigInt(Math.round(amountUsed)),
|
|
165
|
-
baseAmountUsdValue: toBaseUnit(
|
|
176
|
+
baseAmountUsdValue: bank ? toBaseUnit(
|
|
166
177
|
fromBaseUnit(BigInt(Math.round(amountUsed)), bank.mintDecimals) *
|
|
167
178
|
marketPrice,
|
|
168
179
|
USD_DECIMALS
|
|
169
|
-
),
|
|
180
|
+
) : BigInt(0),
|
|
170
181
|
},
|
|
171
182
|
amountCanBeUsed: {
|
|
172
|
-
baseUnit: BigInt(Math.round(
|
|
173
|
-
baseAmountUsdValue: toBaseUnit(
|
|
174
|
-
fromBaseUnit(BigInt(Math.round(
|
|
183
|
+
baseUnit: BigInt(Math.round(amountCanBeUsed)),
|
|
184
|
+
baseAmountUsdValue: bank ? toBaseUnit(
|
|
185
|
+
fromBaseUnit(BigInt(Math.round(amountCanBeUsed)), bank.mintDecimals) *
|
|
175
186
|
marketPrice,
|
|
176
187
|
USD_DECIMALS
|
|
177
|
-
),
|
|
188
|
+
) : BigInt(0),
|
|
178
189
|
},
|
|
179
190
|
baseAmountMarketPriceUsd: toBaseUnit(marketPrice, USD_DECIMALS),
|
|
180
191
|
flashLoanFeeBps: 0,
|
|
@@ -270,7 +281,11 @@ export async function getMarginfiAccountPositionState(
|
|
|
270
281
|
}
|
|
271
282
|
}
|
|
272
283
|
|
|
273
|
-
if (supplyBank
|
|
284
|
+
if (supplyBank === null) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (!supplyUsage) {
|
|
274
289
|
supplyUsage = await getTokenUsage(
|
|
275
290
|
umi,
|
|
276
291
|
supplyBank,
|
|
@@ -280,7 +295,7 @@ export async function getMarginfiAccountPositionState(
|
|
|
280
295
|
);
|
|
281
296
|
}
|
|
282
297
|
|
|
283
|
-
if (
|
|
298
|
+
if (!debtUsage) {
|
|
284
299
|
debtUsage = await getTokenUsage(
|
|
285
300
|
umi,
|
|
286
301
|
debtBank,
|
|
@@ -290,10 +305,6 @@ export async function getMarginfiAccountPositionState(
|
|
|
290
305
|
);
|
|
291
306
|
}
|
|
292
307
|
|
|
293
|
-
if (supplyBank === null || debtBank === null) {
|
|
294
|
-
return undefined;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
308
|
const supplyPrice = PRICES[supplyMint!.toString()].price;
|
|
298
309
|
let [maxLtv, liqThreshold] = await getMaxLtvAndLiqThreshold(
|
|
299
310
|
supplyBank,
|
|
@@ -130,6 +130,10 @@ export function eligibileForRebalance(
|
|
|
130
130
|
return true;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
if (positionState.supply.amountUsed.baseUnit === BigInt(0)) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
133
137
|
const boostToBps =
|
|
134
138
|
eligibleForRefresh(positionState, positionSettings) &&
|
|
135
139
|
positionSettings.automation.targetPeriods > 0
|
|
@@ -3,7 +3,6 @@ import { none, some } from "@metaplex-foundation/umi";
|
|
|
3
3
|
import { setupTest } from "../shared";
|
|
4
4
|
import {
|
|
5
5
|
SolautoMarginfiClient,
|
|
6
|
-
newSolautoMarginfiPositionArgs,
|
|
7
6
|
} from "../../src/clients/solautoMarginfiClient";
|
|
8
7
|
import {
|
|
9
8
|
solautoAction,
|
|
@@ -35,13 +34,6 @@ describe("Solauto Marginfi tests", async () => {
|
|
|
35
34
|
const debtDecimals = 6;
|
|
36
35
|
|
|
37
36
|
await client.initialize(
|
|
38
|
-
// newSolautoMarginfiPositionArgs(
|
|
39
|
-
// positionId,
|
|
40
|
-
// signer,
|
|
41
|
-
// undefined,
|
|
42
|
-
// supply,
|
|
43
|
-
// new PublicKey(USDC_MINT)
|
|
44
|
-
// )
|
|
45
37
|
{
|
|
46
38
|
signer,
|
|
47
39
|
positionId,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { describe, it, before } from
|
|
1
|
+
import { describe, it, before } from "mocha";
|
|
2
2
|
import { PublicKey } from "@solana/web3.js";
|
|
3
3
|
import { NATIVE_MINT } from "@solana/spl-token";
|
|
4
4
|
import { assert } from "chai";
|
|
5
|
-
import {
|
|
6
|
-
newSolautoMarginfiPositionArgs,
|
|
7
|
-
SolautoMarginfiClient,
|
|
8
|
-
} from "../../src/clients/solautoMarginfiClient";
|
|
5
|
+
import { SolautoMarginfiClient } from "../../src/clients/solautoMarginfiClient";
|
|
9
6
|
import { setupTest } from "../shared";
|
|
10
7
|
import { MARGINFI_ACCOUNTS } from "../../src/constants/marginfiAccounts";
|
|
11
8
|
import { getRebalanceValues } from "../../src/utils/solauto/rebalanceUtils";
|
|
@@ -92,16 +89,16 @@ async function getFakePosition(
|
|
|
92
89
|
settings: SolautoSettingsParameters,
|
|
93
90
|
dca?: DCASettings
|
|
94
91
|
): Promise<SolautoClient> {
|
|
95
|
-
const client = new SolautoMarginfiClient(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
1,
|
|
99
|
-
signer,
|
|
100
|
-
undefined,
|
|
101
|
-
new PublicKey(NATIVE_MINT),
|
|
102
|
-
new PublicKey(MARGINFI_ACCOUNTS.USDC.mint)
|
|
103
|
-
)
|
|
92
|
+
const client = new SolautoMarginfiClient(
|
|
93
|
+
process.env.HELIUS_API_KEY ?? "",
|
|
94
|
+
true
|
|
104
95
|
);
|
|
96
|
+
await client.initialize({
|
|
97
|
+
positionId: 1,
|
|
98
|
+
signer,
|
|
99
|
+
supplyMint: new PublicKey(NATIVE_MINT),
|
|
100
|
+
debtMint: new PublicKey(MARGINFI_ACCOUNTS.USDC.mint),
|
|
101
|
+
});
|
|
105
102
|
|
|
106
103
|
const state = await client.getFreshPositionState();
|
|
107
104
|
client.solautoPositionData = {
|
|
@@ -268,16 +265,16 @@ describe("Rebalance tests", async () => {
|
|
|
268
265
|
});
|
|
269
266
|
|
|
270
267
|
it("Standard rebalance with target rate", async () => {
|
|
271
|
-
const client = new SolautoMarginfiClient(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
1,
|
|
275
|
-
signer,
|
|
276
|
-
undefined,
|
|
277
|
-
new PublicKey(NATIVE_MINT),
|
|
278
|
-
new PublicKey(MARGINFI_ACCOUNTS.USDC.mint)
|
|
279
|
-
)
|
|
268
|
+
const client = new SolautoMarginfiClient(
|
|
269
|
+
process.env.HELIUS_API_KEY ?? "",
|
|
270
|
+
true
|
|
280
271
|
);
|
|
272
|
+
await client.initialize({
|
|
273
|
+
positionId: 1,
|
|
274
|
+
signer,
|
|
275
|
+
supplyMint: new PublicKey(NATIVE_MINT),
|
|
276
|
+
debtMint: new PublicKey(MARGINFI_ACCOUNTS.USDC.mint),
|
|
277
|
+
});
|
|
281
278
|
|
|
282
279
|
client.livePositionUpdates.new({
|
|
283
280
|
type: "supply",
|