@injectivelabs/wallet-core 1.14.41-alpha.5 → 1.14.41-alpha.7
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.
- package/dist/cjs/broadcaster/MsgBroadcaster.d.ts +5 -5
- package/dist/cjs/broadcaster/MsgBroadcaster.d.ts.map +1 -1
- package/dist/cjs/broadcaster/MsgBroadcaster.js +600 -601
- package/dist/cjs/broadcaster/MsgBroadcaster.js.map +1 -1
- package/dist/cjs/broadcaster/Web3Broadcaster.js +15 -24
- package/dist/cjs/broadcaster/Web3Broadcaster.js.map +1 -1
- package/dist/cjs/strategy/BaseWalletStrategy.js +61 -91
- package/dist/cjs/strategy/BaseWalletStrategy.js.map +1 -1
- package/dist/esm/broadcaster/MsgBroadcaster.d.ts +5 -5
- package/dist/esm/broadcaster/MsgBroadcaster.d.ts.map +1 -1
- package/dist/esm/broadcaster/MsgBroadcaster.js +14 -14
- package/dist/esm/broadcaster/MsgBroadcaster.js.map +1 -1
- package/package.json +11 -16
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.MsgBroadcaster = void 0;
|
|
13
4
|
const sdk_ts_1 = require("@injectivelabs/sdk-ts");
|
|
@@ -37,12 +28,17 @@ const defaultRetriesConfig = () => ({
|
|
|
37
28
|
* Mainly used for building UI products
|
|
38
29
|
*/
|
|
39
30
|
class MsgBroadcaster {
|
|
31
|
+
options;
|
|
32
|
+
walletStrategy;
|
|
33
|
+
endpoints;
|
|
34
|
+
chainId;
|
|
35
|
+
txTimeout = utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT;
|
|
36
|
+
simulateTx = true;
|
|
37
|
+
txTimeoutOnFeeDelegation = false;
|
|
38
|
+
ethereumChainId;
|
|
39
|
+
gasBufferCoefficient = 1.2;
|
|
40
|
+
retriesOnError = defaultRetriesConfig();
|
|
40
41
|
constructor(options) {
|
|
41
|
-
this.txTimeout = utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT;
|
|
42
|
-
this.simulateTx = true;
|
|
43
|
-
this.txTimeoutOnFeeDelegation = false;
|
|
44
|
-
this.gasBufferCoefficient = 1.2;
|
|
45
|
-
this.retriesOnError = defaultRetriesConfig();
|
|
46
42
|
const networkInfo = (0, networks_1.getNetworkInfo)(options.network);
|
|
47
43
|
this.options = options;
|
|
48
44
|
this.simulateTx =
|
|
@@ -72,28 +68,30 @@ class MsgBroadcaster {
|
|
|
72
68
|
* @param tx
|
|
73
69
|
* @returns {string} transaction hash
|
|
74
70
|
*/
|
|
75
|
-
broadcast(tx) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
71
|
+
async broadcast(tx) {
|
|
72
|
+
const { walletStrategy } = this;
|
|
73
|
+
const txWithAddresses = {
|
|
74
|
+
...tx,
|
|
75
|
+
ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
|
|
76
|
+
injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
|
|
77
|
+
};
|
|
78
|
+
if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
|
|
79
|
+
throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
|
|
83
|
+
? await this.broadcastDirectSign(txWithAddresses)
|
|
84
|
+
: (0, wallet_base_1.isEip712V2OnlyWallet)(walletStrategy.wallet)
|
|
85
|
+
? await this.broadcastEip712V2(txWithAddresses)
|
|
86
|
+
: await this.broadcastEip712(txWithAddresses);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
const error = e;
|
|
90
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
throw new exceptions_1.TransactionException(new Error(error));
|
|
94
|
+
}
|
|
97
95
|
}
|
|
98
96
|
/**
|
|
99
97
|
* Broadcasting the transaction using the client
|
|
@@ -103,26 +101,28 @@ class MsgBroadcaster {
|
|
|
103
101
|
* @param tx
|
|
104
102
|
* @returns {string} transaction hash
|
|
105
103
|
*/
|
|
106
|
-
broadcastV2(tx) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
104
|
+
async broadcastV2(tx) {
|
|
105
|
+
const { walletStrategy } = this;
|
|
106
|
+
const txWithAddresses = {
|
|
107
|
+
...tx,
|
|
108
|
+
ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
|
|
109
|
+
injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
|
|
110
|
+
};
|
|
111
|
+
if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
|
|
112
|
+
throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
|
|
116
|
+
? await this.broadcastDirectSign(txWithAddresses)
|
|
117
|
+
: await this.broadcastEip712V2(txWithAddresses);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
const error = e;
|
|
121
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
throw new exceptions_1.TransactionException(new Error(error));
|
|
125
|
+
}
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Broadcasting the transaction using the feeDelegation
|
|
@@ -131,26 +131,28 @@ class MsgBroadcaster {
|
|
|
131
131
|
* @param tx
|
|
132
132
|
* @returns {string} transaction hash
|
|
133
133
|
*/
|
|
134
|
-
broadcastWithFeeDelegation(tx) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
134
|
+
async broadcastWithFeeDelegation(tx) {
|
|
135
|
+
const { walletStrategy } = this;
|
|
136
|
+
const txWithAddresses = {
|
|
137
|
+
...tx,
|
|
138
|
+
ethereumAddress: (0, wallet_base_1.getEthereumSignerAddress)(tx.injectiveAddress),
|
|
139
|
+
injectiveAddress: (0, wallet_base_1.getInjectiveSignerAddress)(tx.injectiveAddress),
|
|
140
|
+
};
|
|
141
|
+
if (sdk_ts_1.ofacWallets.includes(txWithAddresses.ethereumAddress)) {
|
|
142
|
+
throw new exceptions_1.GeneralException(new Error('You cannot execute this transaction'));
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
return (0, wallet_base_1.isCosmosWallet)(walletStrategy.wallet)
|
|
146
|
+
? await this.broadcastDirectSignWithFeeDelegation(txWithAddresses)
|
|
147
|
+
: await this.broadcastEip712WithFeeDelegation(txWithAddresses);
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
const error = e;
|
|
151
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
throw new exceptions_1.TransactionException(new Error(error));
|
|
155
|
+
}
|
|
154
156
|
}
|
|
155
157
|
/**
|
|
156
158
|
* Prepare/sign/broadcast transaction using
|
|
@@ -161,88 +163,85 @@ class MsgBroadcaster {
|
|
|
161
163
|
* @param tx The transaction that needs to be broadcasted
|
|
162
164
|
* @returns transaction hash
|
|
163
165
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const { stdFee: simulatedStdFee } = yield this.getTxWithSignersAndStdFee({
|
|
188
|
-
chainId,
|
|
189
|
-
signMode: sdk_ts_1.SIGN_EIP712,
|
|
190
|
-
memo: tx.memo,
|
|
191
|
-
message: msgs,
|
|
192
|
-
timeoutHeight: timeoutHeight.toNumber(),
|
|
193
|
-
signers: {
|
|
194
|
-
pubKey: baseAccount.pubKey.key,
|
|
195
|
-
accountNumber: baseAccount.accountNumber,
|
|
196
|
-
sequence: baseAccount.sequence,
|
|
197
|
-
},
|
|
198
|
-
fee: stdFee,
|
|
199
|
-
});
|
|
200
|
-
stdFee = simulatedStdFee;
|
|
201
|
-
}
|
|
202
|
-
/** EIP712 for signing on Ethereum wallets */
|
|
203
|
-
const eip712TypedData = (0, sdk_ts_1.getEip712TypedData)({
|
|
204
|
-
msgs,
|
|
205
|
-
fee: stdFee,
|
|
206
|
-
tx: {
|
|
207
|
-
memo: tx.memo,
|
|
208
|
-
accountNumber: baseAccount.accountNumber.toString(),
|
|
209
|
-
sequence: baseAccount.sequence.toString(),
|
|
210
|
-
timeoutHeight: timeoutHeight.toFixed(),
|
|
211
|
-
chainId,
|
|
212
|
-
},
|
|
213
|
-
ethereumChainId,
|
|
214
|
-
});
|
|
215
|
-
/** Signing on Ethereum */
|
|
216
|
-
const signature = yield walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress);
|
|
217
|
-
const pubKeyOrSignatureDerivedPubKey = getEthereumWalletPubKey({
|
|
218
|
-
pubKey: (_b = baseAccount.pubKey) === null || _b === void 0 ? void 0 : _b.key,
|
|
219
|
-
eip712TypedData,
|
|
220
|
-
signature,
|
|
221
|
-
});
|
|
222
|
-
/** Preparing the transaction for client broadcasting */
|
|
223
|
-
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
224
|
-
message: msgs,
|
|
225
|
-
memo: tx.memo,
|
|
166
|
+
async broadcastEip712(tx) {
|
|
167
|
+
const { chainId, txTimeout, endpoints, ethereumChainId, walletStrategy } = this;
|
|
168
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
169
|
+
if (!ethereumChainId) {
|
|
170
|
+
throw new exceptions_1.GeneralException(new Error('Please provide ethereumChainId'));
|
|
171
|
+
}
|
|
172
|
+
/** Account Details * */
|
|
173
|
+
const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
|
|
174
|
+
const { baseAccount } = accountDetails;
|
|
175
|
+
/** Block Details */
|
|
176
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
177
|
+
const latestHeight = latestBlock.header.height;
|
|
178
|
+
const timeoutHeight = new utils_1.BigNumberInBase(latestHeight).plus(txTimeout);
|
|
179
|
+
const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
|
|
180
|
+
let stdFee = (0, utils_1.getStdFee)({ ...tx.gas, gas });
|
|
181
|
+
/**
|
|
182
|
+
* Account has been created on chain
|
|
183
|
+
* and we can simulate the transaction
|
|
184
|
+
* to estimate the gas
|
|
185
|
+
**/
|
|
186
|
+
if (baseAccount.pubKey) {
|
|
187
|
+
const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
|
|
188
|
+
chainId,
|
|
226
189
|
signMode: sdk_ts_1.SIGN_EIP712,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
sequence: baseAccount.sequence,
|
|
190
|
+
memo: tx.memo,
|
|
191
|
+
message: msgs,
|
|
230
192
|
timeoutHeight: timeoutHeight.toNumber(),
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
193
|
+
signers: {
|
|
194
|
+
pubKey: baseAccount.pubKey.key,
|
|
195
|
+
accountNumber: baseAccount.accountNumber,
|
|
196
|
+
sequence: baseAccount.sequence,
|
|
197
|
+
},
|
|
198
|
+
fee: stdFee,
|
|
236
199
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
200
|
+
stdFee = simulatedStdFee;
|
|
201
|
+
}
|
|
202
|
+
/** EIP712 for signing on Ethereum wallets */
|
|
203
|
+
const eip712TypedData = (0, sdk_ts_1.getEip712TypedData)({
|
|
204
|
+
msgs,
|
|
205
|
+
fee: stdFee,
|
|
206
|
+
tx: {
|
|
207
|
+
memo: tx.memo,
|
|
208
|
+
accountNumber: baseAccount.accountNumber.toString(),
|
|
209
|
+
sequence: baseAccount.sequence.toString(),
|
|
210
|
+
timeoutHeight: timeoutHeight.toFixed(),
|
|
241
211
|
chainId,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
212
|
+
},
|
|
213
|
+
ethereumChainId,
|
|
214
|
+
});
|
|
215
|
+
/** Signing on Ethereum */
|
|
216
|
+
const signature = await walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress);
|
|
217
|
+
const pubKeyOrSignatureDerivedPubKey = getEthereumWalletPubKey({
|
|
218
|
+
pubKey: baseAccount.pubKey?.key,
|
|
219
|
+
eip712TypedData,
|
|
220
|
+
signature,
|
|
221
|
+
});
|
|
222
|
+
/** Preparing the transaction for client broadcasting */
|
|
223
|
+
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
224
|
+
message: msgs,
|
|
225
|
+
memo: tx.memo,
|
|
226
|
+
signMode: sdk_ts_1.SIGN_EIP712,
|
|
227
|
+
fee: stdFee,
|
|
228
|
+
pubKey: pubKeyOrSignatureDerivedPubKey,
|
|
229
|
+
sequence: baseAccount.sequence,
|
|
230
|
+
timeoutHeight: timeoutHeight.toNumber(),
|
|
231
|
+
accountNumber: baseAccount.accountNumber,
|
|
232
|
+
chainId,
|
|
233
|
+
});
|
|
234
|
+
const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
|
|
235
|
+
ethereumChainId,
|
|
236
|
+
});
|
|
237
|
+
const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
|
|
238
|
+
/** Append Signatures */
|
|
239
|
+
txRawEip712.signatures = [(0, sdk_ts_1.hexToBuff)(signature)];
|
|
240
|
+
return walletStrategy.sendTransaction(txRawEip712, {
|
|
241
|
+
chainId,
|
|
242
|
+
endpoints,
|
|
243
|
+
txTimeout,
|
|
244
|
+
address: tx.injectiveAddress,
|
|
246
245
|
});
|
|
247
246
|
}
|
|
248
247
|
/**
|
|
@@ -254,87 +253,84 @@ class MsgBroadcaster {
|
|
|
254
253
|
* @param tx The transaction that needs to be broadcasted
|
|
255
254
|
* @returns transaction hash
|
|
256
255
|
*/
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const { stdFee: simulatedStdFee } = yield this.getTxWithSignersAndStdFee({
|
|
281
|
-
chainId,
|
|
282
|
-
signMode: sdk_ts_1.SIGN_EIP712_V2,
|
|
283
|
-
memo: tx.memo,
|
|
284
|
-
message: msgs,
|
|
285
|
-
timeoutHeight: timeoutHeight.toNumber(),
|
|
286
|
-
signers: {
|
|
287
|
-
pubKey: baseAccount.pubKey.key,
|
|
288
|
-
accountNumber: baseAccount.accountNumber,
|
|
289
|
-
sequence: baseAccount.sequence,
|
|
290
|
-
},
|
|
291
|
-
fee: stdFee,
|
|
292
|
-
});
|
|
293
|
-
stdFee = simulatedStdFee;
|
|
294
|
-
}
|
|
295
|
-
/** EIP712 for signing on Ethereum wallets */
|
|
296
|
-
const eip712TypedData = (0, sdk_ts_1.getEip712TypedDataV2)({
|
|
297
|
-
msgs,
|
|
298
|
-
fee: stdFee,
|
|
299
|
-
tx: {
|
|
300
|
-
memo: tx.memo,
|
|
301
|
-
accountNumber: baseAccount.accountNumber.toString(),
|
|
302
|
-
sequence: baseAccount.sequence.toString(),
|
|
303
|
-
timeoutHeight: timeoutHeight.toFixed(),
|
|
304
|
-
chainId,
|
|
305
|
-
},
|
|
306
|
-
ethereumChainId,
|
|
307
|
-
});
|
|
308
|
-
/** Signing on Ethereum */
|
|
309
|
-
const signature = yield walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress);
|
|
310
|
-
const pubKeyOrSignatureDerivedPubKey = getEthereumWalletPubKey({
|
|
311
|
-
pubKey: (_b = baseAccount.pubKey) === null || _b === void 0 ? void 0 : _b.key,
|
|
312
|
-
eip712TypedData,
|
|
313
|
-
signature,
|
|
314
|
-
});
|
|
315
|
-
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
316
|
-
message: msgs,
|
|
317
|
-
memo: tx.memo,
|
|
256
|
+
async broadcastEip712V2(tx) {
|
|
257
|
+
const { walletStrategy, chainId, txTimeout, endpoints, ethereumChainId } = this;
|
|
258
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
259
|
+
if (!ethereumChainId) {
|
|
260
|
+
throw new exceptions_1.GeneralException(new Error('Please provide ethereumChainId'));
|
|
261
|
+
}
|
|
262
|
+
/** Account Details * */
|
|
263
|
+
const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
|
|
264
|
+
const { baseAccount } = accountDetails;
|
|
265
|
+
/** Block Details */
|
|
266
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
267
|
+
const latestHeight = latestBlock.header.height;
|
|
268
|
+
const timeoutHeight = new utils_1.BigNumberInBase(latestHeight).plus(txTimeout);
|
|
269
|
+
const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
|
|
270
|
+
let stdFee = (0, utils_1.getStdFee)({ ...tx.gas, gas });
|
|
271
|
+
/**
|
|
272
|
+
* Account has been created on chain
|
|
273
|
+
* and we can simulate the transaction
|
|
274
|
+
* to estimate the gas
|
|
275
|
+
**/
|
|
276
|
+
if (baseAccount.pubKey) {
|
|
277
|
+
const { stdFee: simulatedStdFee } = await this.getTxWithSignersAndStdFee({
|
|
278
|
+
chainId,
|
|
318
279
|
signMode: sdk_ts_1.SIGN_EIP712_V2,
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
sequence: baseAccount.sequence,
|
|
280
|
+
memo: tx.memo,
|
|
281
|
+
message: msgs,
|
|
322
282
|
timeoutHeight: timeoutHeight.toNumber(),
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
283
|
+
signers: {
|
|
284
|
+
pubKey: baseAccount.pubKey.key,
|
|
285
|
+
accountNumber: baseAccount.accountNumber,
|
|
286
|
+
sequence: baseAccount.sequence,
|
|
287
|
+
},
|
|
288
|
+
fee: stdFee,
|
|
328
289
|
});
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
290
|
+
stdFee = simulatedStdFee;
|
|
291
|
+
}
|
|
292
|
+
/** EIP712 for signing on Ethereum wallets */
|
|
293
|
+
const eip712TypedData = (0, sdk_ts_1.getEip712TypedDataV2)({
|
|
294
|
+
msgs,
|
|
295
|
+
fee: stdFee,
|
|
296
|
+
tx: {
|
|
297
|
+
memo: tx.memo,
|
|
298
|
+
accountNumber: baseAccount.accountNumber.toString(),
|
|
299
|
+
sequence: baseAccount.sequence.toString(),
|
|
300
|
+
timeoutHeight: timeoutHeight.toFixed(),
|
|
333
301
|
chainId,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
302
|
+
},
|
|
303
|
+
ethereumChainId,
|
|
304
|
+
});
|
|
305
|
+
/** Signing on Ethereum */
|
|
306
|
+
const signature = await walletStrategy.signEip712TypedData(JSON.stringify(eip712TypedData), tx.ethereumAddress);
|
|
307
|
+
const pubKeyOrSignatureDerivedPubKey = getEthereumWalletPubKey({
|
|
308
|
+
pubKey: baseAccount.pubKey?.key,
|
|
309
|
+
eip712TypedData,
|
|
310
|
+
signature,
|
|
311
|
+
});
|
|
312
|
+
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
313
|
+
message: msgs,
|
|
314
|
+
memo: tx.memo,
|
|
315
|
+
signMode: sdk_ts_1.SIGN_EIP712_V2,
|
|
316
|
+
fee: stdFee,
|
|
317
|
+
pubKey: pubKeyOrSignatureDerivedPubKey,
|
|
318
|
+
sequence: baseAccount.sequence,
|
|
319
|
+
timeoutHeight: timeoutHeight.toNumber(),
|
|
320
|
+
accountNumber: baseAccount.accountNumber,
|
|
321
|
+
chainId,
|
|
322
|
+
});
|
|
323
|
+
const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
|
|
324
|
+
ethereumChainId,
|
|
325
|
+
});
|
|
326
|
+
const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
|
|
327
|
+
/** Append Signatures */
|
|
328
|
+
txRawEip712.signatures = [(0, sdk_ts_1.hexToBuff)(signature)];
|
|
329
|
+
return walletStrategy.sendTransaction(txRawEip712, {
|
|
330
|
+
chainId,
|
|
331
|
+
endpoints,
|
|
332
|
+
txTimeout,
|
|
333
|
+
address: tx.injectiveAddress,
|
|
338
334
|
});
|
|
339
335
|
}
|
|
340
336
|
/**
|
|
@@ -344,70 +340,66 @@ class MsgBroadcaster {
|
|
|
344
340
|
* @param tx The transaction that needs to be broadcasted
|
|
345
341
|
* @returns transaction hash
|
|
346
342
|
*/
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
/** We only do it on the first account tx fail */
|
|
401
|
-
if (baseAccount.sequence > 1) {
|
|
402
|
-
throw e;
|
|
403
|
-
}
|
|
404
|
-
return yield this.broadcastWeb3WithFeeDelegation(tx);
|
|
343
|
+
async broadcastEip712WithFeeDelegation(tx) {
|
|
344
|
+
const { txTimeout, endpoints, simulateTx, walletStrategy, ethereumChainId, txTimeoutOnFeeDelegation, } = this;
|
|
345
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
346
|
+
const web3Msgs = msgs.map((msg) => msg.toWeb3());
|
|
347
|
+
if (!ethereumChainId) {
|
|
348
|
+
throw new exceptions_1.GeneralException(new Error('Please provide ethereumChainId'));
|
|
349
|
+
}
|
|
350
|
+
const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
|
|
351
|
+
let timeoutHeight = undefined;
|
|
352
|
+
if (txTimeoutOnFeeDelegation) {
|
|
353
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
354
|
+
const latestHeight = latestBlock.header.height;
|
|
355
|
+
timeoutHeight = new utils_1.BigNumberInBase(latestHeight)
|
|
356
|
+
.plus(txTimeout)
|
|
357
|
+
.toNumber();
|
|
358
|
+
}
|
|
359
|
+
const prepareTxResponse = await transactionApi.prepareTxRequest({
|
|
360
|
+
timeoutHeight,
|
|
361
|
+
memo: tx.memo,
|
|
362
|
+
message: web3Msgs,
|
|
363
|
+
address: tx.ethereumAddress,
|
|
364
|
+
chainId: ethereumChainId,
|
|
365
|
+
gasLimit: (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs),
|
|
366
|
+
estimateGas: simulateTx,
|
|
367
|
+
});
|
|
368
|
+
const signature = await walletStrategy.signEip712TypedData(prepareTxResponse.data, tx.ethereumAddress);
|
|
369
|
+
const broadcast = async () => await transactionApi.broadcastTxRequest({
|
|
370
|
+
signature,
|
|
371
|
+
message: web3Msgs,
|
|
372
|
+
txResponse: prepareTxResponse,
|
|
373
|
+
chainId: ethereumChainId,
|
|
374
|
+
});
|
|
375
|
+
try {
|
|
376
|
+
const response = await broadcast();
|
|
377
|
+
return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash);
|
|
378
|
+
}
|
|
379
|
+
catch (e) {
|
|
380
|
+
const error = e;
|
|
381
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
382
|
+
const exception = error;
|
|
383
|
+
/**
|
|
384
|
+
* First MsgExec transaction with a PrivateKey wallet
|
|
385
|
+
* always runs out of gas for some reason, temporary solution
|
|
386
|
+
* to just broadcast the transaction twice
|
|
387
|
+
**/
|
|
388
|
+
if (walletStrategy.wallet === wallet_base_1.Wallet.PrivateKey &&
|
|
389
|
+
(0, tx_js_1.checkIfTxRunOutOfGas)(exception)) {
|
|
390
|
+
/** Account Details * */
|
|
391
|
+
const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
|
|
392
|
+
const { baseAccount } = accountDetails;
|
|
393
|
+
/** We only do it on the first account tx fail */
|
|
394
|
+
if (baseAccount.sequence > 1) {
|
|
395
|
+
throw e;
|
|
405
396
|
}
|
|
406
|
-
return
|
|
397
|
+
return await this.broadcastEip712WithFeeDelegation(tx);
|
|
407
398
|
}
|
|
408
|
-
|
|
399
|
+
return await this.retryOnException(exception, broadcast);
|
|
409
400
|
}
|
|
410
|
-
|
|
401
|
+
throw e;
|
|
402
|
+
}
|
|
411
403
|
}
|
|
412
404
|
/**
|
|
413
405
|
* Prepare/sign/broadcast transaction using
|
|
@@ -416,78 +408,81 @@ class MsgBroadcaster {
|
|
|
416
408
|
* @param tx The transaction that needs to be broadcasted
|
|
417
409
|
* @returns transaction hash
|
|
418
410
|
*/
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
411
|
+
async broadcastDirectSign(tx) {
|
|
412
|
+
const { walletStrategy, txTimeout, endpoints, chainId } = this;
|
|
413
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
414
|
+
/**
|
|
415
|
+
* When using Ledger with Keplr/Leap we have
|
|
416
|
+
* to send EIP712 to sign on Keplr/Leap
|
|
417
|
+
*/
|
|
418
|
+
if ([wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.Leap].includes(walletStrategy.getWallet())) {
|
|
419
|
+
const walletDeviceType = await walletStrategy.getWalletDeviceType();
|
|
420
|
+
const isLedgerConnected = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
|
|
421
|
+
if (isLedgerConnected) {
|
|
422
|
+
return this.experimentalBroadcastWalletThroughLedger(tx);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/** Account Details * */
|
|
426
|
+
const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
|
|
427
|
+
const { baseAccount } = accountDetails;
|
|
428
|
+
/** Block Details */
|
|
429
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
430
|
+
const latestHeight = latestBlock.header.height;
|
|
431
|
+
const timeoutHeight = new utils_1.BigNumberInBase(latestHeight).plus(txTimeout);
|
|
432
|
+
const signMode = (0, wallet_base_1.isCosmosAminoOnlyWallet)(walletStrategy.wallet)
|
|
433
|
+
? sdk_ts_1.SIGN_EIP712
|
|
434
|
+
: sdk_ts_1.SIGN_DIRECT;
|
|
435
|
+
const pubKey = await walletStrategy.getPubKey(tx.injectiveAddress);
|
|
436
|
+
const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
|
|
437
|
+
/** Prepare the Transaction * */
|
|
438
|
+
const { txRaw } = await this.getTxWithSignersAndStdFee({
|
|
439
|
+
chainId,
|
|
440
|
+
signMode,
|
|
441
|
+
memo: tx.memo,
|
|
442
|
+
message: msgs,
|
|
443
|
+
timeoutHeight: timeoutHeight.toNumber(),
|
|
444
|
+
signers: {
|
|
445
|
+
pubKey,
|
|
446
|
+
accountNumber: baseAccount.accountNumber,
|
|
447
|
+
sequence: baseAccount.sequence,
|
|
448
|
+
},
|
|
449
|
+
fee: (0, utils_1.getStdFee)({ ...tx.gas, gas }),
|
|
450
|
+
});
|
|
451
|
+
/** Ledger using Cosmos app only allows signing amino docs */
|
|
452
|
+
if ((0, wallet_base_1.isCosmosAminoOnlyWallet)(walletStrategy.wallet)) {
|
|
453
|
+
const aminoSignDoc = (0, sdk_ts_1.getAminoStdSignDoc)({
|
|
454
|
+
...tx,
|
|
455
|
+
...baseAccount,
|
|
456
|
+
msgs,
|
|
449
457
|
chainId,
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
message: msgs,
|
|
453
|
-
timeoutHeight: timeoutHeight.toNumber(),
|
|
454
|
-
signers: {
|
|
455
|
-
pubKey,
|
|
456
|
-
accountNumber: baseAccount.accountNumber,
|
|
457
|
-
sequence: baseAccount.sequence,
|
|
458
|
-
},
|
|
459
|
-
fee: (0, utils_1.getStdFee)(Object.assign(Object.assign({}, tx.gas), { gas })),
|
|
458
|
+
gas: gas || tx.gas?.gas?.toString(),
|
|
459
|
+
timeoutHeight: timeoutHeight.toFixed(),
|
|
460
460
|
});
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const aminoSignDoc = (0, sdk_ts_1.getAminoStdSignDoc)(Object.assign(Object.assign(Object.assign({}, tx), baseAccount), { msgs,
|
|
464
|
-
chainId, gas: gas || ((_c = (_b = tx.gas) === null || _b === void 0 ? void 0 : _b.gas) === null || _c === void 0 ? void 0 : _c.toString()), timeoutHeight: timeoutHeight.toFixed() }));
|
|
465
|
-
const signResponse = yield walletStrategy.signAminoCosmosTransaction({
|
|
466
|
-
signDoc: aminoSignDoc,
|
|
467
|
-
address: tx.injectiveAddress,
|
|
468
|
-
});
|
|
469
|
-
txRaw.signatures = [
|
|
470
|
-
Buffer.from(signResponse.signature.signature, 'base64'),
|
|
471
|
-
];
|
|
472
|
-
return walletStrategy.sendTransaction(txRaw, {
|
|
473
|
-
chainId,
|
|
474
|
-
endpoints,
|
|
475
|
-
txTimeout,
|
|
476
|
-
address: tx.injectiveAddress,
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
const directSignResponse = (yield walletStrategy.signCosmosTransaction({
|
|
480
|
-
txRaw,
|
|
481
|
-
chainId,
|
|
461
|
+
const signResponse = await walletStrategy.signAminoCosmosTransaction({
|
|
462
|
+
signDoc: aminoSignDoc,
|
|
482
463
|
address: tx.injectiveAddress,
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
464
|
+
});
|
|
465
|
+
txRaw.signatures = [
|
|
466
|
+
Buffer.from(signResponse.signature.signature, 'base64'),
|
|
467
|
+
];
|
|
468
|
+
return walletStrategy.sendTransaction(txRaw, {
|
|
486
469
|
chainId,
|
|
487
470
|
endpoints,
|
|
488
471
|
txTimeout,
|
|
489
472
|
address: tx.injectiveAddress,
|
|
490
473
|
});
|
|
474
|
+
}
|
|
475
|
+
const directSignResponse = (await walletStrategy.signCosmosTransaction({
|
|
476
|
+
txRaw,
|
|
477
|
+
chainId,
|
|
478
|
+
address: tx.injectiveAddress,
|
|
479
|
+
accountNumber: baseAccount.accountNumber,
|
|
480
|
+
}));
|
|
481
|
+
return walletStrategy.sendTransaction(directSignResponse, {
|
|
482
|
+
chainId,
|
|
483
|
+
endpoints,
|
|
484
|
+
txTimeout,
|
|
485
|
+
address: tx.injectiveAddress,
|
|
491
486
|
});
|
|
492
487
|
}
|
|
493
488
|
/**
|
|
@@ -496,91 +491,94 @@ class MsgBroadcaster {
|
|
|
496
491
|
* Note: Gas estimation not available
|
|
497
492
|
* @param tx the transaction that needs to be broadcasted
|
|
498
493
|
*/
|
|
499
|
-
experimentalBroadcastWalletThroughLedger(tx) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
494
|
+
async experimentalBroadcastWalletThroughLedger(tx) {
|
|
495
|
+
const { chainId, txTimeout, endpoints, simulateTx, walletStrategy, ethereumChainId, } = this;
|
|
496
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
497
|
+
/**
|
|
498
|
+
* We can only use this method
|
|
499
|
+
* when Ledger is connected through Keplr
|
|
500
|
+
*/
|
|
501
|
+
if ([wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.Leap].includes(walletStrategy.getWallet())) {
|
|
502
|
+
const walletDeviceType = await walletStrategy.getWalletDeviceType();
|
|
503
|
+
const isLedgerConnected = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
|
|
504
|
+
if (!isLedgerConnected) {
|
|
505
|
+
throw new exceptions_1.GeneralException(new Error(`This method can only be used when Ledger is connected through ${walletStrategy.getWallet()}`));
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (!ethereumChainId) {
|
|
509
|
+
throw new exceptions_1.GeneralException(new Error('Please provide ethereumChainId'));
|
|
510
|
+
}
|
|
511
|
+
const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
|
|
512
|
+
/** Account Details * */
|
|
513
|
+
const accountDetails = await new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc).fetchAccount(tx.injectiveAddress);
|
|
514
|
+
const { baseAccount } = accountDetails;
|
|
515
|
+
/** Block Details */
|
|
516
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
517
|
+
const latestHeight = latestBlock.header.height;
|
|
518
|
+
const timeoutHeight = new utils_1.BigNumberInBase(latestHeight).plus(txTimeout);
|
|
519
|
+
const pubKey = await walletStrategy.getPubKey();
|
|
520
|
+
const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
|
|
521
|
+
/** EIP712 for signing on Ethereum wallets */
|
|
522
|
+
const eip712TypedData = (0, sdk_ts_1.getEip712TypedData)({
|
|
523
|
+
msgs,
|
|
524
|
+
fee: (0, utils_1.getStdFee)({ ...tx.gas, gas }),
|
|
525
|
+
tx: {
|
|
526
|
+
memo: tx.memo,
|
|
527
|
+
accountNumber: baseAccount.accountNumber.toString(),
|
|
528
|
+
sequence: baseAccount.sequence.toString(),
|
|
529
|
+
timeoutHeight: timeoutHeight.toFixed(),
|
|
530
|
+
chainId,
|
|
531
|
+
},
|
|
532
|
+
ethereumChainId,
|
|
533
|
+
});
|
|
534
|
+
const aminoSignResponse = await cosmosWallet.signEIP712CosmosTx({
|
|
535
|
+
eip712: eip712TypedData,
|
|
536
|
+
signDoc: (0, wallet_base_1.createEip712StdSignDoc)({
|
|
537
|
+
...tx,
|
|
538
|
+
...baseAccount,
|
|
530
539
|
msgs,
|
|
531
|
-
fee: (0, utils_1.getStdFee)(Object.assign(Object.assign({}, tx.gas), { gas })),
|
|
532
|
-
tx: {
|
|
533
|
-
memo: tx.memo,
|
|
534
|
-
accountNumber: baseAccount.accountNumber.toString(),
|
|
535
|
-
sequence: baseAccount.sequence.toString(),
|
|
536
|
-
timeoutHeight: timeoutHeight.toFixed(),
|
|
537
|
-
chainId,
|
|
538
|
-
},
|
|
539
|
-
ethereumChainId,
|
|
540
|
-
});
|
|
541
|
-
const aminoSignResponse = yield cosmosWallet.signEIP712CosmosTx({
|
|
542
|
-
eip712: eip712TypedData,
|
|
543
|
-
signDoc: (0, wallet_base_1.createEip712StdSignDoc)(Object.assign(Object.assign(Object.assign({}, tx), baseAccount), { msgs,
|
|
544
|
-
chainId, gas: gas || ((_c = (_b = tx.gas) === null || _b === void 0 ? void 0 : _b.gas) === null || _c === void 0 ? void 0 : _c.toString()), timeoutHeight: timeoutHeight.toFixed() })),
|
|
545
|
-
});
|
|
546
|
-
/**
|
|
547
|
-
* Create TxRaw from the signed tx that we
|
|
548
|
-
* get as a response in case the user changed the fee/memo
|
|
549
|
-
* on the Keplr popup
|
|
550
|
-
*/
|
|
551
|
-
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
552
|
-
pubKey,
|
|
553
|
-
message: msgs,
|
|
554
|
-
memo: aminoSignResponse.signed.memo,
|
|
555
|
-
signMode: sdk_ts_1.SIGN_EIP712,
|
|
556
|
-
fee: aminoSignResponse.signed.fee,
|
|
557
|
-
sequence: parseInt(aminoSignResponse.signed.sequence, 10),
|
|
558
|
-
timeoutHeight: parseInt(aminoSignResponse.signed.timeout_height, 10),
|
|
559
|
-
accountNumber: parseInt(aminoSignResponse.signed.account_number, 10),
|
|
560
540
|
chainId,
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
541
|
+
gas: gas || tx.gas?.gas?.toString(),
|
|
542
|
+
timeoutHeight: timeoutHeight.toFixed(),
|
|
543
|
+
}),
|
|
544
|
+
});
|
|
545
|
+
/**
|
|
546
|
+
* Create TxRaw from the signed tx that we
|
|
547
|
+
* get as a response in case the user changed the fee/memo
|
|
548
|
+
* on the Keplr popup
|
|
549
|
+
*/
|
|
550
|
+
const { txRaw } = (0, sdk_ts_1.createTransaction)({
|
|
551
|
+
pubKey,
|
|
552
|
+
message: msgs,
|
|
553
|
+
memo: aminoSignResponse.signed.memo,
|
|
554
|
+
signMode: sdk_ts_1.SIGN_EIP712,
|
|
555
|
+
fee: aminoSignResponse.signed.fee,
|
|
556
|
+
sequence: parseInt(aminoSignResponse.signed.sequence, 10),
|
|
557
|
+
timeoutHeight: parseInt(aminoSignResponse.signed.timeout_height, 10),
|
|
558
|
+
accountNumber: parseInt(aminoSignResponse.signed.account_number, 10),
|
|
559
|
+
chainId,
|
|
560
|
+
});
|
|
561
|
+
/** Preparing the transaction for client broadcasting */
|
|
562
|
+
const web3Extension = (0, sdk_ts_1.createWeb3Extension)({
|
|
563
|
+
ethereumChainId,
|
|
583
564
|
});
|
|
565
|
+
const txRawEip712 = (0, sdk_ts_1.createTxRawEIP712)(txRaw, web3Extension);
|
|
566
|
+
if (simulateTx) {
|
|
567
|
+
await this.simulateTxRaw(txRawEip712);
|
|
568
|
+
}
|
|
569
|
+
/** Append Signatures */
|
|
570
|
+
const signatureBuff = Buffer.from(aminoSignResponse.signature.signature, 'base64');
|
|
571
|
+
txRawEip712.signatures = [signatureBuff];
|
|
572
|
+
/** Broadcast the transaction */
|
|
573
|
+
const response = await new sdk_ts_1.TxGrpcApi(endpoints.grpc).broadcast(txRawEip712, { txTimeout });
|
|
574
|
+
if (response.code !== 0) {
|
|
575
|
+
throw new exceptions_1.TransactionException(new Error(response.rawLog), {
|
|
576
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
577
|
+
contextCode: response.code,
|
|
578
|
+
contextModule: response.codespace,
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
return response;
|
|
584
582
|
}
|
|
585
583
|
/**
|
|
586
584
|
* Prepare/sign/broadcast transaction using
|
|
@@ -589,121 +587,114 @@ class MsgBroadcaster {
|
|
|
589
587
|
* @param tx The transaction that needs to be broadcasted
|
|
590
588
|
* @returns transaction hash
|
|
591
589
|
*/
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
value: pubKey,
|
|
663
|
-
type: '/injective.crypto.v1beta1.ethsecp256k1.PubKey',
|
|
664
|
-
},
|
|
665
|
-
});
|
|
666
|
-
});
|
|
667
|
-
try {
|
|
668
|
-
const response = yield broadcast();
|
|
669
|
-
// Re-enable tx gas check removed above
|
|
670
|
-
if (canDisableCosmosGasCheck && cosmosWallet.enableGasCheck) {
|
|
671
|
-
cosmosWallet.enableGasCheck(chainId);
|
|
672
|
-
}
|
|
673
|
-
return yield new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash);
|
|
674
|
-
}
|
|
675
|
-
catch (e) {
|
|
676
|
-
const error = e;
|
|
677
|
-
if ((0, exceptions_1.isThrownException)(error)) {
|
|
678
|
-
const exception = error;
|
|
679
|
-
return yield this.retryOnException(exception, broadcast);
|
|
680
|
-
}
|
|
681
|
-
throw e;
|
|
682
|
-
}
|
|
590
|
+
async broadcastDirectSignWithFeeDelegation(tx) {
|
|
591
|
+
const { options, chainId, txTimeout, endpoints, walletStrategy, txTimeoutOnFeeDelegation, } = this;
|
|
592
|
+
const msgs = Array.isArray(tx.msgs) ? tx.msgs : [tx.msgs];
|
|
593
|
+
/**
|
|
594
|
+
* We can only use this method when Keplr is connected
|
|
595
|
+
* with ledger
|
|
596
|
+
*/
|
|
597
|
+
if (walletStrategy.getWallet() === wallet_base_1.Wallet.Keplr) {
|
|
598
|
+
const walletDeviceType = await walletStrategy.getWalletDeviceType();
|
|
599
|
+
const isLedgerConnectedOnKeplr = walletDeviceType === wallet_base_1.WalletDeviceType.Hardware;
|
|
600
|
+
if (isLedgerConnectedOnKeplr) {
|
|
601
|
+
throw new exceptions_1.GeneralException(new Error('Keplr + Ledger is not available with fee delegation. Connect with Ledger directly.'));
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
const cosmosWallet = walletStrategy.getCosmosWallet(chainId);
|
|
605
|
+
const canDisableCosmosGasCheck = [wallet_base_1.Wallet.Keplr, wallet_base_1.Wallet.OWallet].includes(walletStrategy.wallet);
|
|
606
|
+
const feePayerPubKey = await this.fetchFeePayerPubKey(options.feePayerPubKey);
|
|
607
|
+
const feePayerPublicKey = sdk_ts_1.PublicKey.fromBase64(feePayerPubKey);
|
|
608
|
+
const feePayer = feePayerPublicKey.toAddress().address;
|
|
609
|
+
/** Account Details * */
|
|
610
|
+
const chainGrpcAuthApi = new sdk_ts_1.ChainGrpcAuthApi(endpoints.grpc);
|
|
611
|
+
const accountDetails = await chainGrpcAuthApi.fetchAccount(tx.injectiveAddress);
|
|
612
|
+
const feePayerAccountDetails = await chainGrpcAuthApi.fetchAccount(feePayer);
|
|
613
|
+
const { baseAccount } = accountDetails;
|
|
614
|
+
const { baseAccount: feePayerBaseAccount } = feePayerAccountDetails;
|
|
615
|
+
/** Block Details */
|
|
616
|
+
const latestBlock = await new sdk_ts_1.ChainGrpcTendermintApi(endpoints.grpc).fetchLatestBlock();
|
|
617
|
+
const latestHeight = latestBlock.header.height;
|
|
618
|
+
const timeoutHeight = new utils_1.BigNumberInBase(latestHeight).plus(txTimeoutOnFeeDelegation ? txTimeout : utils_1.DEFAULT_BLOCK_TIMEOUT_HEIGHT);
|
|
619
|
+
const pubKey = await walletStrategy.getPubKey();
|
|
620
|
+
const gas = (tx.gas?.gas || (0, sdk_ts_1.getGasPriceBasedOnMessage)(msgs)).toString();
|
|
621
|
+
/** Prepare the Transaction * */
|
|
622
|
+
const { txRaw } = await this.getTxWithSignersAndStdFee({
|
|
623
|
+
chainId,
|
|
624
|
+
memo: tx.memo,
|
|
625
|
+
message: msgs,
|
|
626
|
+
timeoutHeight: timeoutHeight.toNumber(),
|
|
627
|
+
signers: [
|
|
628
|
+
{
|
|
629
|
+
pubKey,
|
|
630
|
+
accountNumber: baseAccount.accountNumber,
|
|
631
|
+
sequence: baseAccount.sequence,
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
pubKey: feePayerPublicKey.toBase64(),
|
|
635
|
+
accountNumber: feePayerBaseAccount.accountNumber,
|
|
636
|
+
sequence: feePayerBaseAccount.sequence,
|
|
637
|
+
},
|
|
638
|
+
],
|
|
639
|
+
fee: (0, utils_1.getStdFee)({ ...tx.gas, gas, payer: feePayer }),
|
|
640
|
+
});
|
|
641
|
+
// Temporary remove tx gas check because Keplr doesn't recognize feePayer
|
|
642
|
+
if (canDisableCosmosGasCheck && cosmosWallet.disableGasCheck) {
|
|
643
|
+
cosmosWallet.disableGasCheck(chainId);
|
|
644
|
+
}
|
|
645
|
+
const directSignResponse = (await walletStrategy.signCosmosTransaction({
|
|
646
|
+
txRaw,
|
|
647
|
+
chainId,
|
|
648
|
+
address: tx.injectiveAddress,
|
|
649
|
+
accountNumber: baseAccount.accountNumber,
|
|
650
|
+
}));
|
|
651
|
+
const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
|
|
652
|
+
const broadcast = async () => await transactionApi.broadcastCosmosTxRequest({
|
|
653
|
+
address: tx.injectiveAddress,
|
|
654
|
+
txRaw: (0, sdk_ts_1.createTxRawFromSigResponse)(directSignResponse),
|
|
655
|
+
signature: directSignResponse.signature.signature,
|
|
656
|
+
pubKey: directSignResponse.signature.pub_key || {
|
|
657
|
+
value: pubKey,
|
|
658
|
+
type: '/injective.crypto.v1beta1.ethsecp256k1.PubKey',
|
|
659
|
+
},
|
|
683
660
|
});
|
|
661
|
+
try {
|
|
662
|
+
const response = await broadcast();
|
|
663
|
+
// Re-enable tx gas check removed above
|
|
664
|
+
if (canDisableCosmosGasCheck && cosmosWallet.enableGasCheck) {
|
|
665
|
+
cosmosWallet.enableGasCheck(chainId);
|
|
666
|
+
}
|
|
667
|
+
return await new sdk_ts_1.TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash);
|
|
668
|
+
}
|
|
669
|
+
catch (e) {
|
|
670
|
+
const error = e;
|
|
671
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
672
|
+
const exception = error;
|
|
673
|
+
return await this.retryOnException(exception, broadcast);
|
|
674
|
+
}
|
|
675
|
+
throw e;
|
|
676
|
+
}
|
|
684
677
|
}
|
|
685
678
|
/**
|
|
686
679
|
* Fetch the fee payer's pub key from the web3 gateway
|
|
687
680
|
*
|
|
688
681
|
* Returns a base64 version of it
|
|
689
682
|
*/
|
|
690
|
-
fetchFeePayerPubKey(existingFeePayerPubKey) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
return response.feePayerPubKey.key;
|
|
706
|
-
});
|
|
683
|
+
async fetchFeePayerPubKey(existingFeePayerPubKey) {
|
|
684
|
+
if (existingFeePayerPubKey) {
|
|
685
|
+
return existingFeePayerPubKey;
|
|
686
|
+
}
|
|
687
|
+
const { endpoints } = this;
|
|
688
|
+
const transactionApi = new sdk_ts_1.IndexerGrpcWeb3GwApi(endpoints.web3gw || endpoints.indexer);
|
|
689
|
+
const response = await transactionApi.fetchFeePayer();
|
|
690
|
+
if (!response.feePayerPubKey) {
|
|
691
|
+
throw new exceptions_1.GeneralException(new Error('Please provide a feePayerPubKey'));
|
|
692
|
+
}
|
|
693
|
+
if (response.feePayerPubKey.key.startsWith('0x') ||
|
|
694
|
+
response.feePayerPubKey.key.length === 66) {
|
|
695
|
+
return Buffer.from(response.feePayerPubKey.key, 'hex').toString('base64');
|
|
696
|
+
}
|
|
697
|
+
return response.feePayerPubKey.key;
|
|
707
698
|
}
|
|
708
699
|
/**
|
|
709
700
|
* In case we don't want to simulate the transaction
|
|
@@ -713,71 +704,79 @@ class MsgBroadcaster {
|
|
|
713
704
|
* gas limit based on the simulation and add a small multiplier
|
|
714
705
|
* to be safe (factor of 1.2 as default)
|
|
715
706
|
*/
|
|
716
|
-
getTxWithSignersAndStdFee(args) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
707
|
+
async getTxWithSignersAndStdFee(args) {
|
|
708
|
+
const { simulateTx } = this;
|
|
709
|
+
if (!simulateTx) {
|
|
710
|
+
return {
|
|
711
|
+
...(0, sdk_ts_1.createTransactionWithSigners)(args),
|
|
712
|
+
stdFee: (0, utils_1.getStdFee)(args.fee),
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
const result = await this.simulateTxWithSigners(args);
|
|
716
|
+
if (!result.gasInfo?.gasUsed) {
|
|
717
|
+
return {
|
|
718
|
+
...(0, sdk_ts_1.createTransactionWithSigners)(args),
|
|
719
|
+
stdFee: (0, utils_1.getStdFee)(args.fee),
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
const stdGasFee = {
|
|
723
|
+
...(0, utils_1.getStdFee)({
|
|
724
|
+
...(0, utils_1.getStdFee)(args.fee),
|
|
725
|
+
gas: new utils_1.BigNumberInBase(result.gasInfo.gasUsed)
|
|
728
726
|
.times(this.gasBufferCoefficient)
|
|
729
|
-
.toFixed()
|
|
730
|
-
|
|
731
|
-
}
|
|
727
|
+
.toFixed(),
|
|
728
|
+
}),
|
|
729
|
+
};
|
|
730
|
+
return {
|
|
731
|
+
...(0, sdk_ts_1.createTransactionWithSigners)({
|
|
732
|
+
...args,
|
|
733
|
+
fee: stdGasFee,
|
|
734
|
+
}),
|
|
735
|
+
stdFee: stdGasFee,
|
|
736
|
+
};
|
|
732
737
|
}
|
|
733
738
|
/**
|
|
734
739
|
* Create TxRaw and simulate it
|
|
735
740
|
*/
|
|
736
|
-
simulateTxRaw(txRaw) {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
return simulationResponse;
|
|
742
|
-
});
|
|
741
|
+
async simulateTxRaw(txRaw) {
|
|
742
|
+
const { endpoints } = this;
|
|
743
|
+
txRaw.signatures = [new Uint8Array(0)];
|
|
744
|
+
const simulationResponse = await new sdk_ts_1.TxGrpcApi(endpoints.grpc).simulate(txRaw);
|
|
745
|
+
return simulationResponse;
|
|
743
746
|
}
|
|
744
747
|
/**
|
|
745
748
|
* Create TxRaw and simulate it
|
|
746
749
|
*/
|
|
747
|
-
simulateTxWithSigners(args) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
return simulationResponse;
|
|
754
|
-
});
|
|
750
|
+
async simulateTxWithSigners(args) {
|
|
751
|
+
const { endpoints } = this;
|
|
752
|
+
const { txRaw } = (0, sdk_ts_1.createTransactionWithSigners)(args);
|
|
753
|
+
txRaw.signatures = Array(Array.isArray(args.signers) ? args.signers.length : 1).fill(new Uint8Array(0));
|
|
754
|
+
const simulationResponse = await new sdk_ts_1.TxGrpcApi(endpoints.grpc).simulate(txRaw);
|
|
755
|
+
return simulationResponse;
|
|
755
756
|
}
|
|
756
|
-
retryOnException(exception, retryLogic) {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
});
|
|
757
|
+
async retryOnException(exception, retryLogic) {
|
|
758
|
+
const errorsToRetry = Object.keys(this.retriesOnError);
|
|
759
|
+
const errorKey = `${exception.contextModule}-${exception.contextCode}`;
|
|
760
|
+
if (!errorsToRetry.includes(errorKey)) {
|
|
761
|
+
throw exception;
|
|
762
|
+
}
|
|
763
|
+
const retryConfig = this.retriesOnError[errorKey];
|
|
764
|
+
if (retryConfig.retries >= retryConfig.maxRetries) {
|
|
765
|
+
this.retriesOnError = defaultRetriesConfig();
|
|
766
|
+
throw exception;
|
|
767
|
+
}
|
|
768
|
+
await (0, utils_1.sleep)(retryConfig.timeout);
|
|
769
|
+
try {
|
|
770
|
+
retryConfig.retries += 1;
|
|
771
|
+
return await retryLogic();
|
|
772
|
+
}
|
|
773
|
+
catch (e) {
|
|
774
|
+
const error = e;
|
|
775
|
+
if ((0, exceptions_1.isThrownException)(error)) {
|
|
776
|
+
return this.retryOnException(error, retryLogic);
|
|
777
|
+
}
|
|
778
|
+
throw e;
|
|
779
|
+
}
|
|
781
780
|
}
|
|
782
781
|
}
|
|
783
782
|
exports.MsgBroadcaster = MsgBroadcaster;
|