@@ -37,13 +37,15 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
3737 . sqlTransaction ( async sql => {
3838 let blockQuery : FoundOrNot < DbBlock > ;
3939 let blockHash : string = '0x' ;
40+ let atChainTip : boolean = false ;
4041 // we need to return the block height/hash in the response, so we
4142 // need to fetch the block first.
4243 if (
4344 ( ! blockIdentifier ?. hash && ! blockIdentifier ?. index ) ||
4445 ( blockIdentifier && blockIdentifier . index <= 0 )
4546 ) {
4647 blockQuery = await db . getCurrentBlock ( ) ;
48+ atChainTip = true ;
4749 } else if ( blockIdentifier . index > 0 ) {
4850 blockQuery = await db . getBlock ( { height : blockIdentifier . index } ) ;
4951 } else if ( blockIdentifier . hash !== undefined ) {
@@ -66,12 +68,32 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
6668 throw RosettaErrors [ RosettaErrorsTypes . invalidBlockHash ] ;
6769 }
6870
69- const stxBalance = await db . getStxBalanceAtBlock (
70- accountIdentifier . address ,
71- block . block_height
72- ) ;
73- // return spendable balance (liquid) if no sub-account is specified
74- let balance = ( stxBalance . balance - stxBalance . locked ) . toString ( ) ;
71+ let balance = 0n ;
72+ let locked = 0n ;
73+
74+ // Fetch chain tip balance from pre-computed table when possible.
75+ if ( atChainTip ) {
76+ const stxBalancesResult = await db . v2 . getStxHolderBalance ( {
77+ sql,
78+ stxAddress : accountIdentifier . address ,
79+ } ) ;
80+ balance = stxBalancesResult . found ? stxBalancesResult . result . balance : 0n ;
81+ const stxPoxLockedResult = await db . v2 . getStxPoxLockedAtBlock ( {
82+ sql,
83+ stxAddress : accountIdentifier . address ,
84+ blockHeight : block . block_height ,
85+ burnBlockHeight : block . burn_block_height ,
86+ } ) ;
87+ balance = balance - stxPoxLockedResult . locked ;
88+ locked = stxPoxLockedResult . locked ;
89+ } else {
90+ const stxBalance = await db . getStxBalanceAtBlock (
91+ accountIdentifier . address ,
92+ block . block_height
93+ ) ;
94+ balance = stxBalance . balance - stxBalance . locked ;
95+ locked = stxBalance . locked ;
96+ }
7597
7698 const accountNonceQuery = await db . getAddressNonceAtBlock ( {
7799 stxAddress : accountIdentifier . address ,
@@ -86,12 +108,10 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
86108 if ( subAccountIdentifier !== undefined ) {
87109 switch ( subAccountIdentifier . address ) {
88110 case RosettaConstants . StackedBalance :
89- const lockedBalance = stxBalance . locked ;
90- balance = lockedBalance . toString ( ) ;
111+ balance = locked ;
91112 break ;
92113 case RosettaConstants . SpendableBalance :
93- const spendableBalance = stxBalance . balance - stxBalance . locked ;
94- balance = spendableBalance . toString ( ) ;
114+ balance = balance - locked ;
95115 break ;
96116 case RosettaConstants . VestingLockedBalance :
97117 case RosettaConstants . VestingUnlockedBalance :
@@ -101,11 +121,10 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
101121 ) ;
102122 if ( stxVesting . found ) {
103123 const vestingInfo = getVestingInfo ( stxVesting . result ) ;
104- balance = vestingInfo [ subAccountIdentifier . address ] . toString ( ) ;
105124 extra_metadata [ RosettaConstants . VestingSchedule ] =
106125 vestingInfo [ RosettaConstants . VestingSchedule ] ;
107126 } else {
108- balance = '0' ;
127+ balance = 0n ;
109128 }
110129 break ;
111130 default :
@@ -114,7 +133,7 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
114133 }
115134 const balances : RosettaAmount [ ] = [
116135 {
117- value : balance ,
136+ value : balance . toString ( ) ,
118137 currency : {
119138 symbol : RosettaConstants . symbol ,
120139 decimals : RosettaConstants . decimals ,
@@ -166,16 +185,15 @@ export function createRosettaAccountRouter(db: PgStore, chainId: ChainID): expre
166185 return router ;
167186}
168187
169- function getVestingInfo ( info : AddressTokenOfferingLocked ) : { [ key : string ] : string | string [ ] } {
170- const vestingData : { [ key : string ] : string | string [ ] } = { } ;
188+ function getVestingInfo ( info : AddressTokenOfferingLocked ) {
171189 const jsonVestingSchedule : string [ ] = [ ] ;
172190 info . unlock_schedule . forEach ( schedule => {
173191 const item = { amount : schedule . amount , unlock_height : schedule . block_height } ;
174192 jsonVestingSchedule . push ( JSON . stringify ( item ) ) ;
175193 } ) ;
176-
177- vestingData [ RosettaConstants . VestingLockedBalance ] = info . total_locked ;
178- vestingData [ RosettaConstants . VestingUnlockedBalance ] = info . total_unlocked ;
179- vestingData [ RosettaConstants . VestingSchedule ] = jsonVestingSchedule ;
180- return vestingData ;
194+ return {
195+ [ RosettaConstants . VestingLockedBalance ] : info . total_locked ,
196+ [ RosettaConstants . VestingUnlockedBalance ] : info . total_unlocked ,
197+ [ RosettaConstants . VestingSchedule ] : jsonVestingSchedule ,
198+ } ;
181199}
0 commit comments