@@ -19,6 +19,7 @@ import {
19
19
TxResponse ,
20
20
createTransactionFromMsg ,
21
21
} from "@injectivelabs/sdk-ts" ;
22
+ import { Account } from "@injectivelabs/sdk-ts/dist/cjs/client/chain/types/auth" ;
22
23
23
24
const DEFAULT_GAS_PRICE = 500000000 ;
24
25
@@ -93,6 +94,7 @@ type InjectiveConfig = {
93
94
export class InjectivePricePusher implements IPricePusher {
94
95
private wallet : PrivateKey ;
95
96
private chainConfig : InjectiveConfig ;
97
+ private account : Account | null = null ;
96
98
97
99
constructor (
98
100
private priceServiceConnection : PriceServiceConnection ,
@@ -116,12 +118,14 @@ export class InjectivePricePusher implements IPricePusher {
116
118
117
119
private async signAndBroadcastMsg ( msg : Msgs ) : Promise < TxResponse > {
118
120
const chainGrpcAuthApi = new ChainGrpcAuthApi ( this . grpcEndpoint ) ;
119
- const account = await chainGrpcAuthApi . fetchAccount (
121
+ // Fetch the latest account details only if it's not stored.
122
+ this . account ??= await chainGrpcAuthApi . fetchAccount (
120
123
this . injectiveAddress ( )
121
124
) ;
125
+
122
126
const { txRaw : simulateTxRaw } = createTransactionFromMsg ( {
123
- sequence : account . baseAccount . sequence ,
124
- accountNumber : account . baseAccount . accountNumber ,
127
+ sequence : this . account . baseAccount . sequence ,
128
+ accountNumber : this . account . baseAccount . accountNumber ,
125
129
message : msg ,
126
130
chainId : this . chainConfig . chainId ,
127
131
pubKey : this . wallet . toPublicKey ( ) . toBase64 ( ) ,
@@ -137,23 +141,20 @@ export class InjectivePricePusher implements IPricePusher {
137
141
// gas passed with the transaction should be more than that
138
142
// in order for it to be successfully executed
139
143
// this multiplier takes care of that
144
+ const gas = ( gasUsed * this . chainConfig . gasMultiplier ) . toFixed ( ) ;
140
145
const fee = {
141
146
amount : [
142
147
{
143
148
denom : "inj" ,
144
- amount : (
145
- gasUsed *
146
- this . chainConfig . gasPrice *
147
- this . chainConfig . gasMultiplier
148
- ) . toFixed ( ) ,
149
+ amount : ( Number ( gas ) * this . chainConfig . gasPrice ) . toFixed ( ) ,
149
150
} ,
150
151
] ,
151
- gas : ( gasUsed * this . chainConfig . gasMultiplier ) . toFixed ( ) ,
152
+ gas,
152
153
} ;
153
154
154
155
const { signBytes, txRaw } = createTransactionFromMsg ( {
155
- sequence : account . baseAccount . sequence ,
156
- accountNumber : account . baseAccount . accountNumber ,
156
+ sequence : this . account . baseAccount . sequence ,
157
+ accountNumber : this . account . baseAccount . accountNumber ,
157
158
message : msg ,
158
159
chainId : this . chainConfig . chainId ,
159
160
fee,
@@ -162,11 +163,23 @@ export class InjectivePricePusher implements IPricePusher {
162
163
163
164
const sig = await this . wallet . sign ( Buffer . from ( signBytes ) ) ;
164
165
165
- /** Append Signatures */
166
- txRaw . signatures = [ sig ] ;
167
- const txResponse = await txService . broadcast ( txRaw ) ;
166
+ try {
167
+ this . account . baseAccount . sequence ++ ;
168
+
169
+ /** Append Signatures */
170
+ txRaw . signatures = [ sig ] ;
171
+ // this takes approx 5 seconds
172
+ const txResponse = await txService . broadcast ( txRaw ) ;
168
173
169
- return txResponse ;
174
+ return txResponse ;
175
+ } catch ( e : any ) {
176
+ // The sequence number was invalid and hence we will have to fetch it again.
177
+ if ( e . message . match ( / a c c o u n t s e q u e n c e m i s m a t c h / ) !== null ) {
178
+ // We need to fetch the account details again.
179
+ this . account = null ;
180
+ }
181
+ throw e ;
182
+ }
170
183
}
171
184
172
185
async getPriceFeedUpdateObject ( priceIds : string [ ] ) : Promise < any > {
@@ -200,27 +213,12 @@ export class InjectivePricePusher implements IPricePusher {
200
213
return ;
201
214
}
202
215
203
- let updateFeeQueryResponse : UpdateFeeResponse ;
204
- try {
205
- const api = new ChainGrpcWasmApi ( this . grpcEndpoint ) ;
206
- const { data } = await api . fetchSmartContractState (
207
- this . pythContractAddress ,
208
- Buffer . from (
209
- JSON . stringify ( {
210
- get_update_fee : {
211
- vaas : priceFeedUpdateObject . update_price_feeds . data ,
212
- } ,
213
- } )
214
- ) . toString ( "base64" )
215
- ) ;
216
-
217
- const json = Buffer . from ( data ) . toString ( ) ;
218
- updateFeeQueryResponse = JSON . parse ( json ) ;
219
- } catch ( e ) {
220
- console . error ( "Error fetching update fee" ) ;
221
- console . error ( e ) ;
222
- return ;
223
- }
216
+ // In order to reduce the number of API calls
217
+ // We are calculating the fee using the same logic as in contract.
218
+ const updateFeeQueryResponse : UpdateFeeResponse = {
219
+ denom : "inj" ,
220
+ amount : priceFeedUpdateObject . update_price_feeds . data . length . toFixed ( ) ,
221
+ } ;
224
222
225
223
try {
226
224
const executeMsg = MsgExecuteContract . fromJSON ( {
@@ -231,9 +229,6 @@ export class InjectivePricePusher implements IPricePusher {
231
229
} ) ;
232
230
233
231
const rs = await this . signAndBroadcastMsg ( executeMsg ) ;
234
-
235
- if ( rs . code !== 0 ) throw new Error ( "Error: transaction failed" ) ;
236
-
237
232
console . log ( "Succesfully broadcasted txHash:" , rs . txHash ) ;
238
233
} catch ( e : any ) {
239
234
if ( e . message . match ( / a c c o u n t i n j [ a - z A - Z 0 - 9 ] + n o t f o u n d / ) !== null ) {
0 commit comments