11import { Connection , PublicKey } from '@solana/web3.js' ;
22import BN from 'bn.js' ;
3- import { EXT_PROGRAM_ID , PROGRAM_ID } from '. ' ;
4- import { getProgram , getExtProgram } from '. /idl' ;
3+ import { BorshAccountsCoder , Idl } from '@coral-xyz/anchor ' ;
4+ import { IdlDefinedFields } from '@coral-xyz/anchor/dist/cjs /idl' ;
55
66export interface EarnManagerData {
77 isActive : boolean ;
@@ -13,49 +13,213 @@ export interface EarnManagerData {
1313
1414export interface GlobalAccountData {
1515 admin : PublicKey ;
16- earnAuthority ?: PublicKey ;
17- mint : PublicKey ;
18- underlyingMint ?: PublicKey ;
16+ extMint : PublicKey ;
17+ mMint : PublicKey ;
18+ variant : 'Crank' | 'ScaledUi' | 'NoYield' ;
19+ wrapAuthorities : PublicKey [ ] ;
20+
21+ // crank fields
1922 index ?: BN ;
2023 timestamp ?: BN ;
21- maxYield ?: BN ;
22- claimComplete ?: boolean ;
24+ earnAuthority ?: PublicKey ;
2325}
2426
2527export interface EarnerData {
26- user : PublicKey ;
2728 lastClaimIndex : BN ;
2829 lastClaimTimestamp : BN ;
2930 bump : number ;
31+ user : PublicKey ;
3032 userTokenAccount : PublicKey ;
31- earnManager ? : PublicKey | null ;
32- recipientTokenAccount ? : PublicKey | null ;
33+ earnManager : PublicKey ;
34+ recipientTokenAccount : PublicKey | null ;
3335}
3436
35- export async function loadGlobal ( connection : Connection , program = PROGRAM_ID ) : Promise < GlobalAccountData > {
37+ export async function loadGlobal ( connection : Connection , program : PublicKey ) : Promise < GlobalAccountData > {
3638 const [ globalAccount ] = PublicKey . findProgramAddressSync ( [ Buffer . from ( 'global' ) ] , program ) ;
3739
38- // $M
39- if ( program . equals ( PROGRAM_ID ) ) {
40- return await getProgram ( connection ) . account . global . fetch ( globalAccount ) ;
41- }
40+ // global account will differ depending on the program features
41+ const globalData = ( await connection . getAccountInfo ( globalAccount ) ) ! . data ;
4242
43- // wrapped $M
44- if ( program . equals ( EXT_PROGRAM_ID ) ) {
45- const extGlobal = await getExtProgram ( connection ) . account . extGlobal . fetch ( globalAccount ) ;
46- return {
47- ...extGlobal ,
48- mint : extGlobal . extMint ,
49- underlyingMint : extGlobal . mMint ,
50- } ;
43+ const yieldType = globalData [ 140 ] ;
44+ const decoder = yieldVariantsDecoder ( yieldType ) ;
45+ const global = decoder . decode ( 'ExtGlobalV2' , globalData ) ;
46+
47+ return {
48+ admin : global . admin ,
49+ extMint : global . ext_mint ,
50+ mMint : global . m_mint ,
51+ variant : Object . keys ( global . yield_config . yield_variant ) [ 0 ] as 'Crank' | 'ScaledUi' | 'NoYield' ,
52+ wrapAuthorities : global . wrap_authorities ,
53+ index : global . yield_config . index ,
54+ timestamp : global . yield_config . ts ,
55+ earnAuthority : global . yield_config . earn_authority ,
56+ } ;
57+ }
58+
59+ function yieldVariantsDecoder ( variant : number ) {
60+ return new BorshAccountsCoder ( extensionIDL ( variant ) ) ;
61+ }
62+
63+ function extensionIDL ( variant : number ) : Idl {
64+ if ( variant >= 3 ) {
65+ throw new Error ( 'Invalid yield variant, must be 0, 1, or 2' ) ;
5166 }
5267
53- // $M extension (global account will differ depending on the program features)
54- const globalData = ( await connection . getAccountInfo ( globalAccount ) ) ! . data ;
68+ const yieldVariants : IdlDefinedFields [ ] = [
69+ [
70+ {
71+ name : 'yield_variant' ,
72+ type : {
73+ defined : {
74+ name : 'YieldVariant' ,
75+ } ,
76+ } ,
77+ } ,
78+ ] ,
79+ [
80+ {
81+ name : 'yield_variant' ,
82+ type : {
83+ defined : {
84+ name : 'YieldVariant' ,
85+ } ,
86+ } ,
87+ } ,
88+ {
89+ name : 'fee_bps' ,
90+ type : 'u64' ,
91+ } ,
92+ {
93+ name : 'last_m_index' ,
94+ type : 'u64' ,
95+ } ,
96+ {
97+ name : 'last_ext_index' ,
98+ type : 'u64' ,
99+ } ,
100+ ] ,
101+ [
102+ {
103+ name : 'yield_variant' ,
104+ type : {
105+ defined : {
106+ name : 'YieldVariant' ,
107+ } ,
108+ } ,
109+ } ,
110+ {
111+ name : 'earn_authority' ,
112+ type : 'pubkey' ,
113+ } ,
114+ {
115+ name : 'index' ,
116+ type : 'u64' ,
117+ } ,
118+ {
119+ name : 'ts' ,
120+ type : 'u64' ,
121+ } ,
122+ ] ,
123+ ] ;
55124
56125 return {
57- admin : new PublicKey ( globalData . subarray ( 8 , 40 ) ) ,
58- mint : new PublicKey ( globalData . subarray ( 40 , 72 ) ) ,
59- underlyingMint : new PublicKey ( globalData . subarray ( 72 , 104 ) ) ,
126+ address : '' ,
127+ instructions : [ ] ,
128+ metadata : {
129+ name : '' ,
130+ version : '' ,
131+ spec : '' ,
132+ } ,
133+ accounts : [
134+ {
135+ name : 'ExtGlobalV2' ,
136+ discriminator : [ 116 , 209 , 219 , 83 , 70 , 143 , 55 , 127 ] ,
137+ } ,
138+ ] ,
139+ types : [
140+ {
141+ name : 'ExtGlobalV2' ,
142+ type : {
143+ kind : 'struct' ,
144+ fields : [
145+ {
146+ name : 'admin' ,
147+ type : 'pubkey' ,
148+ } ,
149+ {
150+ name : 'pending_admin' ,
151+ type : {
152+ option : 'pubkey' ,
153+ } ,
154+ } ,
155+ {
156+ name : 'ext_mint' ,
157+ type : 'pubkey' ,
158+ } ,
159+ {
160+ name : 'm_mint' ,
161+ type : 'pubkey' ,
162+ } ,
163+ {
164+ name : 'm_earn_global_account' ,
165+ type : 'pubkey' ,
166+ } ,
167+ {
168+ name : 'bump' ,
169+ type : 'u8' ,
170+ } ,
171+ {
172+ name : 'm_vault_bump' ,
173+ type : 'u8' ,
174+ } ,
175+ {
176+ name : 'ext_mint_authority_bump' ,
177+ type : 'u8' ,
178+ } ,
179+ {
180+ name : 'yield_config' ,
181+ type : {
182+ defined : {
183+ name : 'YieldConfig' ,
184+ } ,
185+ } ,
186+ } ,
187+ {
188+ name : 'wrap_authorities' ,
189+ type : {
190+ vec : 'pubkey' ,
191+ } ,
192+ } ,
193+ ] ,
194+ } ,
195+ } ,
196+ {
197+ name : 'YieldConfig' ,
198+ type : {
199+ kind : 'struct' ,
200+ fields : yieldVariants [ variant ] ,
201+ } ,
202+ } ,
203+ {
204+ name : 'YieldVariant' ,
205+ repr : {
206+ kind : 'rust' ,
207+ } ,
208+ type : {
209+ kind : 'enum' ,
210+ variants : [
211+ {
212+ name : 'NoYield' ,
213+ } ,
214+ {
215+ name : 'ScaledUi' ,
216+ } ,
217+ {
218+ name : 'Crank' ,
219+ } ,
220+ ] ,
221+ } ,
222+ } ,
223+ ] ,
60224 } ;
61225}
0 commit comments