@injectivelabs/wallet-core 1.16.38 → 1.16.39-alpha.1

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.
Files changed (41) hide show
  1. package/dist/cjs/index.cjs +1016 -0
  2. package/dist/cjs/index.d.cts +288 -0
  3. package/dist/cjs/package.json +2 -2
  4. package/dist/esm/index.d.ts +288 -3
  5. package/dist/esm/index.js +1012 -3
  6. package/dist/esm/package.json +2 -2
  7. package/package.json +46 -47
  8. package/dist/cjs/broadcaster/MsgBroadcaster.d.ts +0 -137
  9. package/dist/cjs/broadcaster/MsgBroadcaster.js +0 -920
  10. package/dist/cjs/broadcaster/Web3Broadcaster.d.ts +0 -30
  11. package/dist/cjs/broadcaster/Web3Broadcaster.js +0 -32
  12. package/dist/cjs/broadcaster/index.d.ts +0 -3
  13. package/dist/cjs/broadcaster/index.js +0 -19
  14. package/dist/cjs/broadcaster/types.d.ts +0 -56
  15. package/dist/cjs/broadcaster/types.js +0 -13
  16. package/dist/cjs/index.d.ts +0 -3
  17. package/dist/cjs/index.js +0 -19
  18. package/dist/cjs/strategy/BaseWalletStrategy.d.ts +0 -58
  19. package/dist/cjs/strategy/BaseWalletStrategy.js +0 -176
  20. package/dist/cjs/strategy/index.d.ts +0 -2
  21. package/dist/cjs/strategy/index.js +0 -8
  22. package/dist/cjs/utils/index.d.ts +0 -1
  23. package/dist/cjs/utils/index.js +0 -17
  24. package/dist/cjs/utils/tx.d.ts +0 -1
  25. package/dist/cjs/utils/tx.js +0 -11
  26. package/dist/esm/broadcaster/MsgBroadcaster.d.ts +0 -137
  27. package/dist/esm/broadcaster/MsgBroadcaster.js +0 -916
  28. package/dist/esm/broadcaster/Web3Broadcaster.d.ts +0 -30
  29. package/dist/esm/broadcaster/Web3Broadcaster.js +0 -28
  30. package/dist/esm/broadcaster/index.d.ts +0 -3
  31. package/dist/esm/broadcaster/index.js +0 -3
  32. package/dist/esm/broadcaster/types.d.ts +0 -56
  33. package/dist/esm/broadcaster/types.js +0 -10
  34. package/dist/esm/strategy/BaseWalletStrategy.d.ts +0 -58
  35. package/dist/esm/strategy/BaseWalletStrategy.js +0 -173
  36. package/dist/esm/strategy/index.d.ts +0 -2
  37. package/dist/esm/strategy/index.js +0 -2
  38. package/dist/esm/utils/index.d.ts +0 -1
  39. package/dist/esm/utils/index.js +0 -1
  40. package/dist/esm/utils/tx.d.ts +0 -1
  41. package/dist/esm/utils/tx.js +0 -7
