@injectivelabs/wallet-core 1.20.7 → 1.20.9

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.
@@ -0,0 +1,1076 @@
1
+ const require_defineProperty = require('./defineProperty-CImP5zIM.cjs');
2
+ let __injectivelabs_exceptions = require("@injectivelabs/exceptions");
3
+ let __injectivelabs_ts_types = require("@injectivelabs/ts-types");
4
+ let __injectivelabs_sdk_ts_core_accounts = require("@injectivelabs/sdk-ts/core/accounts");
5
+ let __injectivelabs_sdk_ts_utils = require("@injectivelabs/sdk-ts/utils");
6
+ let __injectivelabs_sdk_ts_client_indexer = require("@injectivelabs/sdk-ts/client/indexer");
7
+ let __injectivelabs_networks = require("@injectivelabs/networks");
8
+ let __injectivelabs_sdk_ts_client_chain = require("@injectivelabs/sdk-ts/client/chain");
9
+ let __injectivelabs_utils = require("@injectivelabs/utils");
10
+ let __injectivelabs_wallet_base = require("@injectivelabs/wallet-base");
11
+ let __injectivelabs_sdk_ts_core_tx = require("@injectivelabs/sdk-ts/core/tx");
12
+
13
+ //#region src/utils/tx.ts
14
+ const checkIfTxRunOutOfGas = (e) => {
15
+ return e instanceof __injectivelabs_exceptions.TransactionException && e.contextCode === __injectivelabs_exceptions.ChainCosmosErrorCode.ErrOutOfGas && e.contextModule === __injectivelabs_exceptions.TransactionChainErrorModule.CosmosSdk && e.originalMessage.includes("out of gas");
16
+ };
17
+
18
+ //#endregion
19
+ //#region src/broadcaster/MsgBroadcaster.ts
20
+ const getEthereumWalletPubKey = async ({ pubKey, eip712TypedData, signature }) => {
21
+ if (pubKey) return pubKey;
22
+ return (0, __injectivelabs_sdk_ts_utils.hexToBase64)(await (0, __injectivelabs_sdk_ts_utils.recoverTypedSignaturePubKey)(eip712TypedData, signature));
23
+ };
24
+ const defaultRetriesConfig = () => ({ [`${__injectivelabs_exceptions.TransactionChainErrorModule.CosmosSdk}-${__injectivelabs_exceptions.ChainCosmosErrorCode.ErrMempoolIsFull}`]: {
25
+ retries: 0,
26
+ maxRetries: 10,
27
+ timeout: 1e3
28
+ } });
29
+ /**
30
+ * This class is used to broadcast transactions
31
+ * using the WalletStrategy as a handler
32
+ * for the sign/broadcast flow of the transactions
33
+ *
34
+ * Mainly used for building UI products
35
+ */
36
+ var MsgBroadcaster = class {
37
+ constructor(options) {
38
+ require_defineProperty._defineProperty(this, "options", void 0);
39
+ require_defineProperty._defineProperty(this, "walletStrategy", void 0);
40
+ require_defineProperty._defineProperty(this, "endpoints", void 0);
41
+ require_defineProperty._defineProperty(this, "chainId", void 0);
42
+ require_defineProperty._defineProperty(this, "txTimeout", __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT);
43
+ require_defineProperty._defineProperty(this, "simulateTx", true);
44
+ require_defineProperty._defineProperty(this, "txTimeoutOnFeeDelegation", false);
45
+ require_defineProperty._defineProperty(this, "evmChainId", void 0);
46
+ require_defineProperty._defineProperty(this, "gasBufferCoefficient", 1.2);
47
+ require_defineProperty._defineProperty(this, "retriesOnError", defaultRetriesConfig());
48
+ require_defineProperty._defineProperty(this, "httpHeaders", void 0);
49
+ require_defineProperty._defineProperty(this, "txInclusion", void 0);
50
+ const networkInfo = (0, __injectivelabs_networks.getNetworkInfo)(options.network);
51
+ this.options = options;
52
+ this.simulateTx = options.simulateTx !== void 0 ? options.simulateTx : true;
53
+ this.txTimeout = options.txTimeout || __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT;
54
+ this.txTimeoutOnFeeDelegation = options.txTimeoutOnFeeDelegation !== void 0 ? options.txTimeoutOnFeeDelegation : true;
55
+ this.gasBufferCoefficient = options.gasBufferCoefficient || 1.2;
56
+ this.chainId = options.chainId || networkInfo.chainId;
57
+ this.evmChainId = options.evmChainId || networkInfo.evmChainId;
58
+ this.endpoints = options.endpoints || (0, __injectivelabs_networks.getNetworkEndpoints)(options.network);
59
+ this.walletStrategy = options.walletStrategy;
60
+ this.httpHeaders = options.httpHeaders;
61
+ this.txInclusion = options.txInclusion;
62
+ }
63
+ setOptions(options) {
64
+ this.simulateTx = options.simulateTx || this.simulateTx;
65
+ this.txTimeout = options.txTimeout || this.txTimeout;
66
+ this.txTimeoutOnFeeDelegation = options.txTimeoutOnFeeDelegation || this.txTimeoutOnFeeDelegation;
67
+ this.txInclusion = options.txInclusion || this.txInclusion;
68
+ }
69
+ async getEvmChainId() {
70
+ const { walletStrategy } = this;
71
+ if (!(0, __injectivelabs_wallet_base.isEvmBrowserWallet)(walletStrategy.wallet)) return this.evmChainId;
72
+ const mainnetEvmIds = [__injectivelabs_ts_types.EvmChainId.Mainnet, __injectivelabs_ts_types.EvmChainId.MainnetEvm];
73
+ const testnetEvmIds = [__injectivelabs_ts_types.EvmChainId.Sepolia, __injectivelabs_ts_types.EvmChainId.TestnetEvm];
74
+ const devnetEvmIds = [
75
+ __injectivelabs_ts_types.EvmChainId.Sepolia,
76
+ __injectivelabs_ts_types.EvmChainId.DevnetEvm,
77
+ __injectivelabs_ts_types.EvmChainId.MainnetEvm,
78
+ __injectivelabs_ts_types.EvmChainId.TestnetEvm
79
+ ];
80
+ try {
81
+ const chainId = await walletStrategy.getEthereumChainId();
82
+ if (!chainId) return this.evmChainId;
83
+ const evmChainId = parseInt(chainId, 16);
84
+ if (isNaN(evmChainId)) return this.evmChainId;
85
+ if ((0, __injectivelabs_networks.isMainnet)(this.options.network) && !mainnetEvmIds.includes(evmChainId) || (0, __injectivelabs_networks.isTestnet)(this.options.network) && !testnetEvmIds.includes(evmChainId) || !(0, __injectivelabs_networks.isMainnet)(this.options.network) && !(0, __injectivelabs_networks.isTestnet)(this.options.network) && !devnetEvmIds.includes(evmChainId)) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Your selected network is incorrect"));
86
+ return evmChainId;
87
+ } catch (e) {
88
+ throw new __injectivelabs_exceptions.WalletException(e);
89
+ }
90
+ }
91
+ /**
92
+ * Broadcasting the transaction using the client
93
+ * side approach for both cosmos and ethereum native wallets
94
+ *
95
+ * @param tx
96
+ * @returns {string} transaction hash
97
+ */
98
+ async broadcast(tx) {
99
+ const { walletStrategy } = this;
100
+ const txWithAddresses = {
101
+ ...tx,
102
+ ethereumAddress: (0, __injectivelabs_wallet_base.getEthereumSignerAddress)(tx.injectiveAddress),
103
+ injectiveAddress: (0, __injectivelabs_wallet_base.getInjectiveSignerAddress)(tx.injectiveAddress)
104
+ };
105
+ if (__injectivelabs_sdk_ts_utils.ofacList.includes(txWithAddresses.ethereumAddress)) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("You cannot execute this transaction"));
106
+ try {
107
+ return (0, __injectivelabs_wallet_base.isCosmosWallet)(walletStrategy.wallet) ? await this.broadcastDirectSign(txWithAddresses) : (0, __injectivelabs_wallet_base.isEip712V2OnlyWallet)(walletStrategy.wallet) ? await this.broadcastEip712V2(txWithAddresses) : await this.broadcastEip712(txWithAddresses);
108
+ } catch (e) {
109
+ const error = e;
110
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionFail);
111
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) throw error;
112
+ throw new __injectivelabs_exceptions.TransactionException(new Error(error));
113
+ }
114
+ }
115
+ /**
116
+ * Broadcasting the transaction using the client
117
+ * side approach for both cosmos and ethereum native wallets
118
+ * Note: using EIP712_V2 for Ethereum wallets
119
+ *
120
+ * @param tx
121
+ * @returns {string} transaction hash
122
+ */
123
+ async broadcastV2(tx) {
124
+ const { walletStrategy } = this;
125
+ const txWithAddresses = {
126
+ ...tx,
127
+ ethereumAddress: (0, __injectivelabs_wallet_base.getEthereumSignerAddress)(tx.injectiveAddress),
128
+ injectiveAddress: (0, __injectivelabs_wallet_base.getInjectiveSignerAddress)(tx.injectiveAddress)
129
+ };
130
+ if (__injectivelabs_sdk_ts_utils.ofacList.includes(txWithAddresses.ethereumAddress)) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("You cannot execute this transaction"));
131
+ try {
132
+ return (0, __injectivelabs_wallet_base.isCosmosWallet)(walletStrategy.wallet) ? await this.broadcastDirectSign(txWithAddresses) : await this.broadcastEip712V2(txWithAddresses);
133
+ } catch (e) {
134
+ const error = e;
135
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionFail);
136
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) throw error;
137
+ throw new __injectivelabs_exceptions.TransactionException(new Error(error));
138
+ }
139
+ }
140
+ /**
141
+ * Broadcasting the transaction using the feeDelegation
142
+ * support approach for both cosmos and ethereum native wallets
143
+ *
144
+ * @param tx
145
+ * @returns {string} transaction hash
146
+ */
147
+ async broadcastWithFeeDelegation(tx) {
148
+ const { walletStrategy } = this;
149
+ const txWithAddresses = {
150
+ ...tx,
151
+ ethereumAddress: (0, __injectivelabs_wallet_base.getEthereumSignerAddress)(tx.injectiveAddress),
152
+ injectiveAddress: (0, __injectivelabs_wallet_base.getInjectiveSignerAddress)(tx.injectiveAddress)
153
+ };
154
+ if (__injectivelabs_sdk_ts_utils.ofacList.includes(txWithAddresses.ethereumAddress)) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("You cannot execute this transaction"));
155
+ try {
156
+ return (0, __injectivelabs_wallet_base.isCosmosWallet)(walletStrategy.wallet) ? await this.broadcastDirectSignWithFeeDelegation(txWithAddresses) : await this.broadcastEip712WithFeeDelegation(txWithAddresses);
157
+ } catch (e) {
158
+ const error = e;
159
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionFail);
160
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) throw error;
161
+ throw new __injectivelabs_exceptions.TransactionException(new Error(error));
162
+ }
163
+ }
164
+ /**
165
+ * Sign and broadcast a pre-built transaction whose fee payer signature
166
+ * is already provided (e.g. from the RFQ executor / web3-gw `prepare`
167
+ * endpoint). The taker is signed locally with the supplied private key.
168
+ *
169
+ * Autosign-only: the caller passes the autosign private key directly
170
+ * (e.g. `sharedWalletStore.autoSign.privateKey`). We don't go through
171
+ * `walletStrategy.signCosmosTransaction` because the PK strategy stubs
172
+ * that out — and going through the wallet strategy would defeat the
173
+ * point of autosign (no popups).
174
+ *
175
+ * @param tx Base64-encoded or raw `TxRaw` bytes returned by the prepare endpoint
176
+ * @param feePayerSig Hex (`0x...`) or base64 fee payer signature
177
+ * @param accountNumber Account number of the taker
178
+ * @param privateKey Taker (autosign) private key — hex, with or without `0x`
179
+ * @returns transaction response with txHash
180
+ */
181
+ async broadcastWithFeePayerSig({ tx, privateKey, feePayerSig, accountNumber, txInclusion, txTimeoutInBlocks: txTimeoutInBlocksParam }) {
182
+ const { chainId, endpoints, walletStrategy } = this;
183
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(txTimeoutInBlocksParam);
184
+ const pk = __injectivelabs_sdk_ts_core_accounts.PrivateKey.fromHex(privateKey);
185
+ if (__injectivelabs_sdk_ts_utils.ofacList.includes(pk.toHex().toLowerCase())) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("You cannot execute this transaction"));
186
+ const txBytes = typeof tx === "string" ? (0, __injectivelabs_sdk_ts_utils.base64ToUint8Array)(tx) : tx;
187
+ const txRaw = __injectivelabs_sdk_ts_core_tx.CosmosTxV1Beta1TxPb.TxRaw.fromBinary(txBytes);
188
+ try {
189
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationStart);
190
+ const signDoc = __injectivelabs_sdk_ts_core_tx.CosmosTxV1Beta1TxPb.SignDoc.create({
191
+ chainId,
192
+ bodyBytes: txRaw.bodyBytes,
193
+ authInfoBytes: txRaw.authInfoBytes,
194
+ accountNumber: BigInt(accountNumber)
195
+ });
196
+ const signDocBytes = __injectivelabs_sdk_ts_core_tx.CosmosTxV1Beta1TxPb.SignDoc.toBinary(signDoc);
197
+ const takerSig = await pk.sign(signDocBytes);
198
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationEnd);
199
+ txRaw.signatures = [takerSig, feePayerSig.startsWith("0x") ? (0, __injectivelabs_sdk_ts_utils.hexToUint8Array)(feePayerSig.slice(2)) : (0, __injectivelabs_sdk_ts_utils.base64ToUint8Array)(feePayerSig)];
200
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
201
+ const txInclusionOptions = this.resolveTxInclusionOptions({ txInclusion });
202
+ const txResponse = await new __injectivelabs_sdk_ts_core_tx.TxGrpcApi(endpoints.grpc).broadcast(txRaw, {
203
+ txTimeout: txTimeoutInBlocks,
204
+ ...txInclusionOptions,
205
+ onBroadcast: () => {
206
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
207
+ }
208
+ });
209
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
210
+ if (txResponse.code !== 0) throw new __injectivelabs_exceptions.TransactionException(/* @__PURE__ */ new Error(`Transaction failed - ${txResponse.rawLog} - ${txResponse.txHash}`), {
211
+ code: __injectivelabs_exceptions.UnspecifiedErrorCode,
212
+ contextCode: txResponse.code,
213
+ contextModule: txResponse.codespace
214
+ });
215
+ return txResponse;
216
+ } catch (e) {
217
+ const error = e;
218
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionFail);
219
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) throw error;
220
+ throw new __injectivelabs_exceptions.TransactionException(new Error(error));
221
+ }
222
+ }
223
+ /**
224
+ * Prepare/sign/broadcast transaction using
225
+ * Ethereum native wallets on the client side.
226
+ *
227
+ * Note: Gas estimation not available
228
+ *
229
+ * @param tx The transaction that needs to be broadcasted
230
+ * @returns transaction hash
231
+ */
232
+ async broadcastEip712(tx) {
233
+ var _tx$gas, _baseAccount$pubKey;
234
+ const { chainId, endpoints, walletStrategy } = this;
235
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
236
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
237
+ const [evmChainId, { baseAccount, latestHeight }] = await Promise.all([this.getEvmChainId(), this.fetchAccountAndBlockDetails(tx.injectiveAddress, tx.accountDetails)]);
238
+ if (!evmChainId) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Please provide evmChainId"));
239
+ const timeoutHeight = (0, __injectivelabs_utils.toBigNumber)(latestHeight.toString()).plus(txTimeoutInBlocks);
240
+ const txTimeoutTimeInSeconds = txTimeoutInBlocks * __injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS;
241
+ const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1e3;
242
+ const gas = (((_tx$gas = tx.gas) === null || _tx$gas === void 0 ? void 0 : _tx$gas.gas) || (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs)).toString();
243
+ let stdFee = (0, __injectivelabs_utils.getStdFee)({
244
+ ...tx.gas,
245
+ gas
246
+ });
247
+ /**
248
+ * Account has not been created on chain
249
+ * and we cannot simulate the transaction
250
+ * to estimate the gas
251
+ **/
252
+ if (!baseAccount.pubKey) stdFee = await this.getStdFeeWithDynamicBaseFee(stdFee);
253
+ else {
254
+ const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
255
+ chainId,
256
+ signMode: __injectivelabs_sdk_ts_core_tx.SIGN_EIP712,
257
+ memo: tx.memo,
258
+ message: msgs,
259
+ timeoutHeight: timeoutHeight.toNumber(),
260
+ signers: {
261
+ pubKey: baseAccount.pubKey.key,
262
+ accountNumber: baseAccount.accountNumber,
263
+ sequence: baseAccount.sequence
264
+ },
265
+ fee: stdFee
266
+ });
267
+ stdFee = simulatedStdFee;
268
+ }
269
+ /** EIP712 for signing on Ethereum wallets */
270
+ const eip712TypedData = (0, __injectivelabs_sdk_ts_core_tx.getEip712TypedData)({
271
+ msgs,
272
+ fee: stdFee,
273
+ tx: {
274
+ memo: tx.memo,
275
+ accountNumber: baseAccount.accountNumber.toString(),
276
+ sequence: baseAccount.sequence.toString(),
277
+ timeoutHeight: timeoutHeight.toFixed(),
278
+ chainId
279
+ },
280
+ evmChainId
281
+ });
282
+ /** Signing on Ethereum */
283
+ const signature = await walletStrategy.signEip712TypedData((0, __injectivelabs_sdk_ts_utils.safeBigIntStringify)(eip712TypedData), tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
284
+ const pubKeyOrSignatureDerivedPubKey = await getEthereumWalletPubKey({
285
+ pubKey: (_baseAccount$pubKey = baseAccount.pubKey) === null || _baseAccount$pubKey === void 0 ? void 0 : _baseAccount$pubKey.key,
286
+ eip712TypedData,
287
+ signature
288
+ });
289
+ /** Preparing the transaction for client broadcasting */
290
+ const { txRaw } = (0, __injectivelabs_sdk_ts_core_tx.createTransaction)({
291
+ message: msgs,
292
+ memo: tx.memo,
293
+ signMode: __injectivelabs_sdk_ts_core_tx.SIGN_EIP712,
294
+ fee: stdFee,
295
+ pubKey: pubKeyOrSignatureDerivedPubKey,
296
+ sequence: baseAccount.sequence,
297
+ timeoutHeight: timeoutHeight.toNumber(),
298
+ accountNumber: baseAccount.accountNumber,
299
+ chainId
300
+ });
301
+ const txRawEip712 = (0, __injectivelabs_sdk_ts_core_tx.createTxRawEIP712)(txRaw, (0, __injectivelabs_sdk_ts_core_tx.createWeb3Extension)({ evmChainId }));
302
+ /** Append Signatures */
303
+ txRawEip712.signatures = [(0, __injectivelabs_sdk_ts_utils.hexToBuff)(signature)];
304
+ const inclusionWaiter = await this.prepareTxInclusionWaiter({
305
+ tx,
306
+ txRawOrSignResponse: txRawEip712,
307
+ timeout: txTimeoutTimeInMilliSeconds
308
+ });
309
+ let response;
310
+ try {
311
+ response = await walletStrategy.sendTransaction(txRawEip712, {
312
+ chainId,
313
+ endpoints,
314
+ txTimeout: txTimeoutInBlocks,
315
+ txInclusion: this.resolveTxInclusionOptions(tx),
316
+ address: tx.injectiveAddress,
317
+ onBroadcast: () => {
318
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
319
+ }
320
+ });
321
+ } catch (e) {
322
+ inclusionWaiter.close();
323
+ throw e;
324
+ }
325
+ const confirmedTx = await this.waitForPreparedTxInclusion({
326
+ tx,
327
+ inclusionWaiter,
328
+ responseTxHash: response.txHash,
329
+ timeout: txTimeoutTimeInMilliSeconds
330
+ });
331
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
332
+ return confirmedTx;
333
+ }
334
+ /**
335
+ * Prepare/sign/broadcast transaction using
336
+ * Ethereum native wallets on the client side.
337
+ *
338
+ * Note: Gas estimation not available
339
+ *
340
+ * @param tx The transaction that needs to be broadcasted
341
+ * @returns transaction hash
342
+ */
343
+ async broadcastEip712V2(tx) {
344
+ var _tx$gas2, _baseAccount$pubKey2;
345
+ const { chainId, endpoints, walletStrategy } = this;
346
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
347
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
348
+ const [evmChainId, { baseAccount, latestHeight }] = await Promise.all([this.getEvmChainId(), this.fetchAccountAndBlockDetails(tx.injectiveAddress, tx.accountDetails)]);
349
+ if (!evmChainId) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Please provide evmChainId"));
350
+ const timeoutHeight = (0, __injectivelabs_utils.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
351
+ const txTimeoutTimeInSeconds = txTimeoutInBlocks * __injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS;
352
+ const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1e3;
353
+ const gas = (((_tx$gas2 = tx.gas) === null || _tx$gas2 === void 0 ? void 0 : _tx$gas2.gas) || (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs)).toString();
354
+ let stdFee = (0, __injectivelabs_utils.getStdFee)({
355
+ ...tx.gas,
356
+ gas
357
+ });
358
+ /**
359
+ * Account has not been created on chain
360
+ * and we cannot simulate the transaction
361
+ * to estimate the gas
362
+ **/
363
+ if (!baseAccount.pubKey) stdFee = await this.getStdFeeWithDynamicBaseFee(stdFee);
364
+ else {
365
+ const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
366
+ chainId,
367
+ signMode: __injectivelabs_sdk_ts_core_tx.SIGN_EIP712_V2,
368
+ memo: tx.memo,
369
+ message: msgs,
370
+ timeoutHeight: timeoutHeight.toNumber(),
371
+ signers: {
372
+ pubKey: baseAccount.pubKey.key,
373
+ sequence: baseAccount.sequence,
374
+ accountNumber: baseAccount.accountNumber
375
+ },
376
+ fee: stdFee
377
+ });
378
+ stdFee = simulatedStdFee;
379
+ }
380
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationStart);
381
+ /** EIP712 for signing on Ethereum wallets */
382
+ const eip712TypedData = (0, __injectivelabs_sdk_ts_core_tx.getEip712TypedDataV2)({
383
+ msgs,
384
+ fee: stdFee,
385
+ tx: {
386
+ memo: tx.memo,
387
+ accountNumber: baseAccount.accountNumber.toString(),
388
+ sequence: baseAccount.sequence.toString(),
389
+ timeoutHeight: timeoutHeight.toFixed(),
390
+ chainId
391
+ },
392
+ evmChainId
393
+ });
394
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationEnd);
395
+ /** Signing on Ethereum */
396
+ const signature = await walletStrategy.signEip712TypedData((0, __injectivelabs_sdk_ts_utils.safeBigIntStringify)(eip712TypedData), tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
397
+ const pubKeyOrSignatureDerivedPubKey = await getEthereumWalletPubKey({
398
+ pubKey: (_baseAccount$pubKey2 = baseAccount.pubKey) === null || _baseAccount$pubKey2 === void 0 ? void 0 : _baseAccount$pubKey2.key,
399
+ eip712TypedData,
400
+ signature
401
+ });
402
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
403
+ const { txRaw } = (0, __injectivelabs_sdk_ts_core_tx.createTransaction)({
404
+ message: msgs,
405
+ memo: tx.memo,
406
+ signMode: __injectivelabs_sdk_ts_core_tx.SIGN_EIP712_V2,
407
+ fee: stdFee,
408
+ pubKey: pubKeyOrSignatureDerivedPubKey,
409
+ sequence: baseAccount.sequence,
410
+ timeoutHeight: timeoutHeight.toNumber(),
411
+ accountNumber: baseAccount.accountNumber,
412
+ chainId
413
+ });
414
+ const txRawEip712 = (0, __injectivelabs_sdk_ts_core_tx.createTxRawEIP712)(txRaw, (0, __injectivelabs_sdk_ts_core_tx.createWeb3Extension)({ evmChainId }));
415
+ /** Append Signatures */
416
+ txRawEip712.signatures = [(0, __injectivelabs_sdk_ts_utils.hexToBuff)(signature)];
417
+ const inclusionWaiter = await this.prepareTxInclusionWaiter({
418
+ tx,
419
+ timeout: txTimeoutTimeInMilliSeconds,
420
+ txRawOrSignResponse: txRawEip712
421
+ });
422
+ let response;
423
+ try {
424
+ response = await walletStrategy.sendTransaction(txRawEip712, {
425
+ chainId,
426
+ endpoints,
427
+ txTimeout: txTimeoutInBlocks,
428
+ txInclusion: this.resolveTxInclusionOptions(tx),
429
+ address: tx.injectiveAddress,
430
+ onBroadcast: () => {
431
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
432
+ }
433
+ });
434
+ } catch (e) {
435
+ inclusionWaiter.close();
436
+ throw e;
437
+ }
438
+ const confirmedTx = await this.waitForPreparedTxInclusion({
439
+ tx,
440
+ inclusionWaiter,
441
+ responseTxHash: response.txHash,
442
+ timeout: txTimeoutTimeInMilliSeconds
443
+ });
444
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
445
+ return confirmedTx;
446
+ }
447
+ /**
448
+ * Prepare/sign/broadcast transaction using
449
+ * Ethereum native wallets using the Web3Gateway.
450
+ *
451
+ * @param tx The transaction that needs to be broadcasted
452
+ * @returns transaction hash
453
+ */
454
+ async broadcastEip712WithFeeDelegation(tx) {
455
+ const { endpoints, simulateTx, httpHeaders, walletStrategy, txTimeoutOnFeeDelegation } = this;
456
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
457
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
458
+ const web3Msgs = msgs.map((msg) => msg.toWeb3());
459
+ const evmChainId = await this.getEvmChainId();
460
+ if (!evmChainId) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Please provide evmChainId"));
461
+ const transactionApi = new __injectivelabs_sdk_ts_client_indexer.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
462
+ if (httpHeaders) transactionApi.setMetadata(httpHeaders);
463
+ const txTimeoutTimeInSeconds = txTimeoutInBlocks * __injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS;
464
+ const txTimeoutTimeInMilliSeconds = txTimeoutTimeInSeconds * 1e3;
465
+ let timeoutHeight = void 0;
466
+ if (txTimeoutOnFeeDelegation) timeoutHeight = (0, __injectivelabs_utils.toBigNumber)((await new __injectivelabs_sdk_ts_client_chain.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock()).header.height.toString()).plus(txTimeoutInBlocks).toNumber();
467
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationStart);
468
+ const prepareTxResponse = await transactionApi.prepareTxRequest({
469
+ timeoutHeight,
470
+ memo: tx.memo,
471
+ message: web3Msgs,
472
+ address: tx.ethereumAddress,
473
+ chainId: evmChainId,
474
+ gasLimit: (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs),
475
+ estimateGas: simulateTx
476
+ });
477
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationEnd);
478
+ const signature = await walletStrategy.signEip712TypedData(prepareTxResponse.data, tx.ethereumAddress, { txTimeout: txTimeoutTimeInSeconds });
479
+ const broadcast = async () => await transactionApi.broadcastTxRequest({
480
+ signature,
481
+ message: web3Msgs,
482
+ txResponse: prepareTxResponse,
483
+ chainId: evmChainId
484
+ });
485
+ try {
486
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
487
+ const response = await broadcast();
488
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
489
+ const confirmedTx = await this.waitForTxInclusion({
490
+ tx,
491
+ txHash: response.txHash,
492
+ timeout: txTimeoutTimeInMilliSeconds
493
+ });
494
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
495
+ return confirmedTx;
496
+ } catch (e) {
497
+ const error = e;
498
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) {
499
+ const exception = error;
500
+ /**
501
+ * First MsgExec transaction with a PrivateKey wallet
502
+ * always runs out of gas for some reason, temporary solution
503
+ * to just broadcast the transaction twice
504
+ **/
505
+ if (walletStrategy.wallet === __injectivelabs_wallet_base.Wallet.PrivateKey && checkIfTxRunOutOfGas(exception)) {
506
+ const { baseAccount } = await new __injectivelabs_sdk_ts_client_chain.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
507
+ /** We only do it on the first account tx fail */
508
+ if (baseAccount.sequence > 1) throw e;
509
+ return await this.broadcastEip712WithFeeDelegation(tx);
510
+ }
511
+ return await this.retryOnException(exception, broadcast);
512
+ }
513
+ throw e;
514
+ }
515
+ }
516
+ /**
517
+ * Prepare/sign/broadcast transaction using
518
+ * Cosmos native wallets on the client side.
519
+ *
520
+ * @param tx The transaction that needs to be broadcasted
521
+ * @returns transaction hash
522
+ */
523
+ async broadcastDirectSign(tx) {
524
+ var _tx$gas3;
525
+ const { chainId, endpoints, walletStrategy } = this;
526
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
527
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
528
+ /**
529
+ * When using Ledger with Keplr/Leap we have
530
+ * to send EIP712 to sign on Keplr/Leap
531
+ */
532
+ if ([__injectivelabs_wallet_base.Wallet.Keplr, __injectivelabs_wallet_base.Wallet.Leap].includes(walletStrategy.getWallet())) {
533
+ if (await walletStrategy.getWalletDeviceType() === __injectivelabs_wallet_base.WalletDeviceType.Hardware) return this.experimentalBroadcastWalletThroughLedger(tx);
534
+ }
535
+ const [{ baseAccount, latestHeight }, pubKey] = await Promise.all([this.fetchAccountAndBlockDetails(tx.injectiveAddress, tx.accountDetails), walletStrategy.getPubKey(tx.injectiveAddress)]);
536
+ const timeoutHeight = (0, __injectivelabs_utils.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
537
+ const txTimeoutTimeInMilliSeconds = txTimeoutInBlocks * __injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS * 1e3;
538
+ const signMode = (0, __injectivelabs_wallet_base.isCosmosAminoOnlyWallet)(walletStrategy.wallet) ? __injectivelabs_sdk_ts_core_tx.SIGN_EIP712 : __injectivelabs_sdk_ts_core_tx.SIGN_DIRECT;
539
+ const gas = (((_tx$gas3 = tx.gas) === null || _tx$gas3 === void 0 ? void 0 : _tx$gas3.gas) || (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs)).toString();
540
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationStart);
541
+ /** Prepare the Transaction * */
542
+ const { txRaw } = await this.getTxWithSignersAndStdFee({
543
+ chainId,
544
+ signMode,
545
+ memo: tx.memo,
546
+ message: msgs,
547
+ timeoutHeight: timeoutHeight.toNumber(),
548
+ signers: {
549
+ pubKey,
550
+ accountNumber: baseAccount.accountNumber,
551
+ sequence: baseAccount.sequence
552
+ },
553
+ fee: (0, __injectivelabs_utils.getStdFee)({
554
+ ...tx.gas,
555
+ gas
556
+ })
557
+ });
558
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationEnd);
559
+ /** Ledger using Cosmos app only allows signing amino docs */
560
+ if ((0, __injectivelabs_wallet_base.isCosmosAminoOnlyWallet)(walletStrategy.wallet)) {
561
+ var _tx$gas4;
562
+ const aminoSignDoc = (0, __injectivelabs_sdk_ts_core_tx.getAminoStdSignDoc)({
563
+ ...tx,
564
+ ...baseAccount,
565
+ msgs,
566
+ chainId,
567
+ 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()),
568
+ timeoutHeight: timeoutHeight.toFixed()
569
+ });
570
+ txRaw.signatures = [(0, __injectivelabs_sdk_ts_utils.base64ToUint8Array)((await walletStrategy.signAminoCosmosTransaction({
571
+ signDoc: aminoSignDoc,
572
+ address: tx.injectiveAddress
573
+ })).signature.signature)];
574
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
575
+ const inclusionWaiter$1 = await this.prepareTxInclusionWaiter({
576
+ tx,
577
+ txRawOrSignResponse: txRaw,
578
+ timeout: txTimeoutTimeInMilliSeconds
579
+ });
580
+ let response$1;
581
+ try {
582
+ response$1 = await walletStrategy.sendTransaction(txRaw, {
583
+ chainId,
584
+ endpoints,
585
+ address: tx.injectiveAddress,
586
+ txTimeout: txTimeoutInBlocks,
587
+ txInclusion: this.resolveTxInclusionOptions(tx),
588
+ onBroadcast: () => {
589
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
590
+ }
591
+ });
592
+ } catch (e) {
593
+ inclusionWaiter$1.close();
594
+ throw e;
595
+ }
596
+ const confirmedTx$1 = await this.waitForPreparedTxInclusion({
597
+ tx,
598
+ inclusionWaiter: inclusionWaiter$1,
599
+ timeout: txTimeoutTimeInMilliSeconds,
600
+ responseTxHash: response$1.txHash
601
+ });
602
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
603
+ return confirmedTx$1;
604
+ }
605
+ const directSignResponse = await walletStrategy.signCosmosTransaction({
606
+ txRaw,
607
+ chainId,
608
+ address: tx.injectiveAddress,
609
+ accountNumber: baseAccount.accountNumber
610
+ });
611
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
612
+ const inclusionWaiter = await this.prepareTxInclusionWaiter({
613
+ tx,
614
+ timeout: txTimeoutTimeInMilliSeconds,
615
+ txRawOrSignResponse: directSignResponse
616
+ });
617
+ let response;
618
+ try {
619
+ response = await walletStrategy.sendTransaction(directSignResponse, {
620
+ chainId,
621
+ endpoints,
622
+ txTimeout: txTimeoutInBlocks,
623
+ txInclusion: this.resolveTxInclusionOptions(tx),
624
+ address: tx.injectiveAddress,
625
+ onBroadcast: () => {
626
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
627
+ }
628
+ });
629
+ } catch (e) {
630
+ inclusionWaiter.close();
631
+ throw e;
632
+ }
633
+ const confirmedTx = await this.waitForPreparedTxInclusion({
634
+ tx,
635
+ inclusionWaiter,
636
+ responseTxHash: response.txHash,
637
+ timeout: txTimeoutTimeInMilliSeconds
638
+ });
639
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
640
+ return confirmedTx;
641
+ }
642
+ /**
643
+ * We use this method only when we want to broadcast a transaction using Ledger on Keplr/Leap for Injective
644
+ *
645
+ * Note: Gas estimation not available
646
+ * @param tx the transaction that needs to be broadcasted
647
+ */
648
+ async experimentalBroadcastWalletThroughLedger(tx) {
649
+ var _tx$gas5, _tx$gas6;
650
+ const { chainId, endpoints, evmChainId, simulateTx, walletStrategy } = this;
651
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
652
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
653
+ /**
654
+ * We can only use this method
655
+ * when Ledger is connected through Keplr
656
+ */
657
+ if ([__injectivelabs_wallet_base.Wallet.Keplr, __injectivelabs_wallet_base.Wallet.Leap].includes(walletStrategy.getWallet())) {
658
+ if (!(await walletStrategy.getWalletDeviceType() === __injectivelabs_wallet_base.WalletDeviceType.Hardware)) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error(`This method can only be used when Ledger is connected through ${walletStrategy.getWallet()}`));
659
+ }
660
+ if (!evmChainId) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Please provide evmChainId"));
661
+ const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
662
+ const [{ baseAccount, latestHeight }, pubKey] = await Promise.all([this.fetchAccountAndBlockDetails(tx.injectiveAddress, tx.accountDetails), walletStrategy.getPubKey()]);
663
+ const timeoutHeight = (0, __injectivelabs_utils.toBigNumber)(latestHeight).plus(txTimeoutInBlocks);
664
+ const gas = (((_tx$gas5 = tx.gas) === null || _tx$gas5 === void 0 ? void 0 : _tx$gas5.gas) || (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs)).toString();
665
+ /** EIP712 for signing on Ethereum wallets */
666
+ const eip712TypedData = (0, __injectivelabs_sdk_ts_core_tx.getEip712TypedData)({
667
+ msgs,
668
+ fee: await this.getStdFeeWithDynamicBaseFee({
669
+ ...tx.gas,
670
+ gas
671
+ }),
672
+ tx: {
673
+ chainId,
674
+ memo: tx.memo,
675
+ timeoutHeight: timeoutHeight.toFixed(),
676
+ sequence: baseAccount.sequence.toString(),
677
+ accountNumber: baseAccount.accountNumber.toString()
678
+ },
679
+ evmChainId
680
+ });
681
+ const aminoSignResponse = await cosmosWallet.signEIP712CosmosTx({
682
+ eip712: eip712TypedData,
683
+ signDoc: (0, __injectivelabs_wallet_base.createEip712StdSignDoc)({
684
+ ...tx,
685
+ ...baseAccount,
686
+ msgs,
687
+ chainId,
688
+ 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()),
689
+ timeoutHeight: timeoutHeight.toFixed()
690
+ })
691
+ });
692
+ /**
693
+ * Create TxRaw from the signed tx that we
694
+ * get as a response in case the user changed the fee/memo
695
+ * on the Keplr popup
696
+ */
697
+ const { txRaw } = (0, __injectivelabs_sdk_ts_core_tx.createTransaction)({
698
+ pubKey,
699
+ chainId,
700
+ message: msgs,
701
+ signMode: __injectivelabs_sdk_ts_core_tx.SIGN_EIP712,
702
+ memo: aminoSignResponse.signed.memo,
703
+ fee: aminoSignResponse.signed.fee,
704
+ sequence: parseInt(aminoSignResponse.signed.sequence, 10),
705
+ accountNumber: parseInt(aminoSignResponse.signed.account_number, 10),
706
+ timeoutHeight: parseInt(aminoSignResponse.signed.timeout_height, 10)
707
+ });
708
+ const txRawEip712 = (0, __injectivelabs_sdk_ts_core_tx.createTxRawEIP712)(txRaw, (0, __injectivelabs_sdk_ts_core_tx.createWeb3Extension)({ evmChainId }));
709
+ if (simulateTx) await this.simulateTxRaw(txRawEip712);
710
+ txRawEip712.signatures = [(0, __injectivelabs_sdk_ts_utils.base64ToUint8Array)(aminoSignResponse.signature.signature)];
711
+ /** Broadcast the transaction */
712
+ const response = await new __injectivelabs_sdk_ts_core_tx.TxGrpcApi(endpoints.grpc).broadcast(txRawEip712, {
713
+ txTimeout: txTimeoutInBlocks,
714
+ ...this.resolveTxInclusionOptions(tx),
715
+ onBroadcast: () => {
716
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
717
+ }
718
+ });
719
+ if (response.code !== 0) throw new __injectivelabs_exceptions.TransactionException(new Error(response.rawLog), {
720
+ code: __injectivelabs_exceptions.UnspecifiedErrorCode,
721
+ contextCode: response.code,
722
+ contextModule: response.codespace
723
+ });
724
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
725
+ return response;
726
+ }
727
+ /**
728
+ * Prepare/sign/broadcast transaction using
729
+ * Cosmos native wallets using the Web3Gateway.
730
+ *
731
+ * @param tx The transaction that needs to be broadcasted
732
+ * @returns transaction hash
733
+ */
734
+ async broadcastDirectSignWithFeeDelegation(tx) {
735
+ var _tx$gas7;
736
+ const { options, chainId, endpoints, simulateTx, httpHeaders, walletStrategy, txTimeoutOnFeeDelegation } = this;
737
+ const txTimeoutInBlocks = this.resolveTimeoutInBlocks(tx.txTimeoutInBlocks);
738
+ const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
739
+ /**
740
+ * We can only use this method when Keplr is connected
741
+ * with ledger
742
+ */
743
+ if (walletStrategy.getWallet() === __injectivelabs_wallet_base.Wallet.Keplr) {
744
+ if (await walletStrategy.getWalletDeviceType() === __injectivelabs_wallet_base.WalletDeviceType.Hardware) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Keplr + Ledger is not available with fee delegation. Connect with Ledger directly."));
745
+ }
746
+ const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
747
+ const canDisableCosmosGasCheck = [__injectivelabs_wallet_base.Wallet.Keplr, __injectivelabs_wallet_base.Wallet.OWallet].includes(walletStrategy.wallet);
748
+ const feePayerPubKey = await this.fetchFeePayerPubKey(options.feePayerPubKey);
749
+ const feePayerPublicKey = __injectivelabs_sdk_ts_core_accounts.PublicKey.fromBase64(feePayerPubKey);
750
+ const feePayer = feePayerPublicKey.toAddress().address;
751
+ const transactionApi = new __injectivelabs_sdk_ts_client_indexer.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
752
+ if (httpHeaders) transactionApi.setMetadata(httpHeaders);
753
+ const fetchAccountBlockDetails = async () => {
754
+ try {
755
+ const { baseAccount: baseAccount$1, latestHeight: latestHeight$1 } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress, tx.accountDetails);
756
+ return {
757
+ baseAccount: baseAccount$1,
758
+ latestHeight: latestHeight$1
759
+ };
760
+ } catch (e) {
761
+ const error = e;
762
+ if ((0, __injectivelabs_exceptions.isThrownException)(error) && error.message.toLowerCase().includes(`account ${tx.injectiveAddress} not found`)) {
763
+ await transactionApi.prepareCosmosTxRequest({
764
+ address: tx.injectiveAddress,
765
+ message: msgs.map((msg) => msg.toWeb3Gw()),
766
+ memo: tx.memo,
767
+ estimateGas: simulateTx
768
+ });
769
+ const { baseAccount: baseAccount$1, latestHeight: latestHeight$1 } = await this.fetchAccountAndBlockDetails(tx.injectiveAddress);
770
+ return {
771
+ baseAccount: baseAccount$1,
772
+ latestHeight: latestHeight$1
773
+ };
774
+ }
775
+ throw e;
776
+ }
777
+ };
778
+ /** Account Details * */
779
+ const { baseAccount, latestHeight } = await fetchAccountBlockDetails();
780
+ const chainGrpcAuthApi = new __injectivelabs_sdk_ts_client_chain.ChainGrpcAuthApi(endpoints.grpc);
781
+ if (httpHeaders) chainGrpcAuthApi.setMetadata(httpHeaders);
782
+ const { baseAccount: feePayerBaseAccount } = await chainGrpcAuthApi.fetchAccount(feePayer);
783
+ const timeoutHeight = (0, __injectivelabs_utils.toBigNumber)(latestHeight).plus(txTimeoutOnFeeDelegation ? txTimeoutInBlocks : __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT);
784
+ const txTimeoutTimeInMilliSeconds = txTimeoutInBlocks * __injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS * 1e3;
785
+ const pubKey = await walletStrategy.getPubKey();
786
+ const gas = (((_tx$gas7 = tx.gas) === null || _tx$gas7 === void 0 ? void 0 : _tx$gas7.gas) || (0, __injectivelabs_sdk_ts_utils.getGasPriceBasedOnMessage)(msgs)).toString();
787
+ /** Prepare the Transaction * */
788
+ const { txRaw } = await this.getTxWithSignersAndStdFee({
789
+ chainId,
790
+ memo: tx.memo,
791
+ message: msgs,
792
+ timeoutHeight: timeoutHeight.toNumber(),
793
+ signers: [{
794
+ pubKey,
795
+ accountNumber: baseAccount.accountNumber,
796
+ sequence: baseAccount.sequence
797
+ }, {
798
+ pubKey: feePayerPublicKey.toBase64(),
799
+ accountNumber: feePayerBaseAccount.accountNumber,
800
+ sequence: feePayerBaseAccount.sequence
801
+ }],
802
+ fee: (0, __injectivelabs_utils.getStdFee)({
803
+ ...tx.gas,
804
+ gas,
805
+ payer: feePayer
806
+ })
807
+ });
808
+ if (canDisableCosmosGasCheck && cosmosWallet.disableGasCheck) cosmosWallet.disableGasCheck(chainId);
809
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationStart);
810
+ const directSignResponse = await walletStrategy.signCosmosTransaction({
811
+ txRaw,
812
+ chainId,
813
+ address: tx.injectiveAddress,
814
+ accountNumber: baseAccount.accountNumber
815
+ });
816
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionPreparationEnd);
817
+ const signedTxRaw = (0, __injectivelabs_sdk_ts_core_tx.createTxRawFromSigResponse)(directSignResponse);
818
+ const broadcast = async () => await transactionApi.broadcastCosmosTxRequest({
819
+ txRaw: signedTxRaw,
820
+ address: tx.injectiveAddress,
821
+ signature: directSignResponse.signature.signature,
822
+ pubKey: directSignResponse.signature.pub_key || {
823
+ value: pubKey,
824
+ type: "/injective.crypto.v1beta1.ethsecp256k1.PubKey"
825
+ }
826
+ });
827
+ try {
828
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastStart);
829
+ const inclusionWaiter = await this.prepareTxInclusionWaiter({
830
+ tx,
831
+ txRawOrSignResponse: signedTxRaw,
832
+ timeout: txTimeoutTimeInMilliSeconds
833
+ });
834
+ let response;
835
+ try {
836
+ response = await broadcast();
837
+ } catch (e) {
838
+ inclusionWaiter.close();
839
+ throw e;
840
+ }
841
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastSynced);
842
+ if (canDisableCosmosGasCheck && cosmosWallet.enableGasCheck) cosmosWallet.enableGasCheck(chainId);
843
+ const confirmedTx = await this.waitForPreparedTxInclusion({
844
+ tx,
845
+ inclusionWaiter,
846
+ responseTxHash: response.txHash,
847
+ timeout: txTimeoutTimeInMilliSeconds
848
+ });
849
+ walletStrategy.emit(__injectivelabs_wallet_base.WalletStrategyEmitterEventType.TransactionBroadcastEnd);
850
+ return confirmedTx;
851
+ } catch (e) {
852
+ const error = e;
853
+ if ((0, __injectivelabs_exceptions.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 __injectivelabs_sdk_ts_client_indexer.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
869
+ if (httpHeaders) transactionApi.setMetadata(httpHeaders);
870
+ const response = await transactionApi.fetchFeePayer();
871
+ if (!response.feePayerPubKey) throw new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Please provide a feePayerPubKey"));
872
+ if (response.feePayerPubKey.key.startsWith("0x") || response.feePayerPubKey.key.length === 66) return (0, __injectivelabs_sdk_ts_utils.uint8ArrayToBase64)((0, __injectivelabs_sdk_ts_utils.hexToUint8Array)(response.feePayerPubKey.key));
873
+ return response.feePayerPubKey.key;
874
+ }
875
+ async getStdFeeWithDynamicBaseFee(args) {
876
+ const client = new __injectivelabs_sdk_ts_client_chain.ChainGrpcTxFeesApi(this.endpoints.grpc);
877
+ let baseFee = __injectivelabs_utils.DEFAULT_GAS_PRICE;
878
+ try {
879
+ const response = await client.fetchEipBaseFee();
880
+ baseFee = Number((response === null || response === void 0 ? void 0 : response.baseFee) || __injectivelabs_utils.DEFAULT_GAS_PRICE);
881
+ } catch (_unused) {}
882
+ if (!args) return (0, __injectivelabs_utils.getStdFee)(baseFee ? { gasPrice: baseFee } : {});
883
+ if (typeof args === "string") return (0, __injectivelabs_utils.getStdFee)({
884
+ ...baseFee && { gasPrice: (0, __injectivelabs_utils.toBigNumber)(baseFee).toFixed() },
885
+ gas: args
886
+ });
887
+ return (0, __injectivelabs_utils.getStdFee)({
888
+ ...args,
889
+ ...baseFee && { gasPrice: (0, __injectivelabs_utils.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
+ ...(0, __injectivelabs_sdk_ts_core_tx.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
+ ...(0, __injectivelabs_sdk_ts_core_tx.createTransactionWithSigners)(args),
910
+ stdFee: await this.getStdFeeWithDynamicBaseFee(args.fee)
911
+ };
912
+ const stdGasFee = { ...await this.getStdFeeWithDynamicBaseFee({
913
+ ...(0, __injectivelabs_utils.getStdFee)(args.fee),
914
+ gas: (0, __injectivelabs_utils.toBigNumber)(result.gasInfo.gasUsed).times(this.gasBufferCoefficient).toFixed()
915
+ }) };
916
+ return {
917
+ ...(0, __injectivelabs_sdk_ts_core_tx.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 __injectivelabs_sdk_ts_core_tx.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 } = (0, __injectivelabs_sdk_ts_core_tx.createTransactionWithSigners)(args);
940
+ txRaw.signatures = Array(Array.isArray(args.signers) ? args.signers.length : 1).fill(new Uint8Array(0));
941
+ const client = new __injectivelabs_sdk_ts_core_tx.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 (0, __injectivelabs_utils.sleep)(retryConfig.timeout);
955
+ try {
956
+ retryConfig.retries += 1;
957
+ return await retryLogic();
958
+ } catch (e) {
959
+ const error = e;
960
+ if ((0, __injectivelabs_exceptions.isThrownException)(error)) return this.retryOnException(error, retryLogic);
961
+ throw e;
962
+ }
963
+ }
964
+ async fetchAccountAndBlockDetails(address, existingAccountDetails) {
965
+ const { endpoints, httpHeaders } = this;
966
+ const tendermintClient = new __injectivelabs_sdk_ts_client_chain.ChainGrpcTendermintApi(endpoints.grpc);
967
+ if (httpHeaders) tendermintClient.setMetadata(httpHeaders);
968
+ if (existingAccountDetails) return {
969
+ baseAccount: existingAccountDetails,
970
+ latestHeight: (await tendermintClient.fetchLatestBlock()).header.height.toString()
971
+ };
972
+ const chainClient = new __injectivelabs_sdk_ts_client_chain.ChainGrpcAuthApi(endpoints.grpc);
973
+ if (httpHeaders) chainClient.setMetadata(httpHeaders);
974
+ const [accountDetails, latestBlock] = await Promise.all([chainClient.fetchAccount(address), tendermintClient.fetchLatestBlock()]);
975
+ const { baseAccount } = accountDetails;
976
+ return {
977
+ baseAccount,
978
+ latestHeight: latestBlock.header.height.toString()
979
+ };
980
+ }
981
+ resolveTimeoutInBlocks(override) {
982
+ return typeof override === "number" && Number.isInteger(override) && override > 0 ? override : this.txTimeout;
983
+ }
984
+ resolveTxInclusionOptions(tx) {
985
+ var _txInclusion$eventInc;
986
+ const txInclusion = (tx === null || tx === void 0 ? void 0 : tx.txInclusion) || this.txInclusion;
987
+ if (!txInclusion) return;
988
+ return {
989
+ ...txInclusion,
990
+ eventInclusion: {
991
+ ...txInclusion.eventInclusion,
992
+ rpcEndpoint: ((_txInclusion$eventInc = txInclusion.eventInclusion) === null || _txInclusion$eventInc === void 0 ? void 0 : _txInclusion$eventInc.rpcEndpoint) || this.endpoints.rpc
993
+ }
994
+ };
995
+ }
996
+ createTxGrpcApi() {
997
+ const client = new __injectivelabs_sdk_ts_core_tx.TxGrpcApi(this.endpoints.grpc);
998
+ if (this.httpHeaders) client.setMetadata(this.httpHeaders);
999
+ return client;
1000
+ }
1001
+ async waitForTxInclusion({ tx, txHash, timeout }) {
1002
+ return this.createTxGrpcApi().waitForTxInclusion({
1003
+ txHash,
1004
+ timeout,
1005
+ options: this.resolveTxInclusionOptions(tx)
1006
+ });
1007
+ }
1008
+ async prepareTxInclusionWaiter({ tx, timeout, txRawOrSignResponse }) {
1009
+ const txRaw = (0, __injectivelabs_sdk_ts_core_tx.createTxRawFromSigResponse)(txRawOrSignResponse);
1010
+ const txHash = __injectivelabs_sdk_ts_core_tx.TxClient.hash(txRaw);
1011
+ return this.createTxGrpcApi().prepareTxInclusionWait({
1012
+ txHash,
1013
+ timeout,
1014
+ options: this.resolveTxInclusionOptions(tx)
1015
+ });
1016
+ }
1017
+ async waitForPreparedTxInclusion({ tx, timeout, responseTxHash, inclusionWaiter }) {
1018
+ if (!inclusionWaiter) return this.waitForTxInclusion({
1019
+ tx,
1020
+ timeout,
1021
+ txHash: responseTxHash
1022
+ });
1023
+ const confirmedTx = await inclusionWaiter.wait(responseTxHash);
1024
+ if (!confirmedTx) throw new __injectivelabs_exceptions.TransactionException(/* @__PURE__ */ new Error(`The transaction with ${responseTxHash} is not found`));
1025
+ return confirmedTx;
1026
+ }
1027
+ };
1028
+
1029
+ //#endregion
1030
+ //#region src/broadcaster/Web3Broadcaster.ts
1031
+ /**
1032
+ * Preparing and broadcasting
1033
+ * Ethereum transactions
1034
+ */
1035
+ var Web3Broadcaster = class {
1036
+ constructor({ walletStrategy, evmChainId }) {
1037
+ require_defineProperty._defineProperty(this, "walletStrategy", void 0);
1038
+ require_defineProperty._defineProperty(this, "evmChainId", void 0);
1039
+ this.evmChainId = evmChainId;
1040
+ this.walletStrategy = walletStrategy;
1041
+ }
1042
+ async sendTransaction(args) {
1043
+ const { evmChainId, walletStrategy } = this;
1044
+ try {
1045
+ const chainId = args.evmChainId || evmChainId;
1046
+ const txHash = await walletStrategy.sendEvmTransaction(args.tx, {
1047
+ evmChainId: chainId,
1048
+ address: args.address
1049
+ });
1050
+ await walletStrategy.getEvmTransactionReceipt(txHash, chainId);
1051
+ return txHash;
1052
+ } catch (e) {
1053
+ throw new __injectivelabs_exceptions.Web3Exception(new Error(e.message));
1054
+ }
1055
+ }
1056
+ };
1057
+
1058
+ //#endregion
1059
+ Object.defineProperty(exports, 'MsgBroadcaster', {
1060
+ enumerable: true,
1061
+ get: function () {
1062
+ return MsgBroadcaster;
1063
+ }
1064
+ });
1065
+ Object.defineProperty(exports, 'Web3Broadcaster', {
1066
+ enumerable: true,
1067
+ get: function () {
1068
+ return Web3Broadcaster;
1069
+ }
1070
+ });
1071
+ Object.defineProperty(exports, 'checkIfTxRunOutOfGas', {
1072
+ enumerable: true,
1073
+ get: function () {
1074
+ return checkIfTxRunOutOfGas;
1075
+ }
1076
+ });