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