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