@@ -4,7 +4,8 @@ import { Network, PoolContractV2, Version } from '../index.js';
44import { decodeEntryKey } from '../ledger_entry_helper.js' ;
55import * as FixedMath from '../math.js' ;
66import {
7- getEmissionEntryTokenType ,
7+ getEmissionIndex ,
8+ getReserveId ,
89 ReserveConfig ,
910 ReserveData ,
1011 ReserveEmissionConfig ,
@@ -516,19 +517,19 @@ export class ReserveV1 extends Reserve {
516517 reserveData = ReserveData . fromLedgerEntryData ( ledgerEntry ) ;
517518 break ;
518519 case `EmisConfig` : {
519- const token_type = getEmissionEntryTokenType ( ledgerEntry ) ;
520- if ( token_type == 0 ) {
520+ const index = getEmissionIndex ( ledgerEntry ) ;
521+ if ( index % 2 == 0 ) {
521522 emissionBorrowConfig = EmissionConfig . fromLedgerEntryData ( ledgerEntry ) ;
522- } else if ( token_type == 1 ) {
523+ } else {
523524 emissionSupplyConfig = EmissionConfig . fromLedgerEntryData ( ledgerEntry ) ;
524525 }
525526 break ;
526527 }
527528 case `EmisData` : {
528- const token_type = getEmissionEntryTokenType ( ledgerEntry ) ;
529- if ( token_type == 0 ) {
529+ const index = getEmissionIndex ( ledgerEntry ) ;
530+ if ( index % 2 == 0 ) {
530531 emissionBorrowData = EmissionData . fromLedgerEntryData ( ledgerEntry ) ;
531- } else if ( token_type == 1 ) {
532+ } else {
532533 emissionSupplyData = EmissionData . fromLedgerEntryData ( ledgerEntry ) ;
533534 }
534535 break ;
@@ -576,6 +577,116 @@ export class ReserveV1 extends Reserve {
576577 reserve . accrue ( backstopTakeRate , timestamp ) ;
577578 return reserve ;
578579 }
580+
581+ static async loadList (
582+ network : Network ,
583+ poolId : string ,
584+ backstopTakeRate : bigint ,
585+ reserveList : string [ ] ,
586+ timestamp ?: number
587+ ) : Promise < Reserve [ ] > {
588+ const reserves = new Array < Reserve > ( ) ;
589+ const stellarRpc = new rpc . Server ( network . rpc , network . opts ) ;
590+
591+ const ledgerKeys : xdr . LedgerKey [ ] = [ ] ;
592+ for ( const [ index , reserveId ] of reserveList . entries ( ) ) {
593+ const dTokenIndex = index * 2 ;
594+ const bTokenIndex = index * 2 + 1 ;
595+ ledgerKeys . push (
596+ ...[
597+ ReserveConfig . ledgerKey ( poolId , reserveId ) ,
598+ ReserveData . ledgerKey ( poolId , reserveId ) ,
599+ ReserveEmissionConfig . ledgerKey ( poolId , bTokenIndex ) ,
600+ ReserveEmissionData . ledgerKey ( poolId , bTokenIndex ) ,
601+ ReserveEmissionConfig . ledgerKey ( poolId , dTokenIndex ) ,
602+ ReserveEmissionData . ledgerKey ( poolId , dTokenIndex ) ,
603+ ]
604+ ) ;
605+ }
606+
607+ const reserveLedgerEntries = await stellarRpc . getLedgerEntries ( ...ledgerKeys ) ;
608+
609+ const reserveConfigMap : Map < string , ReserveConfig > = new Map ( ) ;
610+ const reserveDataMap : Map < string , ReserveData > = new Map ( ) ;
611+ const emissionConfigMap : Map < number , EmissionConfig > = new Map ( ) ;
612+ const emissionDataMap : Map < number , EmissionData > = new Map ( ) ;
613+
614+ for ( const entry of reserveLedgerEntries . entries ) {
615+ const ledgerEntry = entry . val ;
616+ const key = decodeEntryKey ( ledgerEntry . contractData ( ) . key ( ) ) ;
617+ switch ( key ) {
618+ case 'ResConfig' : {
619+ const reserveId = getReserveId ( ledgerEntry ) ;
620+ reserveConfigMap . set ( reserveId , ReserveConfig . fromLedgerEntryData ( ledgerEntry ) ) ;
621+ break ;
622+ }
623+ case 'ResData' : {
624+ const reserveId = getReserveId ( ledgerEntry ) ;
625+ reserveDataMap . set ( reserveId , ReserveData . fromLedgerEntryData ( ledgerEntry ) ) ;
626+ break ;
627+ }
628+ case `EmisConfig` : {
629+ const emissionIndex = getEmissionIndex ( ledgerEntry ) ;
630+ emissionConfigMap . set ( emissionIndex , EmissionConfig . fromLedgerEntryData ( ledgerEntry ) ) ;
631+ break ;
632+ }
633+ case `EmisData` : {
634+ const emissionIndex = getEmissionIndex ( ledgerEntry ) ;
635+ emissionDataMap . set ( emissionIndex , EmissionData . fromLedgerEntryData ( ledgerEntry ) ) ;
636+ break ;
637+ }
638+ default :
639+ throw Error ( `Invalid reserve key: should not contain ${ key } ` ) ;
640+ }
641+ }
642+
643+ for ( const [ index , reserveId ] of reserveList . entries ( ) ) {
644+ const reserveConfig = reserveConfigMap . get ( reserveId ) ;
645+ const reserveData = reserveDataMap . get ( reserveId ) ;
646+ if ( reserveConfig == undefined || reserveData == undefined ) {
647+ throw new Error ( 'Unable to load reserve: missing data.' ) ;
648+ }
649+ const dTokenIndex = index * 2 ;
650+ const bTokenIndex = index * 2 + 1 ;
651+ const emissionBorrowConfig = emissionConfigMap . get ( dTokenIndex ) ;
652+ const emissionBorrowData = emissionDataMap . get ( dTokenIndex ) ;
653+ const emissionSupplyConfig = emissionConfigMap . get ( bTokenIndex ) ;
654+ const emissionSupplyData = emissionDataMap . get ( bTokenIndex ) ;
655+
656+ let borrowEmissions : Emissions | undefined = undefined ;
657+ if ( emissionBorrowConfig && emissionBorrowData ) {
658+ borrowEmissions = new EmissionsV1 (
659+ emissionBorrowConfig ,
660+ emissionBorrowData ,
661+ reserveLedgerEntries . latestLedger
662+ ) ;
663+ borrowEmissions . accrue ( reserveData . dSupply , reserveConfig . decimals , timestamp ) ;
664+ }
665+ let supplyEmissions : Emissions | undefined = undefined ;
666+ if ( emissionSupplyConfig && emissionSupplyData ) {
667+ supplyEmissions = new EmissionsV1 (
668+ emissionSupplyConfig ,
669+ emissionSupplyData ,
670+ reserveLedgerEntries . latestLedger
671+ ) ;
672+ supplyEmissions . accrue ( reserveData . bSupply , reserveConfig . decimals , timestamp ) ;
673+ }
674+ const reserve = new ReserveV1 (
675+ poolId ,
676+ reserveId ,
677+ reserveConfig ,
678+ reserveData ,
679+ borrowEmissions ,
680+ supplyEmissions ,
681+ 0 ,
682+ 0 ,
683+ reserveLedgerEntries . latestLedger
684+ ) ;
685+ reserve . accrue ( backstopTakeRate , timestamp ) ;
686+ reserves . push ( reserve ) ;
687+ }
688+ return reserves ;
689+ }
579690}
580691
581692export class ReserveV2 extends Reserve {
0 commit comments