@exponent-labs/marginfi-sy-sdk 0.0.3

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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.0.3](https://github.com/exponent-finance/exponent-core/compare/@exponent-labs/marginfi-sy-sdk@0.0.2...@exponent-labs/marginfi-sy-sdk@0.0.3) (2025-03-03)
7
+
8
+ **Note:** Version bump only for package @exponent-labs/marginfi-sy-sdk
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.0.2](https://github.com/exponent-finance/exponent-core/compare/@exponent-labs/marginfi-sy-sdk@0.0.1...@exponent-labs/marginfi-sy-sdk@0.0.2) (2025-03-03)
15
+
16
+ **Note:** Version bump only for package @exponent-labs/marginfi-sy-sdk
@@ -0,0 +1,136 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN, web3 } from "@coral-xyz/anchor";
3
+ import { MarginfiStandard } from "@exponent-labs/marginfi-sy-idl";
4
+ import { MarginfiSyPda } from "@exponent-labs/marginfi-sy-pda";
5
+ import { MfiSyState, SyMetaJson } from "@exponent-labs/exponent-types";
6
+ export type ClaimAmount = {
7
+ all: {};
8
+ } | {
9
+ some: {
10
+ 0: BN;
11
+ };
12
+ };
13
+ export declare class MfiSySdk {
14
+ state: MfiSyState;
15
+ /** Private program for building instructions */
16
+ private program;
17
+ pda: MarginfiSyPda;
18
+ constructor(state: MfiSyState);
19
+ /** Load an instance of SyMeta */
20
+ static load({ cnx, mfiBank, mfiSyProgramId, mfiProgramId, mfiGroupId, }: {
21
+ cnx: web3.Connection;
22
+ mfiBank: web3.PublicKey;
23
+ mfiSyProgramId: web3.PublicKey;
24
+ mfiProgramId?: web3.PublicKey;
25
+ mfiGroupId?: web3.PublicKey;
26
+ }): Promise<MfiSySdk>;
27
+ /** Reload the state of the account */
28
+ reload(cnx: web3.Connection): Promise<void>;
29
+ toJson(): SyMetaJson;
30
+ get selfAddress(): web3.PublicKey;
31
+ get account(): import("@exponent-labs/exponent-types").MarginfiSyMeta;
32
+ get mintSy(): web3.PublicKey;
33
+ get marginfiBank(): web3.PublicKey;
34
+ get marginfiAccount(): web3.PublicKey;
35
+ get tokenSyEscrow(): web3.PublicKey;
36
+ get maxSySupply(): bigint;
37
+ get minMintSize(): bigint;
38
+ get minRedeemSize(): bigint;
39
+ get mintBase(): web3.PublicKey;
40
+ get tokenProgramBase(): web3.PublicKey;
41
+ get tokenBaseAccountAuthority(): web3.PublicKey;
42
+ get bankLiquidityVault(): web3.PublicKey;
43
+ get bankLiquidityVaultAuthority(): web3.PublicKey;
44
+ get marginfiEmissionsAuth(): web3.PublicKey;
45
+ get marginfiEmissionsVault(): web3.PublicKey;
46
+ get marginfiGroup(): web3.PublicKey;
47
+ get marginfiProgram(): web3.PublicKey;
48
+ get hasEmission(): boolean;
49
+ ixMintSy({ depositor, amountBase, baseSrc, syDst, }: {
50
+ depositor: web3.PublicKey;
51
+ amountBase: string;
52
+ baseSrc?: web3.PublicKey;
53
+ syDst?: web3.PublicKey;
54
+ }): Promise<web3.TransactionInstruction>;
55
+ ixRedeemSy({ redeemer, amountSy, baseDst, sySrc, }: {
56
+ redeemer: web3.PublicKey;
57
+ amountSy: string;
58
+ baseDst?: web3.PublicKey;
59
+ sySrc?: web3.PublicKey;
60
+ }): Promise<web3.TransactionInstruction>;
61
+ ixInitializePosition({ owner, feePayer }: {
62
+ owner: web3.PublicKey;
63
+ feePayer: web3.PublicKey;
64
+ }): Promise<web3.TransactionInstruction>;
65
+ ixDeposit({ depositor, amountSy, emissionDst, sySrc, }: {
66
+ depositor: web3.PublicKey;
67
+ amountSy: string;
68
+ emissionDst?: web3.PublicKey;
69
+ sySrc?: web3.PublicKey;
70
+ }): Promise<web3.TransactionInstruction>;
71
+ ixWithdraw({ signer, amountSy, syDst }: {
72
+ signer: web3.PublicKey;
73
+ amountSy: string;
74
+ syDst?: web3.PublicKey;
75
+ }): Promise<web3.TransactionInstruction>;
76
+ ixCollectEmission({ owner, index, emissionDst, amount, }: {
77
+ owner: web3.PublicKey;
78
+ index: number;
79
+ emissionDst?: web3.PublicKey;
80
+ amount?: string;
81
+ }): import("@coral-xyz/anchor/dist/cjs/program/namespace/methods").MethodsBuilder<MarginfiStandard, {
82
+ name: "collectEmission";
83
+ discriminator: [8];
84
+ accounts: [{
85
+ name: "owner";
86
+ signer: true;
87
+ }, {
88
+ name: "meta";
89
+ writable: true;
90
+ }, {
91
+ name: "position";
92
+ writable: true;
93
+ }, {
94
+ name: "tokenEmissionAccountAuthority";
95
+ writable: true;
96
+ }, {
97
+ name: "tokenEmissionSigner";
98
+ writable: true;
99
+ }, {
100
+ name: "tokenProgram";
101
+ }];
102
+ args: [{
103
+ name: "amount";
104
+ type: {
105
+ defined: {
106
+ name: "amount";
107
+ };
108
+ };
109
+ }];
110
+ } & {
111
+ name: "collectEmission";
112
+ }, {
113
+ name: "owner";
114
+ signer: true;
115
+ } | {
116
+ name: "meta";
117
+ writable: true;
118
+ } | {
119
+ name: "position";
120
+ writable: true;
121
+ } | {
122
+ name: "tokenEmissionAccountAuthority";
123
+ writable: true;
124
+ } | {
125
+ name: "tokenEmissionSigner";
126
+ writable: true;
127
+ } | {
128
+ name: "tokenProgram";
129
+ }>;
130
+ }
131
+ export declare function fetchBank(address: web3.PublicKey, connection: web3.Connection): Promise<{
132
+ baseMint: web3.PublicKey;
133
+ assetShareValue: string;
134
+ emissionsMint: web3.PublicKey;
135
+ emissionTokenProgram: web3.PublicKey;
136
+ }>;
package/build/index.js ADDED
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.fetchBank = exports.MfiSySdk = void 0;
27
+ const anchor_1 = require("@coral-xyz/anchor");
28
+ const marginfi_sy_idl_1 = require("@exponent-labs/marginfi-sy-idl");
29
+ const marginfi_sy_pda_1 = require("@exponent-labs/marginfi-sy-pda");
30
+ const spl_token_1 = require("@solana/spl-token");
31
+ const mfiPda = __importStar(require("@exponent-labs/marginfi-pda"));
32
+ const exponent_fetcher_1 = require("@exponent-labs/exponent-fetcher");
33
+ const precise_number_1 = require("@exponent-labs/precise-number");
34
+ const i80f48_util_1 = require("@exponent-labs/i80f48-util");
35
+ const MARGINFI_GROUP_ID = new anchor_1.web3.PublicKey("4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8");
36
+ const MARGINFI_PROGRAM_ID = new anchor_1.web3.PublicKey("MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA");
37
+ const PYTH_USDC_FEED_ID = new anchor_1.web3.PublicKey("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD");
38
+ function toJson(m) {
39
+ return {
40
+ selfAddress: m.selfAddress.toBase58(),
41
+ marginfiBank: m.marginfiBank.toBase58(),
42
+ marginfiAccount: m.marginfiAccount.toBase58(),
43
+ mintSy: m.mintSy.toBase58(),
44
+ tokenSyEscrow: m.tokenSyEscrow.toBase58(),
45
+ emissions: m.account.emissions.map((e) => ({
46
+ mint: e.mint.toBase58(),
47
+ tokenProgram: e.tokenProgram.toBase58(),
48
+ escrowAccount: e.escrowAccount.toBase58(),
49
+ index: parseFloat(precise_number_1.PreciseNumber.fromRaw(e.index[0]).valueString),
50
+ lastSeenIndex: parseFloat(precise_number_1.PreciseNumber.fromRaw(e.lastSeenIndex[0]).valueString),
51
+ lastSeenTotalAccruedEmissions: e.lastSeenTotalAccruedEmissions.toString(),
52
+ totalClaimedEmissions: e.totalClaimedEmissions.toString(),
53
+ treasuryEmission: e.treasuryEmission.toString(),
54
+ })),
55
+ maxSySupply: m.maxSySupply.toString(),
56
+ minMintSize: m.minMintSize.toString(),
57
+ minRedeemSize: m.minRedeemSize.toString(),
58
+ syRate: m.state.syRate,
59
+ };
60
+ }
61
+ async function loadAccountState({ cnx, mfiBank, mfiSyProgramId, }) {
62
+ const pda = new marginfi_sy_pda_1.MarginfiSyPda(mfiSyProgramId);
63
+ const fetcher = new exponent_fetcher_1.ExponentFetcher({ connection: cnx, marginfiSyProgramId: mfiSyProgramId });
64
+ const syMetaAddress = pda.syMeta({ bank: mfiBank });
65
+ const data = await fetcher.fetchMarginfiSyMeta(syMetaAddress);
66
+ return data;
67
+ }
68
+ class MfiSySdk {
69
+ state;
70
+ /** Private program for building instructions */
71
+ program;
72
+ pda;
73
+ constructor(state) {
74
+ this.state = state;
75
+ // create a fake AnchorProvider -- which is unused
76
+ this.program = new anchor_1.Program(marginfi_sy_idl_1.IDL, new anchor_1.AnchorProvider(new anchor_1.web3.Connection("https://api.devnet.solana.com"), new exponent_fetcher_1.MyWallet(anchor_1.web3.Keypair.generate())));
77
+ this.pda = new marginfi_sy_pda_1.MarginfiSyPda(state.marginfiSyProgramId);
78
+ }
79
+ /** Load an instance of SyMeta */
80
+ static async load({ cnx, mfiBank, mfiSyProgramId, mfiProgramId = MARGINFI_PROGRAM_ID, mfiGroupId = new anchor_1.web3.PublicKey(MARGINFI_GROUP_ID), }) {
81
+ const account = await loadAccountState({ cnx, mfiBank, mfiSyProgramId });
82
+ const b = await fetchBank(mfiBank, cnx);
83
+ const baseMintAi = await cnx.getAccountInfo(b.baseMint);
84
+ const tokenProgramBase = baseMintAi.owner;
85
+ const selfAddress = new marginfi_sy_pda_1.MarginfiSyPda(mfiSyProgramId).syMeta({ bank: mfiBank });
86
+ const state = {
87
+ marginfiProgramId: mfiProgramId,
88
+ marginfiGroupId: mfiGroupId,
89
+ selfAddress,
90
+ account,
91
+ marginfiSyProgramId: mfiSyProgramId,
92
+ mintBase: b.baseMint,
93
+ tokenProgramBase,
94
+ emissionsMint: b.emissionsMint,
95
+ emissionsTokenProgram: b.emissionTokenProgram,
96
+ syRate: b.assetShareValue,
97
+ };
98
+ return new MfiSySdk(state);
99
+ }
100
+ /** Reload the state of the account */
101
+ async reload(cnx) {
102
+ const b = await fetchBank(this.marginfiBank, cnx);
103
+ const account = await loadAccountState({
104
+ cnx,
105
+ mfiBank: this.marginfiBank,
106
+ mfiSyProgramId: this.state.marginfiSyProgramId,
107
+ });
108
+ this.state.account = account;
109
+ this.state.syRate = b.assetShareValue;
110
+ }
111
+ toJson() {
112
+ return toJson(this);
113
+ }
114
+ get selfAddress() {
115
+ return this.state.selfAddress;
116
+ }
117
+ get account() {
118
+ return this.state.account;
119
+ }
120
+ get mintSy() {
121
+ return this.account.mintSy;
122
+ }
123
+ get marginfiBank() {
124
+ return this.account.marginfiBank;
125
+ }
126
+ get marginfiAccount() {
127
+ return this.account.marginfiAccount;
128
+ }
129
+ get tokenSyEscrow() {
130
+ return this.account.tokenSyEscrow;
131
+ }
132
+ get maxSySupply() {
133
+ return this.account.maxSySupply;
134
+ }
135
+ get minMintSize() {
136
+ return this.account.minMintSize;
137
+ }
138
+ get minRedeemSize() {
139
+ return this.account.minRedeemSize;
140
+ }
141
+ get mintBase() {
142
+ return this.state.mintBase;
143
+ }
144
+ get tokenProgramBase() {
145
+ return this.state.tokenProgramBase;
146
+ }
147
+ get tokenBaseAccountAuthority() {
148
+ return (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintBase, this.selfAddress, true, this.tokenProgramBase);
149
+ }
150
+ get bankLiquidityVault() {
151
+ return mfiPda.getBankLiquidityVault(this.marginfiBank, this.state.marginfiProgramId);
152
+ }
153
+ get bankLiquidityVaultAuthority() {
154
+ return mfiPda.getBankLiquidityVaultAuthority(this.marginfiBank, this.state.marginfiProgramId);
155
+ }
156
+ get marginfiEmissionsAuth() {
157
+ // if there is no emissions mint, return undefined
158
+ if (!this.state.emissionsMint) {
159
+ return undefined;
160
+ }
161
+ return mfiPda.getMarginfiEmissionsAuth(this.marginfiBank, this.state.emissionsMint, this.state.marginfiProgramId);
162
+ }
163
+ get marginfiEmissionsVault() {
164
+ // if there is no emissions mint, return undefined
165
+ if (!this.state.emissionsMint) {
166
+ return undefined;
167
+ }
168
+ return mfiPda.getMarginfiEmissionsVault(this.marginfiBank, this.state.emissionsMint, this.state.marginfiProgramId);
169
+ }
170
+ get marginfiGroup() {
171
+ return this.state.marginfiGroupId;
172
+ }
173
+ get marginfiProgram() {
174
+ return this.state.marginfiProgramId;
175
+ }
176
+ get hasEmission() {
177
+ return !!this.state.emissionsMint;
178
+ }
179
+ ixMintSy({ depositor, amountBase, baseSrc, syDst, }) {
180
+ baseSrc = baseSrc || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintBase, depositor, true, this.state.tokenProgramBase);
181
+ syDst = syDst || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintSy, depositor, true, spl_token_1.TOKEN_PROGRAM_ID);
182
+ const emissionDst = this.state.emissionsMint
183
+ ? (0, spl_token_1.getAssociatedTokenAddressSync)(this.state.emissionsMint, this.selfAddress, true, spl_token_1.TOKEN_PROGRAM_ID)
184
+ : this.program.programId;
185
+ return this.program.methods
186
+ .mint(new anchor_1.BN(amountBase))
187
+ .accountsStrict({
188
+ depositor,
189
+ meta: this.selfAddress,
190
+ mintSy: this.mintSy,
191
+ tokenBaseDepositor: baseSrc,
192
+ tokenSyDepositor: syDst,
193
+ tokenBaseAccountAuthority: this.tokenBaseAccountAuthority,
194
+ marginfiAccount: this.marginfiAccount,
195
+ marginfiBank: this.marginfiBank,
196
+ bankLiquidityVault: this.bankLiquidityVault,
197
+ marginfiGroup: this.marginfiGroup,
198
+ marginfiProgram: this.marginfiProgram,
199
+ baseTokenProgram: this.tokenProgramBase,
200
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
201
+ mintEmission: this.state.emissionsMint || this.program.programId,
202
+ emissionDst,
203
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
204
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
205
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
206
+ mintBase: this.mintBase,
207
+ })
208
+ .instruction();
209
+ }
210
+ ixRedeemSy({ redeemer, amountSy, baseDst, sySrc, }) {
211
+ baseDst = baseDst || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintBase, redeemer, true, this.state.tokenProgramBase);
212
+ sySrc = sySrc || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintSy, redeemer, true, spl_token_1.TOKEN_PROGRAM_ID);
213
+ const remainingAccounts = [
214
+ {
215
+ pubkey: this.marginfiBank,
216
+ isWritable: true,
217
+ isSigner: false,
218
+ },
219
+ // It's ok to hardcode the pyth feed because we have no liabilities
220
+ {
221
+ pubkey: PYTH_USDC_FEED_ID,
222
+ isWritable: false,
223
+ isSigner: false,
224
+ },
225
+ ];
226
+ const emissionDst = this.state.emissionsMint
227
+ ? (0, spl_token_1.getAssociatedTokenAddressSync)(this.state.emissionsMint, this.selfAddress, true, spl_token_1.TOKEN_PROGRAM_ID)
228
+ : this.program.programId;
229
+ return this.program.methods
230
+ .redeem(new anchor_1.BN(amountSy))
231
+ .accountsStrict({
232
+ signer: redeemer,
233
+ meta: this.selfAddress,
234
+ mintSy: this.mintSy,
235
+ tokenBaseDst: baseDst,
236
+ tokenSySigner: sySrc,
237
+ bankLiquidityVaultAuthority: this.bankLiquidityVaultAuthority,
238
+ marginfiAccount: this.marginfiAccount,
239
+ marginfiBank: this.marginfiBank,
240
+ bankLiquidityVault: this.bankLiquidityVault,
241
+ marginfiGroup: this.marginfiGroup,
242
+ marginfiProgram: this.marginfiProgram,
243
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
244
+ tokenBaseProgram: this.tokenProgramBase,
245
+ tokenBaseAccountAuthority: this.tokenBaseAccountAuthority,
246
+ mintEmission: this.state.emissionsMint || this.program.programId,
247
+ emissionDst: this.state.emissionsMint ? emissionDst : this.program.programId,
248
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
249
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
250
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
251
+ mintBase: this.mintBase,
252
+ })
253
+ .remainingAccounts(remainingAccounts)
254
+ .instruction();
255
+ }
256
+ ixInitializePosition({ owner, feePayer }) {
257
+ return this.program.methods
258
+ .initializePosition()
259
+ .accountsStrict({
260
+ owner,
261
+ feePayer,
262
+ meta: this.selfAddress,
263
+ position: this.pda.position({ bank: this.marginfiBank, signer: owner }),
264
+ systemProgram: anchor_1.web3.SystemProgram.programId,
265
+ })
266
+ .instruction();
267
+ }
268
+ ixDeposit({ depositor, amountSy, emissionDst, sySrc, }) {
269
+ emissionDst = emissionDst || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintSy, depositor, true, spl_token_1.TOKEN_PROGRAM_ID);
270
+ sySrc = sySrc || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintSy, depositor, true, spl_token_1.TOKEN_PROGRAM_ID);
271
+ return this.program.methods
272
+ .deposit(new anchor_1.BN(amountSy))
273
+ .accountsStrict({
274
+ marginfiAccount: this.marginfiAccount,
275
+ marginfiBank: this.marginfiBank,
276
+ depositor,
277
+ emissionDst: this.state.emissionsMint ? emissionDst : this.program.programId,
278
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
279
+ marginfiGroup: this.marginfiGroup,
280
+ marginfiProgram: this.marginfiProgram,
281
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
282
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
283
+ meta: this.selfAddress,
284
+ mintEmission: this.state.emissionsMint || this.program.programId,
285
+ mintSy: this.mintSy,
286
+ position: this.pda.position({ bank: this.marginfiBank, signer: depositor }),
287
+ systemProgram: anchor_1.web3.SystemProgram.programId,
288
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
289
+ tokenSyDepositor: sySrc,
290
+ tokenSyEscrow: this.tokenSyEscrow,
291
+ })
292
+ .instruction();
293
+ }
294
+ ixWithdraw({ signer, amountSy, syDst }) {
295
+ syDst = syDst || (0, spl_token_1.getAssociatedTokenAddressSync)(this.mintSy, signer, true, spl_token_1.TOKEN_PROGRAM_ID);
296
+ const tokenEmissionAuthorityMfiAccount = this.hasEmission
297
+ ? (0, spl_token_1.getAssociatedTokenAddressSync)(this.state.emissionsMint, this.selfAddress, true, spl_token_1.TOKEN_PROGRAM_ID)
298
+ : this.program.programId;
299
+ return this.program.methods
300
+ .withdraw(new anchor_1.BN(amountSy))
301
+ .accountsStrict({
302
+ marginfiAccount: this.marginfiAccount,
303
+ marginfiBank: this.marginfiBank,
304
+ owner: signer,
305
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
306
+ marginfiGroup: this.marginfiGroup,
307
+ marginfiProgram: this.marginfiProgram,
308
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
309
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
310
+ meta: this.selfAddress,
311
+ mintEmission: this.state.emissionsMint || this.program.programId,
312
+ mintSy: this.mintSy,
313
+ position: this.pda.position({ bank: this.marginfiBank, signer }),
314
+ systemProgram: anchor_1.web3.SystemProgram.programId,
315
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
316
+ tokenSyEscrow: this.tokenSyEscrow,
317
+ tokenEmissionAuthorityMfiAccount,
318
+ tokenSyDst: syDst,
319
+ })
320
+ .instruction();
321
+ }
322
+ ixCollectEmission({ owner, index, emissionDst, amount, }) {
323
+ const emission = this.state.account.emissions[index];
324
+ emissionDst = emissionDst || (0, spl_token_1.getAssociatedTokenAddressSync)(emission.mint, owner, true, emission.tokenProgram);
325
+ const claimAmount = amount ? { some: { 0: new anchor_1.BN(amount) } } : { all: {} };
326
+ return this.program.methods.collectEmission(claimAmount).accountsStrict({
327
+ meta: this.selfAddress,
328
+ owner,
329
+ position: this.pda.position({ bank: this.marginfiBank, signer: owner }),
330
+ tokenEmissionAccountAuthority: emission.escrowAccount,
331
+ tokenEmissionSigner: emissionDst,
332
+ tokenProgram: emission.tokenProgram,
333
+ });
334
+ }
335
+ }
336
+ exports.MfiSySdk = MfiSySdk;
337
+ const BANK_CONFIG_OFFSET = 8 + 288;
338
+ // Offset in `bank_config` for `oracle_keys`
339
+ const BANK_CONFI_ORACLE_KEYS_OFFSET = 314;
340
+ const MAX_ORACLE_KEYS = 5;
341
+ async function fetchBank(address, connection) {
342
+ const d = await connection.getAccountInfo(address);
343
+ if (!d) {
344
+ throw new Error("Bank not found");
345
+ }
346
+ const assetShareValueOffset = 8 + 32 + 1 + 32 + 7;
347
+ const baseMintBuf = d.data.subarray(8, 8 + 32);
348
+ const assetShareValueBuf = d.data.subarray(assetShareValueOffset, assetShareValueOffset + 16);
349
+ const assetShareValue = (0, i80f48_util_1.decodeBufferLE)(assetShareValueBuf);
350
+ const baseMint = new anchor_1.web3.PublicKey(baseMintBuf);
351
+ const emissionsMintBuf = d.data.subarray(960, 960 + 32);
352
+ const oracleKeysBuf = d.data.subarray(BANK_CONFIG_OFFSET + BANK_CONFI_ORACLE_KEYS_OFFSET, BANK_CONFIG_OFFSET + BANK_CONFI_ORACLE_KEYS_OFFSET + 32 * MAX_ORACLE_KEYS);
353
+ let emissionsMint = new anchor_1.web3.PublicKey(emissionsMintBuf);
354
+ let emissionTokenProgram;
355
+ // if emissions mint is publickey.default, then it should be null
356
+ if (emissionsMint.equals(anchor_1.web3.PublicKey.default)) {
357
+ emissionsMint = null;
358
+ }
359
+ else {
360
+ // fetch the token program for the emissions mint by doing accountinfo.owner
361
+ const accountInfo = await connection.getAccountInfo(emissionsMint);
362
+ emissionTokenProgram = accountInfo?.owner;
363
+ }
364
+ return {
365
+ baseMint,
366
+ assetShareValue,
367
+ emissionsMint,
368
+ emissionTokenProgram,
369
+ };
370
+ }
371
+ exports.fetchBank = fetchBank;
372
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/build/tryit.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const anchor_1 = require("@coral-xyz/anchor");
4
+ const _1 = require(".");
5
+ async function main() {
6
+ const cnx = new anchor_1.web3.Connection("https://api.mainnet-beta.solana.com");
7
+ const MARGINFI_BANK_ID = new anchor_1.web3.PublicKey("2s37akK2eyBbp8DZgCm7RtsaEz8eJP3Nxd4urLHQv7yB");
8
+ const MARGINFI_STANDARD_PROGRAM_ID = new anchor_1.web3.PublicKey("A6xmgU7Qi9voAU1AQEwoMK5awmAd2ohFNDJZMB1eUSY3");
9
+ const sdk = await _1.MfiSySdk.load({
10
+ cnx,
11
+ mfiBank: MARGINFI_BANK_ID,
12
+ mfiSyProgramId: MARGINFI_STANDARD_PROGRAM_ID,
13
+ });
14
+ console.log(sdk);
15
+ }
16
+ main()
17
+ .then(() => console.log("done"))
18
+ .catch((err) => console.error(err));
19
+ //# sourceMappingURL=tryit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryit.js","sourceRoot":"","sources":["../src/tryit.ts"],"names":[],"mappings":";;AAAA,8CAAwC;AACxC,wBAA4B;AAE5B,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,IAAI,aAAI,CAAC,UAAU,CAAC,qCAAqC,CAAC,CAAA;IACtE,MAAM,gBAAgB,GAAG,IAAI,aAAI,CAAC,SAAS,CAAC,8CAA8C,CAAC,CAAA;IAC3F,MAAM,4BAA4B,GAAG,IAAI,aAAI,CAAC,SAAS,CAAC,8CAA8C,CAAC,CAAA;IAEvG,MAAM,GAAG,GAAG,MAAM,WAAQ,CAAC,IAAI,CAAC;QAC9B,GAAG;QACH,OAAO,EAAE,gBAAgB;QACzB,cAAc,EAAE,4BAA4B;KAC7C,CAAC,CAAA;IAEF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAClB,CAAC;AAED,IAAI,EAAE;KACH,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;KAC/B,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@exponent-labs/marginfi-sy-sdk",
3
+ "version": "0.0.3",
4
+ "main": "build/index.js",
5
+ "types": "build/index.d.ts",
6
+ "license": "AGPL-3.0",
7
+ "scripts": {
8
+ "build": "tsc --build",
9
+ "tryit": "ts-node src/tryit.ts"
10
+ },
11
+ "dependencies": {
12
+ "@coral-xyz/anchor": "^0.30.1",
13
+ "@exponent-labs/exponent-fetcher": "^0.0.3",
14
+ "@exponent-labs/i80f48-util": "^0.0.3",
15
+ "@exponent-labs/marginfi-pda": "^0.0.3",
16
+ "@exponent-labs/marginfi-sy-idl": "^0.0.3",
17
+ "@exponent-labs/marginfi-sy-pda": "^0.0.3",
18
+ "@exponent-labs/precise-number": "^0.0.3",
19
+ "@solana/spl-token": "^0.4.6"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.4.5"
23
+ },
24
+ "gitHead": "209b8847e9a0fadb5b5ec96b9b47f0ace4a3bf9d"
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1,464 @@
1
+ import { AnchorProvider, BN, Program, web3 } from "@coral-xyz/anchor"
2
+ import { IDL, MarginfiStandard } from "@exponent-labs/marginfi-sy-idl"
3
+ import { MarginfiSyPda } from "@exponent-labs/marginfi-sy-pda"
4
+ import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"
5
+ import * as mfiPda from "@exponent-labs/marginfi-pda"
6
+ import { ExponentFetcher, MyWallet } from "@exponent-labs/exponent-fetcher"
7
+ import * as c from "@exponent-labs/constants"
8
+ import { MfiSyState, SyMetaJson } from "@exponent-labs/exponent-types"
9
+ import { PreciseNumber } from "@exponent-labs/precise-number"
10
+ import { decodeBufferLE } from "@exponent-labs/i80f48-util"
11
+
12
+ const MARGINFI_GROUP_ID = new web3.PublicKey("4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8")
13
+ const MARGINFI_PROGRAM_ID = new web3.PublicKey("MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA")
14
+ const PYTH_USDC_FEED_ID = new web3.PublicKey("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD")
15
+
16
+ function toJson(m: MfiSySdk): SyMetaJson {
17
+ return {
18
+ selfAddress: m.selfAddress.toBase58(),
19
+ marginfiBank: m.marginfiBank.toBase58(),
20
+ marginfiAccount: m.marginfiAccount.toBase58(),
21
+ mintSy: m.mintSy.toBase58(),
22
+ tokenSyEscrow: m.tokenSyEscrow.toBase58(),
23
+ emissions: m.account.emissions.map((e) => ({
24
+ mint: e.mint.toBase58(),
25
+ tokenProgram: e.tokenProgram.toBase58(),
26
+ escrowAccount: e.escrowAccount.toBase58(),
27
+ index: parseFloat(PreciseNumber.fromRaw(e.index[0]).valueString),
28
+ lastSeenIndex: parseFloat(PreciseNumber.fromRaw(e.lastSeenIndex[0]).valueString),
29
+ lastSeenTotalAccruedEmissions: e.lastSeenTotalAccruedEmissions.toString(),
30
+ totalClaimedEmissions: e.totalClaimedEmissions.toString(),
31
+ treasuryEmission: e.treasuryEmission.toString(),
32
+ })),
33
+ maxSySupply: m.maxSySupply.toString(),
34
+ minMintSize: m.minMintSize.toString(),
35
+ minRedeemSize: m.minRedeemSize.toString(),
36
+ syRate: m.state.syRate,
37
+ }
38
+ }
39
+
40
+ export type ClaimAmount = { all: {} } | { some: { 0: BN } }
41
+
42
+ async function loadAccountState({
43
+ cnx,
44
+ mfiBank,
45
+ mfiSyProgramId,
46
+ }: {
47
+ cnx: web3.Connection
48
+ mfiBank: web3.PublicKey
49
+ mfiSyProgramId: web3.PublicKey
50
+ }) {
51
+ const pda = new MarginfiSyPda(mfiSyProgramId)
52
+ const fetcher = new ExponentFetcher({ connection: cnx, marginfiSyProgramId: mfiSyProgramId })
53
+ const syMetaAddress = pda.syMeta({ bank: mfiBank })
54
+ const data = await fetcher.fetchMarginfiSyMeta(syMetaAddress)
55
+ return data
56
+ }
57
+
58
+ export class MfiSySdk {
59
+ /** Private program for building instructions */
60
+ private program: Program<MarginfiStandard>
61
+
62
+ public pda: MarginfiSyPda
63
+
64
+ constructor(public state: MfiSyState) {
65
+ // create a fake AnchorProvider -- which is unused
66
+ this.program = new Program<MarginfiStandard>(
67
+ IDL as MarginfiStandard,
68
+ new AnchorProvider(new web3.Connection("https://api.devnet.solana.com"), new MyWallet(web3.Keypair.generate())),
69
+ )
70
+
71
+ this.pda = new MarginfiSyPda(state.marginfiSyProgramId)
72
+ }
73
+
74
+ /** Load an instance of SyMeta */
75
+ static async load({
76
+ cnx,
77
+ mfiBank,
78
+ mfiSyProgramId,
79
+ mfiProgramId = MARGINFI_PROGRAM_ID,
80
+ mfiGroupId = new web3.PublicKey(MARGINFI_GROUP_ID),
81
+ }: {
82
+ cnx: web3.Connection
83
+ mfiBank: web3.PublicKey
84
+ mfiSyProgramId: web3.PublicKey
85
+ mfiProgramId?: web3.PublicKey
86
+ mfiGroupId?: web3.PublicKey
87
+ }) {
88
+ const account = await loadAccountState({ cnx, mfiBank, mfiSyProgramId })
89
+ const b = await fetchBank(mfiBank, cnx)
90
+ const baseMintAi = await cnx.getAccountInfo(b.baseMint)
91
+ const tokenProgramBase = baseMintAi.owner
92
+ const selfAddress = new MarginfiSyPda(mfiSyProgramId).syMeta({ bank: mfiBank })
93
+
94
+ const state: MfiSyState = {
95
+ marginfiProgramId: mfiProgramId,
96
+ marginfiGroupId: mfiGroupId,
97
+ selfAddress,
98
+ account,
99
+ marginfiSyProgramId: mfiSyProgramId,
100
+ mintBase: b.baseMint,
101
+ tokenProgramBase,
102
+ emissionsMint: b.emissionsMint,
103
+ emissionsTokenProgram: b.emissionTokenProgram,
104
+ syRate: b.assetShareValue,
105
+ }
106
+
107
+ return new MfiSySdk(state)
108
+ }
109
+
110
+ /** Reload the state of the account */
111
+ async reload(cnx: web3.Connection) {
112
+ const b = await fetchBank(this.marginfiBank, cnx)
113
+ const account = await loadAccountState({
114
+ cnx,
115
+ mfiBank: this.marginfiBank,
116
+ mfiSyProgramId: this.state.marginfiSyProgramId,
117
+ })
118
+ this.state.account = account
119
+ this.state.syRate = b.assetShareValue
120
+ }
121
+
122
+ toJson() {
123
+ return toJson(this)
124
+ }
125
+
126
+ get selfAddress() {
127
+ return this.state.selfAddress
128
+ }
129
+
130
+ get account() {
131
+ return this.state.account
132
+ }
133
+
134
+ get mintSy() {
135
+ return this.account.mintSy
136
+ }
137
+
138
+ get marginfiBank() {
139
+ return this.account.marginfiBank
140
+ }
141
+
142
+ get marginfiAccount() {
143
+ return this.account.marginfiAccount
144
+ }
145
+
146
+ get tokenSyEscrow() {
147
+ return this.account.tokenSyEscrow
148
+ }
149
+
150
+ get maxSySupply() {
151
+ return this.account.maxSySupply
152
+ }
153
+
154
+ get minMintSize() {
155
+ return this.account.minMintSize
156
+ }
157
+
158
+ get minRedeemSize() {
159
+ return this.account.minRedeemSize
160
+ }
161
+
162
+ get mintBase() {
163
+ return this.state.mintBase
164
+ }
165
+
166
+ get tokenProgramBase() {
167
+ return this.state.tokenProgramBase
168
+ }
169
+
170
+ get tokenBaseAccountAuthority() {
171
+ return getAssociatedTokenAddressSync(this.mintBase, this.selfAddress, true, this.tokenProgramBase)
172
+ }
173
+
174
+ get bankLiquidityVault() {
175
+ return mfiPda.getBankLiquidityVault(this.marginfiBank, this.state.marginfiProgramId)
176
+ }
177
+
178
+ get bankLiquidityVaultAuthority() {
179
+ return mfiPda.getBankLiquidityVaultAuthority(this.marginfiBank, this.state.marginfiProgramId)
180
+ }
181
+
182
+ get marginfiEmissionsAuth() {
183
+ // if there is no emissions mint, return undefined
184
+ if (!this.state.emissionsMint) {
185
+ return undefined
186
+ }
187
+
188
+ return mfiPda.getMarginfiEmissionsAuth(this.marginfiBank, this.state.emissionsMint, this.state.marginfiProgramId)
189
+ }
190
+
191
+ get marginfiEmissionsVault() {
192
+ // if there is no emissions mint, return undefined
193
+ if (!this.state.emissionsMint) {
194
+ return undefined
195
+ }
196
+
197
+ return mfiPda.getMarginfiEmissionsVault(this.marginfiBank, this.state.emissionsMint, this.state.marginfiProgramId)
198
+ }
199
+
200
+ get marginfiGroup() {
201
+ return this.state.marginfiGroupId
202
+ }
203
+
204
+ get marginfiProgram() {
205
+ return this.state.marginfiProgramId
206
+ }
207
+
208
+ get hasEmission() {
209
+ return !!this.state.emissionsMint
210
+ }
211
+
212
+ ixMintSy({
213
+ depositor,
214
+ amountBase,
215
+ baseSrc,
216
+ syDst,
217
+ }: {
218
+ depositor: web3.PublicKey
219
+ amountBase: string
220
+ baseSrc?: web3.PublicKey
221
+ syDst?: web3.PublicKey
222
+ }) {
223
+ baseSrc = baseSrc || getAssociatedTokenAddressSync(this.mintBase, depositor, true, this.state.tokenProgramBase)
224
+ syDst = syDst || getAssociatedTokenAddressSync(this.mintSy, depositor, true, TOKEN_PROGRAM_ID)
225
+
226
+ const emissionDst = this.state.emissionsMint
227
+ ? getAssociatedTokenAddressSync(this.state.emissionsMint, this.selfAddress, true, TOKEN_PROGRAM_ID)
228
+ : this.program.programId
229
+
230
+ return this.program.methods
231
+ .mint(new BN(amountBase))
232
+ .accountsStrict({
233
+ depositor,
234
+ meta: this.selfAddress,
235
+ mintSy: this.mintSy,
236
+ tokenBaseDepositor: baseSrc,
237
+ tokenSyDepositor: syDst,
238
+ tokenBaseAccountAuthority: this.tokenBaseAccountAuthority,
239
+ marginfiAccount: this.marginfiAccount,
240
+ marginfiBank: this.marginfiBank,
241
+ bankLiquidityVault: this.bankLiquidityVault,
242
+ marginfiGroup: this.marginfiGroup,
243
+ marginfiProgram: this.marginfiProgram,
244
+ baseTokenProgram: this.tokenProgramBase,
245
+ tokenProgram: TOKEN_PROGRAM_ID,
246
+ mintEmission: this.state.emissionsMint || this.program.programId,
247
+ emissionDst,
248
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
249
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
250
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
251
+ mintBase: this.mintBase,
252
+ })
253
+ .instruction()
254
+ }
255
+
256
+ ixRedeemSy({
257
+ redeemer,
258
+ amountSy,
259
+ baseDst,
260
+ sySrc,
261
+ }: {
262
+ redeemer: web3.PublicKey
263
+ amountSy: string
264
+ baseDst?: web3.PublicKey
265
+ sySrc?: web3.PublicKey
266
+ }) {
267
+ baseDst = baseDst || getAssociatedTokenAddressSync(this.mintBase, redeemer, true, this.state.tokenProgramBase)
268
+ sySrc = sySrc || getAssociatedTokenAddressSync(this.mintSy, redeemer, true, TOKEN_PROGRAM_ID)
269
+
270
+ const remainingAccounts = [
271
+ {
272
+ pubkey: this.marginfiBank,
273
+ isWritable: true,
274
+ isSigner: false,
275
+ },
276
+ // It's ok to hardcode the pyth feed because we have no liabilities
277
+ {
278
+ pubkey: PYTH_USDC_FEED_ID,
279
+ isWritable: false,
280
+ isSigner: false,
281
+ },
282
+ ]
283
+
284
+ const emissionDst = this.state.emissionsMint
285
+ ? getAssociatedTokenAddressSync(this.state.emissionsMint, this.selfAddress, true, TOKEN_PROGRAM_ID)
286
+ : this.program.programId
287
+
288
+ return this.program.methods
289
+ .redeem(new BN(amountSy))
290
+ .accountsStrict({
291
+ signer: redeemer,
292
+ meta: this.selfAddress,
293
+ mintSy: this.mintSy,
294
+ tokenBaseDst: baseDst,
295
+ tokenSySigner: sySrc,
296
+ bankLiquidityVaultAuthority: this.bankLiquidityVaultAuthority,
297
+ marginfiAccount: this.marginfiAccount,
298
+ marginfiBank: this.marginfiBank,
299
+ bankLiquidityVault: this.bankLiquidityVault,
300
+ marginfiGroup: this.marginfiGroup,
301
+ marginfiProgram: this.marginfiProgram,
302
+ tokenProgram: TOKEN_PROGRAM_ID,
303
+ tokenBaseProgram: this.tokenProgramBase,
304
+ tokenBaseAccountAuthority: this.tokenBaseAccountAuthority,
305
+ mintEmission: this.state.emissionsMint || this.program.programId,
306
+ emissionDst: this.state.emissionsMint ? emissionDst : this.program.programId,
307
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
308
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
309
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
310
+ mintBase: this.mintBase,
311
+ })
312
+ .remainingAccounts(remainingAccounts)
313
+ .instruction()
314
+ }
315
+
316
+ ixInitializePosition({ owner, feePayer }: { owner: web3.PublicKey; feePayer: web3.PublicKey }) {
317
+ return this.program.methods
318
+ .initializePosition()
319
+ .accountsStrict({
320
+ owner,
321
+ feePayer,
322
+ meta: this.selfAddress,
323
+ position: this.pda.position({ bank: this.marginfiBank, signer: owner }),
324
+ systemProgram: web3.SystemProgram.programId,
325
+ })
326
+ .instruction()
327
+ }
328
+
329
+ ixDeposit({
330
+ depositor,
331
+ amountSy,
332
+ emissionDst,
333
+ sySrc,
334
+ }: {
335
+ depositor: web3.PublicKey
336
+ amountSy: string
337
+ emissionDst?: web3.PublicKey
338
+ sySrc?: web3.PublicKey
339
+ }) {
340
+ emissionDst = emissionDst || getAssociatedTokenAddressSync(this.mintSy, depositor, true, TOKEN_PROGRAM_ID)
341
+ sySrc = sySrc || getAssociatedTokenAddressSync(this.mintSy, depositor, true, TOKEN_PROGRAM_ID)
342
+
343
+ return this.program.methods
344
+ .deposit(new BN(amountSy))
345
+ .accountsStrict({
346
+ marginfiAccount: this.marginfiAccount,
347
+ marginfiBank: this.marginfiBank,
348
+ depositor,
349
+ emissionDst: this.state.emissionsMint ? emissionDst : this.program.programId,
350
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
351
+ marginfiGroup: this.marginfiGroup,
352
+ marginfiProgram: this.marginfiProgram,
353
+ tokenProgram: TOKEN_PROGRAM_ID,
354
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
355
+ meta: this.selfAddress,
356
+ mintEmission: this.state.emissionsMint || this.program.programId,
357
+ mintSy: this.mintSy,
358
+ position: this.pda.position({ bank: this.marginfiBank, signer: depositor }),
359
+ systemProgram: web3.SystemProgram.programId,
360
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
361
+ tokenSyDepositor: sySrc,
362
+ tokenSyEscrow: this.tokenSyEscrow,
363
+ })
364
+ .instruction()
365
+ }
366
+
367
+ ixWithdraw({ signer, amountSy, syDst }: { signer: web3.PublicKey; amountSy: string; syDst?: web3.PublicKey }) {
368
+ syDst = syDst || getAssociatedTokenAddressSync(this.mintSy, signer, true, TOKEN_PROGRAM_ID)
369
+ const tokenEmissionAuthorityMfiAccount = this.hasEmission
370
+ ? getAssociatedTokenAddressSync(this.state.emissionsMint, this.selfAddress, true, TOKEN_PROGRAM_ID)
371
+ : this.program.programId
372
+
373
+ return this.program.methods
374
+ .withdraw(new BN(amountSy))
375
+ .accountsStrict({
376
+ marginfiAccount: this.marginfiAccount,
377
+ marginfiBank: this.marginfiBank,
378
+ owner: signer,
379
+ marginfiEmissionsAuth: this.marginfiEmissionsAuth || this.program.programId,
380
+ marginfiGroup: this.marginfiGroup,
381
+ marginfiProgram: this.marginfiProgram,
382
+ tokenProgram: TOKEN_PROGRAM_ID,
383
+ marginfiEmissionsVault: this.marginfiEmissionsVault || this.program.programId,
384
+ meta: this.selfAddress,
385
+ mintEmission: this.state.emissionsMint || this.program.programId,
386
+ mintSy: this.mintSy,
387
+ position: this.pda.position({ bank: this.marginfiBank, signer }),
388
+ systemProgram: web3.SystemProgram.programId,
389
+ tokenProgramEmission: this.state.emissionsTokenProgram || this.program.programId,
390
+ tokenSyEscrow: this.tokenSyEscrow,
391
+ tokenEmissionAuthorityMfiAccount,
392
+ tokenSyDst: syDst,
393
+ })
394
+ .instruction()
395
+ }
396
+
397
+ ixCollectEmission({
398
+ owner,
399
+ index,
400
+ emissionDst,
401
+ amount,
402
+ }: {
403
+ owner: web3.PublicKey
404
+ index: number
405
+ emissionDst?: web3.PublicKey
406
+ amount?: string
407
+ }) {
408
+ const emission = this.state.account.emissions[index]
409
+ emissionDst = emissionDst || getAssociatedTokenAddressSync(emission.mint, owner, true, emission.tokenProgram)
410
+
411
+ const claimAmount: ClaimAmount = amount ? { some: { 0: new BN(amount) } } : { all: {} }
412
+
413
+ return this.program.methods.collectEmission(claimAmount).accountsStrict({
414
+ meta: this.selfAddress,
415
+ owner,
416
+ position: this.pda.position({ bank: this.marginfiBank, signer: owner }),
417
+ tokenEmissionAccountAuthority: emission.escrowAccount,
418
+ tokenEmissionSigner: emissionDst,
419
+ tokenProgram: emission.tokenProgram,
420
+ })
421
+ }
422
+ }
423
+
424
+ const BANK_CONFIG_OFFSET = 8 + 288
425
+ // Offset in `bank_config` for `oracle_keys`
426
+ const BANK_CONFI_ORACLE_KEYS_OFFSET = 314
427
+ const MAX_ORACLE_KEYS = 5
428
+
429
+ export async function fetchBank(address: web3.PublicKey, connection: web3.Connection) {
430
+ const d = await connection.getAccountInfo(address)
431
+ if (!d) {
432
+ throw new Error("Bank not found")
433
+ }
434
+
435
+ const assetShareValueOffset = 8 + 32 + 1 + 32 + 7
436
+ const baseMintBuf = d.data.subarray(8, 8 + 32)
437
+ const assetShareValueBuf = d.data.subarray(assetShareValueOffset, assetShareValueOffset + 16)
438
+ const assetShareValue = decodeBufferLE(assetShareValueBuf)
439
+ const baseMint = new web3.PublicKey(baseMintBuf)
440
+ const emissionsMintBuf = d.data.subarray(960, 960 + 32)
441
+
442
+ const oracleKeysBuf = d.data.subarray(
443
+ BANK_CONFIG_OFFSET + BANK_CONFI_ORACLE_KEYS_OFFSET,
444
+ BANK_CONFIG_OFFSET + BANK_CONFI_ORACLE_KEYS_OFFSET + 32 * MAX_ORACLE_KEYS,
445
+ )
446
+
447
+ let emissionsMint: web3.PublicKey | null = new web3.PublicKey(emissionsMintBuf)
448
+ let emissionTokenProgram: web3.PublicKey | null
449
+ // if emissions mint is publickey.default, then it should be null
450
+ if (emissionsMint.equals(web3.PublicKey.default)) {
451
+ emissionsMint = null
452
+ } else {
453
+ // fetch the token program for the emissions mint by doing accountinfo.owner
454
+ const accountInfo = await connection.getAccountInfo(emissionsMint)
455
+ emissionTokenProgram = accountInfo?.owner
456
+ }
457
+
458
+ return {
459
+ baseMint,
460
+ assetShareValue,
461
+ emissionsMint,
462
+ emissionTokenProgram,
463
+ }
464
+ }
package/src/tryit.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { web3 } from "@coral-xyz/anchor"
2
+ import { MfiSySdk } from "."
3
+
4
+ async function main() {
5
+ const cnx = new web3.Connection("https://api.mainnet-beta.solana.com")
6
+ const MARGINFI_BANK_ID = new web3.PublicKey("2s37akK2eyBbp8DZgCm7RtsaEz8eJP3Nxd4urLHQv7yB")
7
+ const MARGINFI_STANDARD_PROGRAM_ID = new web3.PublicKey("A6xmgU7Qi9voAU1AQEwoMK5awmAd2ohFNDJZMB1eUSY3")
8
+
9
+ const sdk = await MfiSySdk.load({
10
+ cnx,
11
+ mfiBank: MARGINFI_BANK_ID,
12
+ mfiSyProgramId: MARGINFI_STANDARD_PROGRAM_ID,
13
+ })
14
+
15
+ console.log(sdk)
16
+ }
17
+
18
+ main()
19
+ .then(() => console.log("done"))
20
+ .catch((err) => console.error(err))
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "src",
4
+ "sourceMap": true,
5
+ "incremental": true /* Save .tsbuildinfo files to allow for incremental compilation of projects. */,
6
+ "composite": true /* Enable constraints that allow a TypeScript project to be used with project references. */,
7
+ "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
8
+ "module": "CommonJS" /* Specify what module code is generated. */,
9
+ "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
10
+ "outDir": "./build" /* Specify an output folder for all emitted files. */,
11
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
12
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
13
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */,
14
+ "resolveJsonModule": true
15
+ },
16
+ "include": ["src/**/*.ts", "src/**/*.json"],
17
+ "exclude": ["node_modules", "build"],
18
+ "references": [
19
+ { "path": "../marginfi-pda" },
20
+ { "path": "../marginfi-sy-pda" },
21
+ { "path": "../marginfi-sy-idl" },
22
+ { "path": "../i80f48-util" },
23
+ { "path": "../precise-number" },
24
+ { "path": "../exponent-fetcher" }
25
+ ]
26
+ }