@@ -1,920 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MsgBroadcaster = void 0;
4
- const ts_types_1 = require("@injectivelabs/ts-types");
5
- const networks_1 = require("@injectivelabs/networks");
6
- const utils_1 = require("@injectivelabs/utils");
7
- const exceptions_1 = require("@injectivelabs/exceptions");
8
- const wallet_base_1 = require("@injectivelabs/wallet-base");
9
- const sdk_ts_1 = require("@injectivelabs/sdk-ts");
10
- const index_js_1 = require("../utils/index.js");
11
- const types_js_1 = require("./types.js");
12
- const getEthereumWalletPubKey = async ({ pubKey, eip712TypedData, signature, }) => {
13
- if (pubKey) {
14
- return pubKey;
15
- }
16
- const recoveredPubKey = await (0, sdk_ts_1.recoverTypedSignaturePubKey)(
17
- // TODO: fix type
18
- eip712TypedData, signature);
19
- return (0, sdk_ts_1.hexToBase64)(recoveredPubKey);
20
- };
21
- const defaultRetriesConfig = () => ({
22
- [`${exceptions_1.TransactionChainErrorModule.CosmosSdk}-${exceptions_1.ChainCosmosErrorCode.ErrMempoolIsFull}`]: {
23
- retries: 0,
24
- maxRetries: 10,
25
- timeout: 1000,
26
- },
27
- });
28
- /**
29
- * This class is used to broadcast transactions
30
- * using the WalletStrategy as a handler
31
- * for the sign/broadcast flow of the transactions
32
- *
33
- * Mainly used for building UI products
34
- */
35
- class MsgBroadcaster {
36
- options;
37
- walletStrategy;
38
- endpoints;
39
- chainId;
40
- txTimeout = utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT;
41
- simulateTx = true;
42
- txTimeoutOnFeeDelegation = false;
43
- evmChainId;
44
- gasBufferCoefficient = 1.2;
45
- retriesOnError = defaultRetriesConfig();
46
- httpHeaders;
47
- constructor(options) {
48
- const networkInfo = (0, networks_1.getNetworkInfo)(options.network);
49
- this.options = options;
50
- this.simulateTx =
51
- options.simulateTx !== undefined ? options.simulateTx : true;
52
- this.txTimeout = options.txTimeout || utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT;
53
- this.txTimeoutOnFeeDelegation =
54
- options.txTimeoutOnFeeDelegation !== undefined
55
- ? options.txTimeoutOnFeeDelegation
56
- : true;
57
- this.gasBufferCoefficient = options.gasBufferCoefficient || 1.2;
58
- this.chainId = options.chainId || networkInfo.chainId;
59
- this.evmChainId = options.evmChainId || networkInfo.evmChainId;
60
- this.endpoints = options.endpoints || (0, networks_1.getNetworkEndpoints)(options.network);
61
- this.walletStrategy = options.walletStrategy;
62
- this.httpHeaders = options.httpHeaders;
63
- }
64
- setOptions(options) {
65
- this.simulateTx = options.simulateTx || this.simulateTx;
66
- this.txTimeout = options.txTimeout || this.txTimeout;
67
- this.txTimeoutOnFeeDelegation =
68
- options.txTimeoutOnFeeDelegation || this.txTimeoutOnFeeDelegation;
69
- }
70
- async getEvmChainId() {
71
- const { walletStrategy } = this;
72
- if (!(0, wallet_base_1.isEvmBrowserWallet)(walletStrategy.wallet)) {
73
- return this.evmChainId;
74
- }
75
- const mainnetEvmIds = [
76
- ts_types_1.EvmChainId.Mainnet,
77
- ts_types_1.EvmChainId.MainnetEvm,
78
- ];
79
- const testnetEvmIds = [
80
- ts_types_1.EvmChainId.Sepolia,
81
- ts_types_1.EvmChainId.TestnetEvm,
82
- ];
83
- const devnetEvmIds = [
84
- ts_types_1.EvmChainId.Sepolia,
85
- ts_types_1.EvmChainId.DevnetEvm,
86
- ts_types_1.EvmChainId.MainnetEvm,
87
- ts_types_1.EvmChainId.TestnetEvm,
88
- ];
89
- try {
90
- const chainId = await walletStrategy.getEthereumChainId();
91
- if (!chainId) {
92
- return this.evmChainId;
93
- }
94
- const evmChainId = parseInt(chainId, 16);
95
- if (isNaN(evmChainId)) {
96
- return this.evmChainId;
97
- }
98
- if (((0, networks_1.isMainnet)(this.options.network) &&
99
- !mainnetEvmIds.includes(evmChainId)) ||
100
- ((0, networks_1.isTestnet)(this.options.network) &&
101
- !testnetEvmIds.includes(evmChainId)) ||
102
- (!(0, networks_1.isMainnet)(this.options.network) &&
103
- !(0, networks_1.isTestnet)(this.options.network) &&
104
- !devnetEvmIds.includes(evmChainId))) {
105
- throw new exceptions_1.WalletException(new Error('Your selected network is incorrect'));
106
- }
107
- return evmChainId;
108
- }
109
- catch (e) {
110
- throw new exceptions_1.WalletException(e);
111
- }
112
- }
113
- /**
114
- * Broadcasting the transaction using the client
115
- * side approach for both cosmos and ethereum native wallets
116
- *
117
- * @param tx
118
- * @returns {string} transaction hash
119
- */
120
- async broadcast(tx) {
121
- const { walletStrategy } = this;
122
- const txWithAddresses = {
123
- ...tx,
124
- ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
125
- injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
126
- };
127
- if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
128
- throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
129
- }
130
- try {
131
- return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
132
- ? await this.broadcastDirectSign(txWithAddresses)
133
- : (0, wallet_base_1.isEip712V2OnlyWallet)(walletStrategy.wallet)
134
- ? await this.broadcastEip712V2(txWithAddresses)
135
- : await this.broadcastEip712(txWithAddresses);
136
- }
137
- catch (e) {
138
- const error = e;
139
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionFail);
140
- if ((0, exceptions_1.isThrownException)(error)) {
141
- throw error;
142
- }
143
- throw new exceptions_1.TransactionException(new Error(error));
144
- }
145
- }
146
- /**
147
- * Broadcasting the transaction using the client
148
- * side approach for both cosmos and ethereum native wallets
149
- * Note: using EIP712_V2 for Ethereum wallets
150
- *
151
- * @param tx
152
- * @returns {string} transaction hash
153
- */
154
- async broadcastV2(tx) {
155
- const { walletStrategy } = this;
156
- const txWithAddresses = {
157
- ...tx,
158
- ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
159
- injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
160
- };
161
- if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
162
- throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
163
- }
164
- try {
165
- return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
166
- ? await this.broadcastDirectSign(txWithAddresses)
167
- : await this.broadcastEip712V2(txWithAddresses);
168
- }
169
- catch (e) {
170
- const error = e;
171
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionFail);
172
- if ((0, exceptions_1.isThrownException)(error)) {
173
- throw error;
174
- }
175
- throw new exceptions_1.TransactionException(new Error(error));
176
- }
177
- }
178
- /**
179
- * Broadcasting the transaction using the feeDelegation
180
- * support approach for both cosmos and ethereum native wallets
181
- *
182
- * @param tx
183
- * @returns {string} transaction hash
184
- */
185
- async broadcastWithFeeDelegation(tx) {
186
- const { walletStrategy } = this;
187
- const txWithAddresses = {
188
- ...tx,
189
- ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
190
- injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
191
- };
192
- if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
193
- throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
194
- }
195
- try {
196
- return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
197
- ? await this.broadcastDirectSignWithFeeDelegation(txWithAddresses)
198
- : await this.broadcastEip712WithFeeDelegation(txWithAddresses);
199
- }
200
- catch (e) {
201
- const error = e;
202
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionFail);
203
- if ((0, exceptions_1.isThrownException)(error)) {
204
- throw error;
205
- }
206
- throw new exceptions_1.TransactionException(new Error(error));
207
- }
208
- }
209
- /**
210
- * Prepare/sign/broadcast transaction using
211
- * Ethereum native wallets on the client side.
212
- *
213
- * Note: Gas estimation not available
214
- *
215
- * @param tx The transaction that needs to be broadcasted
216
- * @returns transaction hash
217
- */
218
- async broadcastEip712(tx) {
219
- const { chainId, endpoints, walletStrategy, txTimeout: txTimeoutInBlocks, } = this;
220
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
221
- const evmChainId = await this.getEvmChainId();
222
- if (!evmChainId) {
223
- throw new exceptions_1.GeneralException(new Error('Please provide evmChainId'));
224
- }
225
- /** Account Details * */
226
- const { baseAccount, latestHeight } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
227
- const timeoutHeight = (0, utils_1.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
228
- const txTimeoutTimeInSeconds = txTimeoutInBlocks * utils_1.DEFAULT_BLOCK_TIME_IN_SECONDS;
229
- const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1000;
230
- const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
231
- let stdFee = (0, utils_1.getStdFee)({ ...tx.gas, gas });
232
- /**
233
- * Account has not been created on chain
234
- * and we cannot simulate the transaction
235
- * to estimate the gas
236
- **/
237
- if (!baseAccount.pubKey) {
238
- stdFee = await this.getStdFeeWithDynamicBaseFee(stdFee);
239
- }
240
- else {
241
- const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
242
- chainId,
243
- signMode: sdk_ts_1.SIGN_EIP712,
244
- memo: tx.memo,
245
- message: msgs,
246
- timeoutHeight: timeoutHeight.toNumber(),
247
- signers: {
248
- pubKey: baseAccount.pubKey.key,
249
- accountNumber: baseAccount.accountNumber,
250
- sequence: baseAccount.sequence,
251
- },
252
- fee: stdFee,
253
- });
254
- stdFee = simulatedStdFee;
255
- }
256
- /** EIP712 for signing on Ethereum wallets */
257
- const eip712TypedData = (0, sdk_ts_1.getEip712TypedData)({
258
- msgs,
259
- fee: stdFee,
260
- tx: {
261
- memo: tx.memo,
262
- accountNumber: baseAccount.accountNumber.toString(),
263
- sequence: baseAccount.sequence.toString(),
264
- timeoutHeight: timeoutHeight.toFixed(),
265
- chainId,
266
- },
267
- evmChainId,
268
- });
269
- /** Signing on Ethereum */
270
- const signature = await walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
271
- const pubKeyOrSignatureDerivedPubKey = await getEthereumWalletPubKey({
272
- pubKey: baseAccount.pubKey?.key,
273
- eip712TypedData,
274
- signature,
275
- });
276
- /** Preparing the transaction for client broadcasting */
277
- const { txRaw } = (0, sdk_ts_1.createTransaction)({
278
- message: msgs,
279
- memo: tx.memo,
280
- signMode: sdk_ts_1.SIGN_EIP712,
281
- fee: stdFee,
282
- pubKey: pubKeyOrSignatureDerivedPubKey,
283
- sequence: baseAccount.sequence,
284
- timeoutHeight: timeoutHeight.toNumber(),
285
- accountNumber: baseAccount.accountNumber,
286
- chainId,
287
- });
288
- const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
289
- evmChainId,
290
- });
291
- const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
292
- /** Append Signatures */
293
- txRawEip712.signatures = [(0, sdk_ts_1.hexToBuff)(signature)];
294
- const response = await walletStrategy.sendTransaction(txRawEip712, {
295
- chainId,
296
- endpoints,
297
- txTimeout: txTimeoutInBlocks,
298
- address: tx.injectiveAddress,
299
- });
300
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
301
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
302
- }
303
- /**
304
- * Prepare/sign/broadcast transaction using
305
- * Ethereum native wallets on the client side.
306
- *
307
- * Note: Gas estimation not available
308
- *
309
- * @param tx The transaction that needs to be broadcasted
310
- * @returns transaction hash
311
- */
312
- async broadcastEip712V2(tx) {
313
- const { chainId, endpoints, walletStrategy, txTimeout: txTimeoutInBlocks, } = this;
314
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
315
- const evmChainId = await this.getEvmChainId();
316
- if (!evmChainId) {
317
- throw new exceptions_1.GeneralException(new Error('Please provide evmChainId'));
318
- }
319
- /** Account Details * */
320
- const { baseAccount, latestHeight } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
321
- const timeoutHeight = (0, utils_1.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
322
- const txTimeoutTimeInSeconds = txTimeoutInBlocks * utils_1.DEFAULT_BLOCK_TIME_IN_SECONDS;
323
- const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1000;
324
- const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
325
- let stdFee = (0, utils_1.getStdFee)({ ...tx.gas, gas });
326
- /**
327
- * Account has not been created on chain
328
- * and we cannot simulate the transaction
329
- * to estimate the gas
330
- **/
331
- if (!baseAccount.pubKey) {
332
- stdFee = await this.getStdFeeWithDynamicBaseFee(stdFee);
333
- }
334
- else {
335
- const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
336
- chainId,
337
- signMode: sdk_ts_1.SIGN_EIP712_V2,
338
- memo: tx.memo,
339
- message: msgs,
340
- timeoutHeight: timeoutHeight.toNumber(),
341
- signers: {
342
- pubKey: baseAccount.pubKey.key,
343
- sequence: baseAccount.sequence,
344
- accountNumber: baseAccount.accountNumber,
345
- },
346
- fee: stdFee,
347
- });
348
- stdFee = simulatedStdFee;
349
- }
350
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationStart);
351
- /** EIP712 for signing on Ethereum wallets */
352
- const eip712TypedData = (0, sdk_ts_1.getEip712TypedDataV2)({
353
- msgs,
354
- fee: stdFee,
355
- tx: {
356
- memo: tx.memo,
357
- accountNumber: baseAccount.accountNumber.toString(),
358
- sequence: baseAccount.sequence.toString(),
359
- timeoutHeight: timeoutHeight.toFixed(),
360
- chainId,
361
- },
362
- evmChainId,
363
- });
364
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationEnd);
365
- /** Signing on Ethereum */
366
- const signature = await walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
367
- const pubKeyOrSignatureDerivedPubKey = await getEthereumWalletPubKey({
368
- pubKey: baseAccount.pubKey?.key,
369
- eip712TypedData,
370
- signature,
371
- });
372
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastStart);
373
- const { txRaw } = (0, sdk_ts_1.createTransaction)({
374
- message: msgs,
375
- memo: tx.memo,
376
- signMode: sdk_ts_1.SIGN_EIP712_V2,
377
- fee: stdFee,
378
- pubKey: pubKeyOrSignatureDerivedPubKey,
379
- sequence: baseAccount.sequence,
380
- timeoutHeight: timeoutHeight.toNumber(),
381
- accountNumber: baseAccount.accountNumber,
382
- chainId,
383
- });
384
- const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
385
- evmChainId,
386
- });
387
- const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
388
- /** Append Signatures */
389
- txRawEip712.signatures = [(0, sdk_ts_1.hexToBuff)(signature)];
390
- const response = await walletStrategy.sendTransaction(txRawEip712, {
391
- chainId,
392
- endpoints,
393
- txTimeout: txTimeoutInBlocks,
394
- address: tx.injectiveAddress,
395
- });
396
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
397
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
398
- }
399
- /**
400
- * Prepare/sign/broadcast transaction using
401
- * Ethereum native wallets using the Web3Gateway.
402
- *
403
- * @param tx The transaction that needs to be broadcasted
404
- * @returns transaction hash
405
- */
406
- async broadcastEip712WithFeeDelegation(tx) {
407
- const { endpoints, simulateTx, httpHeaders, walletStrategy, txTimeoutOnFeeDelegation, txTimeout: txTimeoutInBlocks, } = this;
408
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
409
- const web3Msgs = msgs.map((msg) => msg.toWeb3());
410
- const evmChainId = await this.getEvmChainId();
411
- if (!evmChainId) {
412
- throw new exceptions_1.GeneralException(new Error('Please provide evmChainId'));
413
- }
414
- const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
415
- if (httpHeaders) {
416
- transactionApi.setMetadata(httpHeaders);
417
- }
418
- const txTimeoutTimeInSeconds = txTimeoutInBlocks * utils_1.DEFAULT_BLOCK_TIME_IN_SECONDS;
419
- const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1000;
420
- let timeoutHeight = undefined;
421
- if (txTimeoutOnFeeDelegation) {
422
- const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
423
- const latestHeight = latestBlock.header.height;
424
- timeoutHeight = (0, utils_1.toBigNumber)(latestHeight)
425
- .plus(txTimeoutInBlocks)
426
- .toNumber();
427
- }
428
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationStart);
429
- const prepareTxResponse = await transactionApi.prepareTxRequest({
430
- timeoutHeight,
431
- memo: tx.memo,
432
- message: web3Msgs,
433
- address: tx.ethereumAddress,
434
- chainId: evmChainId,
435
- gasLimit: (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs),
436
- estimateGas: simulateTx,
437
- });
438
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationEnd);
439
- const signature = await walletStrategy.signEip712TypedData(prepareTxResponse.data, tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
440
- const broadcast = async () => await transactionApi.broadcastTxRequest({
441
- signature,
442
- message: web3Msgs,
443
- txResponse: prepareTxResponse,
444
- chainId: evmChainId,
445
- });
446
- try {
447
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastStart);
448
- const response = await broadcast();
449
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
450
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
451
- }
452
- catch (e) {
453
- const error = e;
454
- if ((0, exceptions_1.isThrownException)(error)) {
455
- const exception = error;
456
- /**
457
- * First MsgExec transaction with a PrivateKey wallet
458
- * always runs out of gas for some reason, temporary solution
459
- * to just broadcast the transaction twice
460
- **/
461
- if (walletStrategy.wallet === wallet_base_1.Wallet.PrivateKey &&
462
- (0, index_js_1.checkIfTxRunOutOfGas)(exception)) {
463
- /** Account Details * */
464
- const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
465
- const { baseAccount } = accountDetails;
466
- /** We only do it on the first account tx fail */
467
- if (baseAccount.sequence > 1) {
468
- throw e;
469
- }
470
- return await this.broadcastEip712WithFeeDelegation(tx);
471
- }
472
- return await this.retryOnException(exception, broadcast);
473
- }
474
- throw e;
475
- }
476
- }
477
- /**
478
- * Prepare/sign/broadcast transaction using
479
- * Cosmos native wallets on the client side.
480
- *
481
- * @param tx The transaction that needs to be broadcasted
482
- * @returns transaction hash
483
- */
484
- async broadcastDirectSign(tx) {
485
- const { chainId, endpoints, walletStrategy, txTimeout: txTimeoutInBlocks, } = this;
486
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
487
- /**
488
- * When using Ledger with Keplr/Leap we have
489
- * to send EIP712 to sign on Keplr/Leap
490
- */
491
- if ([wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.Leap].includes(walletStrategy.getWallet())) {
492
- const walletDeviceType = await walletStrategy.getWalletDeviceType();
493
- const isLedgerConnected = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
494
- if (isLedgerConnected) {
495
- return this.experimentalBroadcastWalletThroughLedger(tx);
496
- }
497
- }
498
- const { baseAccount, latestHeight } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
499
- const timeoutHeight = (0, utils_1.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
500
- const txTimeoutTimeInSeconds = txTimeoutInBlocks * utils_1.DEFAULT_BLOCK_TIME_IN_SECONDS;
501
- const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1000;
502
- const signMode = (0, wallet_base_1.isCosmosAminoOnlyWallet)(walletStrategy.wallet)
503
- ? sdk_ts_1.SIGN_EIP712
504
- : sdk_ts_1.SIGN_DIRECT;
505
- const pubKey = await walletStrategy.getPubKey(tx.injectiveAddress);
506
- const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
507
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationStart);
508
- /** Prepare the Transaction * */
509
- const { txRaw } = await this.getTxWithSignersAndStdFee({
510
- chainId,
511
- signMode,
512
- memo: tx.memo,
513
- message: msgs,
514
- timeoutHeight: timeoutHeight.toNumber(),
515
- signers: {
516
- pubKey,
517
- accountNumber: baseAccount.accountNumber,
518
- sequence: baseAccount.sequence,
519
- },
520
- fee: (0, utils_1.getStdFee)({ ...tx.gas, gas }),
521
- });
522
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationEnd);
523
- /** Ledger using Cosmos app only allows signing amino docs */
524
- if ((0, wallet_base_1.isCosmosAminoOnlyWallet)(walletStrategy.wallet)) {
525
- const aminoSignDoc = (0, sdk_ts_1.getAminoStdSignDoc)({
526
- ...tx,
527
- ...baseAccount,
528
- msgs,
529
- chainId,
530
- gas: gas || tx.gas?.gas?.toString(),
531
- timeoutHeight: timeoutHeight.toFixed(),
532
- });
533
- const signResponse = await walletStrategy.signAminoCosmosTransaction({
534
- signDoc: aminoSignDoc,
535
- address: tx.injectiveAddress,
536
- });
537
- txRaw.signatures = [
538
- Buffer.from(signResponse.signature.signature, 'base64'),
539
- ];
540
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastStart);
541
- const response = await walletStrategy.sendTransaction(txRaw, {
542
- chainId,
543
- endpoints,
544
- address: tx.injectiveAddress,
545
- txTimeout: txTimeoutInBlocks,
546
- });
547
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
548
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
549
- }
550
- const directSignResponse = (await walletStrategy.signCosmosTransaction({
551
- txRaw,
552
- chainId,
553
- address: tx.injectiveAddress,
554
- accountNumber: baseAccount.accountNumber,
555
- }));
556
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastStart);
557
- const response = await walletStrategy.sendTransaction(directSignResponse, {
558
- chainId,
559
- endpoints,
560
- txTimeout: txTimeoutInBlocks,
561
- address: tx.injectiveAddress,
562
- });
563
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
564
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
565
- }
566
- /**
567
- * We use this method only when we want to broadcast a transaction using Ledger on Keplr/Leap for Injective
568
- *
569
- * Note: Gas estimation not available
570
- * @param tx the transaction that needs to be broadcasted
571
- */
572
- async experimentalBroadcastWalletThroughLedger(tx) {
573
- const { chainId, endpoints, evmChainId, simulateTx, walletStrategy, txTimeout: txTimeoutInBlocks, } = this;
574
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
575
- /**
576
- * We can only use this method
577
- * when Ledger is connected through Keplr
578
- */
579
- if ([wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.Leap].includes(walletStrategy.getWallet())) {
580
- const walletDeviceType = await walletStrategy.getWalletDeviceType();
581
- const isLedgerConnected = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
582
- if (!isLedgerConnected) {
583
- throw new exceptions_1.GeneralException(new Error(`This method can only be used when Ledger is connected through ${walletStrategy.getWallet()}`));
584
- }
585
- }
586
- if (!evmChainId) {
587
- throw new exceptions_1.GeneralException(new Error('Please provide evmChainId'));
588
- }
589
- const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
590
- const { baseAccount, latestHeight } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
591
- const timeoutHeight = (0, utils_1.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
592
- const pubKey = await walletStrategy.getPubKey();
593
- const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
594
- /** EIP712 for signing on Ethereum wallets */
595
- const eip712TypedData = (0, sdk_ts_1.getEip712TypedData)({
596
- msgs,
597
- fee: await this.getStdFeeWithDynamicBaseFee({ ...tx.gas, gas }),
598
- tx: {
599
- chainId,
600
- memo: tx.memo,
601
- timeoutHeight: timeoutHeight.toFixed(),
602
- sequence: baseAccount.sequence.toString(),
603
- accountNumber: baseAccount.accountNumber.toString(),
604
- },
605
- evmChainId,
606
- });
607
- const aminoSignResponse = await cosmosWallet.signEIP712CosmosTx({
608
- eip712: eip712TypedData,
609
- signDoc: (0, wallet_base_1.createEip712StdSignDoc)({
610
- ...tx,
611
- ...baseAccount,
612
- msgs,
613
- chainId,
614
- gas: gas || tx.gas?.gas?.toString(),
615
- timeoutHeight: timeoutHeight.toFixed(),
616
- }),
617
- });
618
- /**
619
- * Create TxRaw from the signed tx that we
620
- * get as a response in case the user changed the fee/memo
621
- * on the Keplr popup
622
- */
623
- const { txRaw } = (0, sdk_ts_1.createTransaction)({
624
- pubKey,
625
- message: msgs,
626
- memo: aminoSignResponse.signed.memo,
627
- signMode: sdk_ts_1.SIGN_EIP712,
628
- fee: aminoSignResponse.signed.fee,
629
- sequence: parseInt(aminoSignResponse.signed.sequence, 10),
630
- timeoutHeight: parseInt(aminoSignResponse.signed.timeout_height, 10),
631
- accountNumber: parseInt(aminoSignResponse.signed.account_number, 10),
632
- chainId,
633
- });
634
- /** Preparing the transaction for client broadcasting */
635
- const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
636
- evmChainId,
637
- });
638
- const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
639
- if (simulateTx) {
640
- await this.simulateTxRaw(txRawEip712);
641
- }
642
- /** Append Signatures */
643
- const signatureBuff = Buffer.from(aminoSignResponse.signature.signature, 'base64');
644
- txRawEip712.signatures = [signatureBuff];
645
- /** Broadcast the transaction */
646
- const response = await new sdk_ts_1.TxGrpcApi(endpoints.grpc).broadcast(txRawEip712, { txTimeout: txTimeoutInBlocks });
647
- if (response.code !== 0) {
648
- throw new exceptions_1.TransactionException(new Error(response.rawLog), {
649
- code: exceptions_1.UnspecifiedErrorCode,
650
- contextCode: response.code,
651
- contextModule: response.codespace,
652
- });
653
- }
654
- return response;
655
- }
656
- /**
657
- * Prepare/sign/broadcast transaction using
658
- * Cosmos native wallets using the Web3Gateway.
659
- *
660
- * @param tx The transaction that needs to be broadcasted
661
- * @returns transaction hash
662
- */
663
- async broadcastDirectSignWithFeeDelegation(tx) {
664
- const { options, chainId, endpoints, httpHeaders, walletStrategy, txTimeoutOnFeeDelegation, txTimeout: txTimeoutInBlocks, } = this;
665
- const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
666
- /**
667
- * We can only use this method when Keplr is connected
668
- * with ledger
669
- */
670
- if (walletStrategy.getWallet() === wallet_base_1.Wallet.Keplr) {
671
- const walletDeviceType = await walletStrategy.getWalletDeviceType();
672
- const isLedgerConnectedOnKeplr = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
673
- if (isLedgerConnectedOnKeplr) {
674
- throw new exceptions_1.GeneralException(new Error('Keplr + Ledger is not available with fee delegation. Connect with Ledger directly.'));
675
- }
676
- }
677
- const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
678
- const canDisableCosmosGasCheck = [wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.OWallet].includes(walletStrategy.wallet);
679
- const feePayerPubKey = await this.fetchFeePayerPubKey(options.feePayerPubKey);
680
- const feePayerPublicKey = sdk_ts_1.PublicKey.fromBase64(feePayerPubKey);
681
- const feePayer = feePayerPublicKey.toAddress().address;
682
- /** Account Details * */
683
- const { baseAccount, latestHeight } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
684
- const chainGrpcAuthApi = new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc);
685
- if (httpHeaders) {
686
- chainGrpcAuthApi.setMetadata(httpHeaders);
687
- }
688
- const feePayerAccountDetails = await chainGrpcAuthApi.fetchAccount(feePayer);
689
- const { baseAccount: feePayerBaseAccount } = feePayerAccountDetails;
690
- const timeoutHeight = (0, utils_1.toBigNumber)(latestHeight).plus(txTimeoutOnFeeDelegation
691
- ? txTimeoutInBlocks
692
- : utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT);
693
- const txTimeoutTimeInSeconds = txTimeoutInBlocks * utils_1.DEFAULT_BLOCK_TIME_IN_SECONDS;
694
- const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1000;
695
- const pubKey = await walletStrategy.getPubKey();
696
- const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
697
- /** Prepare the Transaction * */
698
- const { txRaw } = await this.getTxWithSignersAndStdFee({
699
- chainId,
700
- memo: tx.memo,
701
- message: msgs,
702
- timeoutHeight: timeoutHeight.toNumber(),
703
- signers: [
704
- {
705
- pubKey,
706
- accountNumber: baseAccount.accountNumber,
707
- sequence: baseAccount.sequence,
708
- },
709
- {
710
- pubKey: feePayerPublicKey.toBase64(),
711
- accountNumber: feePayerBaseAccount.accountNumber,
712
- sequence: feePayerBaseAccount.sequence,
713
- },
714
- ],
715
- fee: (0, utils_1.getStdFee)({ ...tx.gas, gas, payer: feePayer }),
716
- });
717
- // Temporary remove tx gas check because Keplr doesn't recognize feePayer
718
- if (canDisableCosmosGasCheck && cosmosWallet.disableGasCheck) {
719
- cosmosWallet.disableGasCheck(chainId);
720
- }
721
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationStart);
722
- const directSignResponse = (await walletStrategy.signCosmosTransaction({
723
- txRaw,
724
- chainId,
725
- address: tx.injectiveAddress,
726
- accountNumber: baseAccount.accountNumber,
727
- }));
728
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionPreparationEnd);
729
- const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
730
- if (httpHeaders) {
731
- transactionApi.setMetadata(httpHeaders);
732
- }
733
- const broadcast = async () => await transactionApi.broadcastCosmosTxRequest({
734
- address: tx.injectiveAddress,
735
- txRaw: (0, sdk_ts_1.createTxRawFromSigResponse)(directSignResponse),
736
- signature: directSignResponse.signature.signature,
737
- pubKey: directSignResponse.signature.pub_key || {
738
- value: pubKey,
739
- type: '/injective.crypto.v1beta1.ethsecp256k1.PubKey',
740
- },
741
- });
742
- try {
743
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastStart);
744
- const response = await broadcast();
745
- walletStrategy.emit(types_js_1.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
746
- // Re-enable tx gas check removed above
747
- if (canDisableCosmosGasCheck && cosmosWallet.enableGasCheck) {
748
- cosmosWallet.enableGasCheck(chainId);
749
- }
750
- return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash, txTimeoutTimeInMilliSeconds);
751
- }
752
- catch (e) {
753
- const error = e;
754
- if ((0, exceptions_1.isThrownException)(error)) {
755
- const exception = error;
756
- return await this.retryOnException(exception, broadcast);
757
- }
758
- throw e;
759
- }
760
- }
761
- /**
762
- * Fetch the fee payer's pub key from the web3 gateway
763
- *
764
- * Returns a base64 version of it
765
- */
766
- async fetchFeePayerPubKey(existingFeePayerPubKey) {
767
- if (existingFeePayerPubKey) {
768
- return existingFeePayerPubKey;
769
- }
770
- const { endpoints, httpHeaders } = this;
771
- const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
772
- if (httpHeaders) {
773
- transactionApi.setMetadata(httpHeaders);
774
- }
775
- const response = await transactionApi.fetchFeePayer();
776
- if (!response.feePayerPubKey) {
777
- throw new exceptions_1.GeneralException(new Error('Please provide a feePayerPubKey'));
778
- }
779
- if (response.feePayerPubKey.key.startsWith('0x') ||
780
- response.feePayerPubKey.key.length === 66) {
781
- return Buffer.from(response.feePayerPubKey.key, 'hex').toString('base64');
782
- }
783
- return response.feePayerPubKey.key;
784
- }
785
- async getStdFeeWithDynamicBaseFee(args) {
786
- const client = new sdk_ts_1.ChainGrpcTxFeesApi(this.endpoints.grpc);
787
- let baseFee = utils_1.DEFAULT_GAS_PRICE;
788
- try {
789
- const response = await client.fetchEipBaseFee();
790
- baseFee = Number(response?.baseFee || utils_1.DEFAULT_GAS_PRICE);
791
- }
792
- catch { }
793
- if (!args) {
794
- return (0, utils_1.getStdFee)(baseFee ? { gasPrice: baseFee } : {});
795
- }
796
- if (typeof args === 'string') {
797
- return (0, utils_1.getStdFee)({
798
- ...(baseFee && {
799
- gasPrice: (0, utils_1.toBigNumber)(baseFee).toFixed(),
800
- }),
801
- gas: args,
802
- });
803
- }
804
- return (0, utils_1.getStdFee)({
805
- ...args,
806
- ...(baseFee && {
807
- gasPrice: (0, utils_1.toBigNumber)(baseFee).toFixed(),
808
- }),
809
- });
810
- }
811
- /**
812
- * In case we don't want to simulate the transaction
813
- * we get the gas limit based on the message type.
814
- *
815
- * If we want to simulate the transaction we set the
816
- * gas limit based on the simulation and add a small multiplier
817
- * to be safe (factor of 1.2 as default)
818
- */
819
- async getTxWithSignersAndStdFee(args) {
820
- const { simulateTx } = this;
821
- if (!simulateTx) {
822
- return {
823
- ...(0, sdk_ts_1.createTransactionWithSigners)(args),
824
- stdFee: await this.getStdFeeWithDynamicBaseFee(args.fee),
825
- };
826
- }
827
- const result = await this.simulateTxWithSigners(args);
828
- if (!result.gasInfo?.gasUsed) {
829
- return {
830
- ...(0, sdk_ts_1.createTransactionWithSigners)(args),
831
- stdFee: await this.getStdFeeWithDynamicBaseFee(args.fee),
832
- };
833
- }
834
- const stdGasFee = {
835
- ...(await this.getStdFeeWithDynamicBaseFee({
836
- ...(0, utils_1.getStdFee)(args.fee),
837
- gas: (0, utils_1.toBigNumber)(result.gasInfo.gasUsed)
838
- .times(this.gasBufferCoefficient)
839
- .toFixed(),
840
- })),
841
- };
842
- return {
843
- ...(0, sdk_ts_1.createTransactionWithSigners)({
844
- ...args,
845
- fee: stdGasFee,
846
- }),
847
- stdFee: stdGasFee,
848
- };
849
- }
850
- /**
851
- * Create TxRaw and simulate it
852
- */
853
- async simulateTxRaw(txRaw) {
854
- const { endpoints, httpHeaders } = this;
855
- txRaw.signatures = [new Uint8Array(0)];
856
- const client = new sdk_ts_1.TxGrpcApi(endpoints.grpc);
857
- if (httpHeaders) {
858
- client.setMetadata(httpHeaders);
859
- }
860
- const simulationResponse = await client.simulate(txRaw);
861
- return simulationResponse;
862
- }
863
- /**
864
- * Create TxRaw and simulate it
865
- */
866
- async simulateTxWithSigners(args) {
867
- const { endpoints, httpHeaders } = this;
868
- const { txRaw } = (0, sdk_ts_1.createTransactionWithSigners)(args);
869
- txRaw.signatures = Array(Array.isArray(args.signers) ? args.signers.length : 1).fill(new Uint8Array(0));
870
- const client = new sdk_ts_1.TxGrpcApi(endpoints.grpc);
871
- if (httpHeaders) {
872
- client.setMetadata(httpHeaders);
873
- }
874
- const simulationResponse = await client.simulate(txRaw);
875
- return simulationResponse;
876
- }
877
- async retryOnException(exception, retryLogic) {
878
- const errorsToRetry = Object.keys(this.retriesOnError);
879
- const errorKey = `${exception.contextModule}-${exception.contextCode}`;
880
- if (!errorsToRetry.includes(errorKey)) {
881
- throw exception;
882
- }
883
- const retryConfig = this.retriesOnError[errorKey];
884
- if (retryConfig.retries >= retryConfig.maxRetries) {
885
- this.retriesOnError = defaultRetriesConfig();
886
- throw exception;
887
- }
888
- await (0, utils_1.sleep)(retryConfig.timeout);
889
- try {
890
- retryConfig.retries += 1;
891
- return await retryLogic();
892
- }
893
- catch (e) {
894
- const error = e;
895
- if ((0, exceptions_1.isThrownException)(error)) {
896
- return this.retryOnException(error, retryLogic);
897
- }
898
- throw e;
899
- }
900
- }
901
- async fetchAccountAndBlockDetails(address) {
902
- const { endpoints, httpHeaders } = this;
903
- const chainClient = new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc);
904
- const tendermintClient = new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc);
905
- if (httpHeaders) {
906
- chainClient.setMetadata(httpHeaders);
907
- tendermintClient.setMetadata(httpHeaders);
908
- }
909
- const accountDetails = await chainClient.fetchAccount(address);
910
- const { baseAccount } = accountDetails;
911
- const latestBlock = await tendermintClient.fetchLatestBlock();
912
- const latestHeight = latestBlock.header.height;
913
- return {
914
- baseAccount,
915
- latestHeight,
916
- accountDetails,
917
- };
918
- }
919
- }
920
- exports.MsgBroadcaster = MsgBroadcaster;