@keplr-wallet/background 0.13.13 → 0.13.15-rc.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/build/chains/convert.d.ts +7 -0
- package/build/chains/convert.js +109 -0
- package/build/chains/convert.js.map +1 -0
- package/build/chains/handler.js +1 -1
- package/build/chains/handler.js.map +1 -1
- package/build/chains/index.d.ts +1 -0
- package/build/chains/index.js +1 -0
- package/build/chains/index.js.map +1 -1
- package/build/chains/messages.d.ts +1 -1
- package/build/chains/service.d.ts +3 -9
- package/build/chains/service.js +45 -79
- package/build/chains/service.js.map +1 -1
- package/build/chains-ui/service.d.ts +2 -2
- package/build/chains-ui/service.js +5 -6
- package/build/chains-ui/service.js.map +1 -1
- package/build/chains-update/service.js +2 -2
- package/build/chains-update/service.js.map +1 -1
- package/build/keyring/handler.js +21 -15
- package/build/keyring/handler.js.map +1 -1
- package/build/keyring/service.d.ts +0 -1
- package/build/keyring/service.js +103 -78
- package/build/keyring/service.js.map +1 -1
- package/build/keyring-bitcoin/service.js +2 -2
- package/build/keyring-bitcoin/service.js.map +1 -1
- package/build/keyring-cosmos/service.js +31 -18
- package/build/keyring-cosmos/service.js.map +1 -1
- package/build/keyring-ethereum/service.js +19 -19
- package/build/keyring-ethereum/service.js.map +1 -1
- package/build/keyring-ledger/service.js +8 -7
- package/build/keyring-ledger/service.js.map +1 -1
- package/build/keyring-starknet/service.js +7 -7
- package/build/keyring-starknet/service.js.map +1 -1
- package/build/manage-view-asset-token/service.d.ts +1 -2
- package/build/manage-view-asset-token/service.js +2 -2
- package/build/manage-view-asset-token/service.js.map +1 -1
- package/build/permission/service.d.ts +1 -2
- package/build/permission/service.js +2 -2
- package/build/permission/service.js.map +1 -1
- package/build/recent-send-history/service.d.ts +4 -4
- package/build/recent-send-history/service.js +101 -73
- package/build/recent-send-history/service.js.map +1 -1
- package/build/secret-wasm/service.d.ts +3 -3
- package/build/secret-wasm/service.js +29 -29
- package/build/secret-wasm/service.js.map +1 -1
- package/build/token-cw20/service.d.ts +6 -6
- package/build/token-cw20/service.js +28 -21
- package/build/token-cw20/service.js.map +1 -1
- package/build/token-erc20/service.d.ts +2 -3
- package/build/token-erc20/service.js +10 -15
- package/build/token-erc20/service.js.map +1 -1
- package/build/token-scan/service.js +27 -23
- package/build/token-scan/service.js.map +1 -1
- package/build/tx/service.d.ts +1 -0
- package/build/tx/service.js +41 -10
- package/build/tx/service.js.map +1 -1
- package/build/tx-ethereum/service.js +5 -9
- package/build/tx-ethereum/service.js.map +1 -1
- package/build/tx-executor/service.js +2 -7
- package/build/tx-executor/service.js.map +1 -1
- package/build/tx-executor/types.d.ts +7 -1
- package/build/tx-executor/types.js.map +1 -1
- package/build/tx-executor/utils/evm.d.ts +2 -2
- package/build/tx-executor/utils/evm.js +75 -26
- package/build/tx-executor/utils/evm.js.map +1 -1
- package/package.json +13 -13
- package/src/chains/convert.ts +126 -0
- package/src/chains/handler.ts +1 -1
- package/src/chains/index.ts +1 -0
- package/src/chains/messages.ts +1 -1
- package/src/chains/service.ts +64 -97
- package/src/chains-ui/service.ts +8 -7
- package/src/chains-update/service.ts +2 -2
- package/src/keyring/handler.ts +34 -19
- package/src/keyring/service.ts +137 -96
- package/src/keyring-bitcoin/service.ts +2 -2
- package/src/keyring-cosmos/service.ts +46 -18
- package/src/keyring-ethereum/service.ts +24 -17
- package/src/keyring-ledger/service.ts +10 -10
- package/src/keyring-starknet/service.ts +7 -7
- package/src/manage-view-asset-token/service.ts +2 -3
- package/src/permission/service.ts +3 -7
- package/src/recent-send-history/service.ts +141 -95
- package/src/secret-wasm/service.ts +39 -45
- package/src/token-cw20/service.ts +36 -30
- package/src/token-erc20/service.ts +15 -18
- package/src/token-scan/service.ts +34 -21
- package/src/tx/service.ts +60 -12
- package/src/tx-ethereum/service.ts +8 -8
- package/src/tx-executor/service.ts +4 -6
- package/src/tx-executor/types.ts +9 -1
- package/src/tx-executor/utils/evm.ts +92 -32
- package/tsconfig.check.json +2 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Env, KeplrError } from "@keplr-wallet/router";
|
|
2
2
|
import {
|
|
3
3
|
AppCurrency,
|
|
4
|
-
ChainInfo,
|
|
5
4
|
CW20Currency,
|
|
6
5
|
Secret20Currency,
|
|
7
6
|
} from "@keplr-wallet/types";
|
|
@@ -125,8 +124,8 @@ export class TokenCW20Service {
|
|
|
125
124
|
this.chainsService.addChainRemovedHandler(this.onChainRemoved);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
protected readonly onChainRemoved = (
|
|
129
|
-
const chainIdentifier = ChainIdHelper.parse(
|
|
127
|
+
protected readonly onChainRemoved = (chainId: string) => {
|
|
128
|
+
const chainIdentifier = ChainIdHelper.parse(chainId).identifier;
|
|
130
129
|
runInAction(() => {
|
|
131
130
|
this.tokenMap.delete(chainIdentifier);
|
|
132
131
|
});
|
|
@@ -194,14 +193,8 @@ export class TokenCW20Service {
|
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
|
|
197
|
-
protected
|
|
198
|
-
if (
|
|
199
|
-
!chainInfo.features ||
|
|
200
|
-
!(
|
|
201
|
-
chainInfo.features.includes("cosmwasm") ||
|
|
202
|
-
chainInfo.features.includes("secretwasm")
|
|
203
|
-
)
|
|
204
|
-
) {
|
|
196
|
+
protected validateCosmosFeatures(features: string[] | undefined) {
|
|
197
|
+
if (!features?.includes("cosmwasm") && !features?.includes("secretwasm")) {
|
|
205
198
|
throw new Error("The chain doesn't support cosmwasm");
|
|
206
199
|
}
|
|
207
200
|
}
|
|
@@ -215,8 +208,16 @@ export class TokenCW20Service {
|
|
|
215
208
|
viewingKey?: string
|
|
216
209
|
) {
|
|
217
210
|
this.validateAssociatedAccountAddress(associatedAccountAddress);
|
|
218
|
-
const
|
|
219
|
-
|
|
211
|
+
const modularChainInfo =
|
|
212
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
213
|
+
if (
|
|
214
|
+
modularChainInfo.type !== "cosmos" &&
|
|
215
|
+
modularChainInfo.type !== "ethermint"
|
|
216
|
+
) {
|
|
217
|
+
throw new Error("The chain doesn't support cosmwasm");
|
|
218
|
+
}
|
|
219
|
+
const cosmosInfo = modularChainInfo.cosmos;
|
|
220
|
+
this.validateCosmosFeatures(cosmosInfo.features);
|
|
220
221
|
|
|
221
222
|
const existing = this.getToken(
|
|
222
223
|
chainId,
|
|
@@ -251,7 +252,7 @@ export class TokenCW20Service {
|
|
|
251
252
|
// Validate the contract address.
|
|
252
253
|
Bech32Address.validate(
|
|
253
254
|
contractAddress,
|
|
254
|
-
|
|
255
|
+
cosmosInfo.bech32Config?.bech32PrefixAccAddr
|
|
255
256
|
);
|
|
256
257
|
|
|
257
258
|
const params = {
|
|
@@ -305,8 +306,16 @@ export class TokenCW20Service {
|
|
|
305
306
|
associatedAccountAddress: string
|
|
306
307
|
): Promise<void> {
|
|
307
308
|
this.validateAssociatedAccountAddress(associatedAccountAddress);
|
|
308
|
-
const
|
|
309
|
-
|
|
309
|
+
const modularChainInfo =
|
|
310
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
311
|
+
if (
|
|
312
|
+
modularChainInfo.type !== "cosmos" &&
|
|
313
|
+
modularChainInfo.type !== "ethermint"
|
|
314
|
+
) {
|
|
315
|
+
throw new Error("The chain doesn't support cosmwasm");
|
|
316
|
+
}
|
|
317
|
+
const cosmosInfo = modularChainInfo.cosmos;
|
|
318
|
+
this.validateCosmosFeatures(cosmosInfo.features);
|
|
310
319
|
const chainIdentifier = ChainIdHelper.parse(chainId).identifier;
|
|
311
320
|
|
|
312
321
|
if (!this.tokenMap.has(chainIdentifier)) {
|
|
@@ -317,7 +326,10 @@ export class TokenCW20Service {
|
|
|
317
326
|
|
|
318
327
|
const tokens = this.tokenMap.get(chainIdentifier)!;
|
|
319
328
|
|
|
320
|
-
currency = await TokenCW20Service.validateCurrency(
|
|
329
|
+
currency = await TokenCW20Service.validateCurrency(
|
|
330
|
+
cosmosInfo.bech32Config?.bech32PrefixAccAddr,
|
|
331
|
+
currency
|
|
332
|
+
);
|
|
321
333
|
|
|
322
334
|
if (
|
|
323
335
|
!("type" in currency) ||
|
|
@@ -422,7 +434,7 @@ export class TokenCW20Service {
|
|
|
422
434
|
}
|
|
423
435
|
|
|
424
436
|
static async validateCurrency(
|
|
425
|
-
|
|
437
|
+
bech32Prefix: string | undefined,
|
|
426
438
|
currency: AppCurrency
|
|
427
439
|
): Promise<AppCurrency> {
|
|
428
440
|
// Validate the schema.
|
|
@@ -430,13 +442,13 @@ export class TokenCW20Service {
|
|
|
430
442
|
switch (currency.type) {
|
|
431
443
|
case "cw20":
|
|
432
444
|
currency = await TokenCW20Service.validateCW20Currency(
|
|
433
|
-
|
|
445
|
+
bech32Prefix,
|
|
434
446
|
currency
|
|
435
447
|
);
|
|
436
448
|
break;
|
|
437
449
|
case "secret20":
|
|
438
450
|
currency = await TokenCW20Service.validateSecret20Currency(
|
|
439
|
-
|
|
451
|
+
bech32Prefix,
|
|
440
452
|
currency
|
|
441
453
|
);
|
|
442
454
|
break;
|
|
@@ -451,33 +463,27 @@ export class TokenCW20Service {
|
|
|
451
463
|
}
|
|
452
464
|
|
|
453
465
|
static async validateCW20Currency(
|
|
454
|
-
|
|
466
|
+
bech32Prefix: string | undefined,
|
|
455
467
|
currency: CW20Currency
|
|
456
468
|
): Promise<CW20Currency> {
|
|
457
469
|
// Validate the schema.
|
|
458
470
|
currency = await CW20CurrencySchema.validateAsync(currency);
|
|
459
471
|
|
|
460
472
|
// Validate the contract address.
|
|
461
|
-
Bech32Address.validate(
|
|
462
|
-
currency.contractAddress,
|
|
463
|
-
chainInfo.bech32Config?.bech32PrefixAccAddr
|
|
464
|
-
);
|
|
473
|
+
Bech32Address.validate(currency.contractAddress, bech32Prefix);
|
|
465
474
|
|
|
466
475
|
return currency;
|
|
467
476
|
}
|
|
468
477
|
|
|
469
478
|
static async validateSecret20Currency(
|
|
470
|
-
|
|
479
|
+
bech32Prefix: string | undefined,
|
|
471
480
|
currency: Secret20Currency
|
|
472
481
|
): Promise<Secret20Currency> {
|
|
473
482
|
// Validate the schema.
|
|
474
483
|
currency = await Secret20CurrencySchema.validateAsync(currency);
|
|
475
484
|
|
|
476
485
|
// Validate the contract address.
|
|
477
|
-
Bech32Address.validate(
|
|
478
|
-
currency.contractAddress,
|
|
479
|
-
chainInfo.bech32Config?.bech32PrefixAccAddr
|
|
480
|
-
);
|
|
486
|
+
Bech32Address.validate(currency.contractAddress, bech32Prefix);
|
|
481
487
|
|
|
482
488
|
return currency;
|
|
483
489
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Env, KeplrError } from "@keplr-wallet/router";
|
|
2
|
-
import { AppCurrency,
|
|
2
|
+
import { AppCurrency, ERC20Currency } from "@keplr-wallet/types";
|
|
3
3
|
import { ERC20CurrencySchema } from "@keplr-wallet/chain-validator";
|
|
4
4
|
import { ChainIdHelper } from "@keplr-wallet/cosmos";
|
|
5
5
|
import { ChainsService } from "../chains";
|
|
@@ -50,8 +50,8 @@ export class TokenERC20Service {
|
|
|
50
50
|
this.chainsService.addChainRemovedHandler(this.onChainRemoved);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
protected readonly onChainRemoved = (
|
|
54
|
-
const chainIdentifier = ChainIdHelper.parse(
|
|
53
|
+
protected readonly onChainRemoved = (chainId: string) => {
|
|
54
|
+
const chainIdentifier = ChainIdHelper.parse(chainId).identifier;
|
|
55
55
|
runInAction(() => {
|
|
56
56
|
this.tokenMap.delete(chainIdentifier);
|
|
57
57
|
});
|
|
@@ -64,20 +64,15 @@ export class TokenERC20Service {
|
|
|
64
64
|
}
|
|
65
65
|
);
|
|
66
66
|
|
|
67
|
-
protected validateChainInfo(chainInfo: ChainInfo) {
|
|
68
|
-
if (chainInfo.evm === undefined) {
|
|
69
|
-
throw new Error("The chain doesn't support evm");
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
67
|
async suggestERC20Token(env: Env, chainId: string, contractAddress: string) {
|
|
74
68
|
const modularChainInfo =
|
|
75
69
|
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
70
|
+
if (
|
|
71
|
+
modularChainInfo.type === "ethermint" ||
|
|
72
|
+
modularChainInfo.type === "evm"
|
|
73
|
+
) {
|
|
74
|
+
// EVM supported — ok
|
|
75
|
+
} else if (modularChainInfo.type === "starknet") {
|
|
81
76
|
if (modularChainInfo.starknet == null) {
|
|
82
77
|
throw new Error("Starknet chain info is not defined");
|
|
83
78
|
}
|
|
@@ -137,10 +132,12 @@ export class TokenERC20Service {
|
|
|
137
132
|
async setERC20Token(chainId: string, currency: AppCurrency): Promise<void> {
|
|
138
133
|
const modularChainInfo =
|
|
139
134
|
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
135
|
+
if (
|
|
136
|
+
modularChainInfo.type === "ethermint" ||
|
|
137
|
+
modularChainInfo.type === "evm"
|
|
138
|
+
) {
|
|
139
|
+
// EVM supported — ok
|
|
140
|
+
} else if (modularChainInfo.type === "starknet") {
|
|
144
141
|
if (modularChainInfo.starknet == null) {
|
|
145
142
|
throw new Error("Starknet chain info is not defined");
|
|
146
143
|
}
|
|
@@ -149,12 +149,12 @@ export class TokenScanService {
|
|
|
149
149
|
}
|
|
150
150
|
);
|
|
151
151
|
|
|
152
|
-
this.chainsService.addChainRemovedHandler((
|
|
152
|
+
this.chainsService.addChainRemovedHandler((chainId) => {
|
|
153
153
|
runInAction(() => {
|
|
154
154
|
for (const [vaultId, tokenScans] of this.vaultToMap.entries()) {
|
|
155
155
|
let prevTokenScans = tokenScans;
|
|
156
156
|
prevTokenScans = prevTokenScans.filter((scan) => {
|
|
157
|
-
return scan.chainId !==
|
|
157
|
+
return scan.chainId !== chainId;
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
this.vaultToMap.set(vaultId, prevTokenScans);
|
|
@@ -202,8 +202,9 @@ export class TokenScanService {
|
|
|
202
202
|
return;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
const
|
|
206
|
-
|
|
205
|
+
const modularChainInfo =
|
|
206
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
207
|
+
if (modularChainInfo.hideInUI) {
|
|
207
208
|
return;
|
|
208
209
|
}
|
|
209
210
|
|
|
@@ -239,8 +240,9 @@ export class TokenScanService {
|
|
|
239
240
|
return;
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
const
|
|
243
|
-
|
|
243
|
+
const modularChainInfo =
|
|
244
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
245
|
+
if (modularChainInfo.hideInUI) {
|
|
244
246
|
return;
|
|
245
247
|
}
|
|
246
248
|
|
|
@@ -299,7 +301,7 @@ export class TokenScanService {
|
|
|
299
301
|
const logChains: string[] = [];
|
|
300
302
|
|
|
301
303
|
for (const modularChainInfo of modularChainInfos) {
|
|
302
|
-
if (
|
|
304
|
+
if (modularChainInfo.linkedChainKey != null) {
|
|
303
305
|
if (processedLinkedChainKeys.has(modularChainInfo.linkedChainKey)) {
|
|
304
306
|
continue;
|
|
305
307
|
}
|
|
@@ -386,17 +388,23 @@ export class TokenScanService {
|
|
|
386
388
|
return;
|
|
387
389
|
}
|
|
388
390
|
|
|
389
|
-
if (
|
|
391
|
+
if (modularChainInfo.linkedChainKey != null) {
|
|
390
392
|
tokenScan.linkedChainKey = modularChainInfo.linkedChainKey;
|
|
391
393
|
}
|
|
392
394
|
|
|
393
|
-
if (
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
if (
|
|
396
|
+
modularChainInfo.type === "cosmos" ||
|
|
397
|
+
modularChainInfo.type === "ethermint" ||
|
|
398
|
+
modularChainInfo.type === "evm"
|
|
399
|
+
) {
|
|
400
|
+
if (modularChainInfo.hideInUI) {
|
|
396
401
|
return;
|
|
397
402
|
}
|
|
398
403
|
|
|
399
|
-
if (
|
|
404
|
+
if (
|
|
405
|
+
this.chainsService.isEvmOnlyChain(chainId) &&
|
|
406
|
+
modularChainInfo.type === "evm"
|
|
407
|
+
) {
|
|
400
408
|
const evmInfo = this.chainsService.getEVMInfoOrThrow(chainId);
|
|
401
409
|
const pubkey = await this.keyRingService.getPubKey(chainId, vaultId);
|
|
402
410
|
const ethereumHexAddress = `0x${Buffer.from(
|
|
@@ -433,7 +441,7 @@ export class TokenScanService {
|
|
|
433
441
|
BigInt(res.data.result).toString(10) !== "0"
|
|
434
442
|
) {
|
|
435
443
|
assets.push({
|
|
436
|
-
currency:
|
|
444
|
+
currency: modularChainInfo.evm.nativeCurrency,
|
|
437
445
|
amount: BigInt(res.data.result).toString(10),
|
|
438
446
|
});
|
|
439
447
|
}
|
|
@@ -507,7 +515,11 @@ export class TokenScanService {
|
|
|
507
515
|
assets,
|
|
508
516
|
});
|
|
509
517
|
}
|
|
510
|
-
} else
|
|
518
|
+
} else if (
|
|
519
|
+
modularChainInfo.type === "cosmos" ||
|
|
520
|
+
modularChainInfo.type === "ethermint"
|
|
521
|
+
) {
|
|
522
|
+
const cosmosInfo = modularChainInfo.cosmos;
|
|
511
523
|
const bech32Addresses: {
|
|
512
524
|
value: string;
|
|
513
525
|
coinType?: number;
|
|
@@ -539,7 +551,7 @@ export class TokenScanService {
|
|
|
539
551
|
const res = await simpleFetch<{
|
|
540
552
|
balances: { denom: string; amount: string }[];
|
|
541
553
|
}>(
|
|
542
|
-
|
|
554
|
+
cosmosInfo.rest,
|
|
543
555
|
`/cosmos/bank/v1beta1/balances/${bech32Address.value}?pagination.limit=1000`
|
|
544
556
|
);
|
|
545
557
|
|
|
@@ -548,8 +560,9 @@ export class TokenScanService {
|
|
|
548
560
|
|
|
549
561
|
const balances = res.data?.balances ?? [];
|
|
550
562
|
for (const bal of balances) {
|
|
551
|
-
const currency =
|
|
552
|
-
(cur
|
|
563
|
+
const currency = cosmosInfo.currencies.find(
|
|
564
|
+
(cur: { coinMinimalDenom: string }) =>
|
|
565
|
+
cur.coinMinimalDenom === bal.denom
|
|
553
566
|
);
|
|
554
567
|
|
|
555
568
|
// validate
|
|
@@ -577,7 +590,7 @@ export class TokenScanService {
|
|
|
577
590
|
}
|
|
578
591
|
}
|
|
579
592
|
}
|
|
580
|
-
} else if ("starknet"
|
|
593
|
+
} else if (modularChainInfo.type === "starknet") {
|
|
581
594
|
const { hexAddress: starknetHexAddress } =
|
|
582
595
|
await this.keyRingStarknetService.getStarknetKey(vaultId, chainId);
|
|
583
596
|
|
|
@@ -651,7 +664,7 @@ export class TokenScanService {
|
|
|
651
664
|
}
|
|
652
665
|
})
|
|
653
666
|
);
|
|
654
|
-
} else if ("bitcoin"
|
|
667
|
+
} else if (modularChainInfo.type === "bitcoin") {
|
|
655
668
|
const getBitcoinScanInfo = async (
|
|
656
669
|
vaultId: string,
|
|
657
670
|
chainId: string,
|
|
@@ -706,12 +719,12 @@ export class TokenScanService {
|
|
|
706
719
|
};
|
|
707
720
|
|
|
708
721
|
// TODO: 향후 여러 주소체계를 지원하는 체인이 추가되면 linkedChainKey와 관련된 로직은 별도의 함수로 분리가 필요할 것
|
|
709
|
-
if (
|
|
722
|
+
if (modularChainInfo.linkedChainKey != null) {
|
|
710
723
|
const linkedBitcoinChains = this.chainsService
|
|
711
724
|
.getModularChainInfos()
|
|
712
725
|
.filter((chainInfo) => {
|
|
713
726
|
return (
|
|
714
|
-
"bitcoin"
|
|
727
|
+
chainInfo.type === "bitcoin" &&
|
|
715
728
|
chainInfo.linkedChainKey === modularChainInfo.linkedChainKey
|
|
716
729
|
);
|
|
717
730
|
});
|
package/src/tx/service.ts
CHANGED
|
@@ -40,7 +40,15 @@ export class BackgroundTxService {
|
|
|
40
40
|
onFulfill?: (tx: any) => void;
|
|
41
41
|
}
|
|
42
42
|
): Promise<Uint8Array> {
|
|
43
|
-
const
|
|
43
|
+
const modularChainInfo =
|
|
44
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
45
|
+
if (
|
|
46
|
+
modularChainInfo.type !== "cosmos" &&
|
|
47
|
+
modularChainInfo.type !== "ethermint"
|
|
48
|
+
) {
|
|
49
|
+
throw new Error(`Not a cosmos chain: ${chainId}`);
|
|
50
|
+
}
|
|
51
|
+
const cosmosInfo = modularChainInfo.cosmos;
|
|
44
52
|
|
|
45
53
|
if (!options.silent) {
|
|
46
54
|
this.notification.create({
|
|
@@ -75,7 +83,7 @@ export class BackgroundTxService {
|
|
|
75
83
|
|
|
76
84
|
try {
|
|
77
85
|
const result = await simpleFetch<any>(
|
|
78
|
-
|
|
86
|
+
cosmosInfo.rest,
|
|
79
87
|
isProtoTx ? "/cosmos/tx/v1beta1/txs" : "/txs",
|
|
80
88
|
{
|
|
81
89
|
method: "POST",
|
|
@@ -103,7 +111,7 @@ export class BackgroundTxService {
|
|
|
103
111
|
() => {
|
|
104
112
|
return new Promise<void>((resolve, reject) => {
|
|
105
113
|
const txTracer = new TendermintTxTracer(
|
|
106
|
-
|
|
114
|
+
cosmosInfo.rpc,
|
|
107
115
|
"/websocket"
|
|
108
116
|
);
|
|
109
117
|
txTracer.addEventListener("close", () => {
|
|
@@ -166,13 +174,23 @@ export class BackgroundTxService {
|
|
|
166
174
|
}
|
|
167
175
|
|
|
168
176
|
async traceTx(chainId: string, txHash: string): Promise<any> {
|
|
169
|
-
const
|
|
177
|
+
const modularChainInfo =
|
|
178
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
179
|
+
if (
|
|
180
|
+
modularChainInfo.type !== "cosmos" &&
|
|
181
|
+
modularChainInfo.type !== "ethermint"
|
|
182
|
+
) {
|
|
183
|
+
throw new Error(`Not a cosmos chain: ${chainId}`);
|
|
184
|
+
}
|
|
170
185
|
const txHashBuffer = Buffer.from(txHash, "hex");
|
|
171
186
|
|
|
172
187
|
return await retry(
|
|
173
188
|
() => {
|
|
174
189
|
return new Promise<any>((resolve, reject) => {
|
|
175
|
-
const txTracer = new TendermintTxTracer(
|
|
190
|
+
const txTracer = new TendermintTxTracer(
|
|
191
|
+
modularChainInfo.cosmos.rpc,
|
|
192
|
+
"/websocket"
|
|
193
|
+
);
|
|
176
194
|
txTracer.addEventListener("close", () => {
|
|
177
195
|
// reject if ws closed before fulfilled
|
|
178
196
|
// 하지만 로직상 fulfill 되기 전에 ws가 닫히는게 되기 때문에
|
|
@@ -243,12 +261,11 @@ export class BackgroundTxService {
|
|
|
243
261
|
let message = e.message;
|
|
244
262
|
|
|
245
263
|
// Tendermint rpc error.
|
|
246
|
-
const
|
|
247
|
-
e.message
|
|
248
|
-
)
|
|
249
|
-
if (regResult && regResult.length === 4) {
|
|
264
|
+
const tendermintRpcErrorMessage =
|
|
265
|
+
BackgroundTxService.parseTendermintRpcErrorMessage(e.message);
|
|
266
|
+
if (tendermintRpcErrorMessage) {
|
|
250
267
|
// If error is from tendermint
|
|
251
|
-
message =
|
|
268
|
+
message = tendermintRpcErrorMessage;
|
|
252
269
|
}
|
|
253
270
|
|
|
254
271
|
try {
|
|
@@ -286,6 +303,37 @@ export class BackgroundTxService {
|
|
|
286
303
|
});
|
|
287
304
|
}
|
|
288
305
|
|
|
306
|
+
// Keep the Tendermint RPC parsing best-effort only and avoid regex backtracking
|
|
307
|
+
// on raw error strings from external nodes/libraries.
|
|
308
|
+
private static parseTendermintRpcErrorMessage(
|
|
309
|
+
message: string
|
|
310
|
+
): string | undefined {
|
|
311
|
+
if (!message.startsWith("code:")) {
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const messageIndex = message.indexOf("message:");
|
|
316
|
+
const dataIndex = message.indexOf("data:");
|
|
317
|
+
|
|
318
|
+
if (messageIndex < 0 || dataIndex < 0 || messageIndex > dataIndex) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const messageBody = message.slice(messageIndex + "message:".length);
|
|
323
|
+
const dataDelimiter =
|
|
324
|
+
messageBody.indexOf(", data:") >= 0 ? ", data:" : ",data:";
|
|
325
|
+
const dataDelimiterIndex = messageBody.indexOf(dataDelimiter);
|
|
326
|
+
|
|
327
|
+
if (dataDelimiterIndex < 0) {
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const dataMessage = messageBody
|
|
332
|
+
.slice(dataDelimiterIndex + dataDelimiter.length)
|
|
333
|
+
.trim();
|
|
334
|
+
return dataMessage.length > 0 ? dataMessage : undefined;
|
|
335
|
+
}
|
|
336
|
+
|
|
289
337
|
async waitStarknetTransaction(
|
|
290
338
|
chainId: string,
|
|
291
339
|
txHash: string
|
|
@@ -294,7 +342,7 @@ export class BackgroundTxService {
|
|
|
294
342
|
if (!modularChainInfo) {
|
|
295
343
|
throw new Error("Invalid chain id");
|
|
296
344
|
}
|
|
297
|
-
if (
|
|
345
|
+
if (modularChainInfo.type !== "starknet") {
|
|
298
346
|
throw new Error("Chain is not for starknet");
|
|
299
347
|
}
|
|
300
348
|
const starknet = modularChainInfo.starknet;
|
|
@@ -340,7 +388,7 @@ export class BackgroundTxService {
|
|
|
340
388
|
throw new Error("Invalid chain id");
|
|
341
389
|
}
|
|
342
390
|
|
|
343
|
-
if (
|
|
391
|
+
if (modularChainInfo.type !== "bitcoin") {
|
|
344
392
|
throw new Error("Chain is not for bitcoin");
|
|
345
393
|
}
|
|
346
394
|
|
|
@@ -33,11 +33,7 @@ export class BackgroundTxEthereumService {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
try {
|
|
36
|
-
const
|
|
37
|
-
const evmInfo = ChainsService.getEVMInfo(chainInfo);
|
|
38
|
-
if (!evmInfo) {
|
|
39
|
-
throw new Error("No EVM info provided");
|
|
40
|
-
}
|
|
36
|
+
const evmInfo = this.chainsService.getEVMInfoOrThrow(chainId);
|
|
41
37
|
|
|
42
38
|
const sendRawTransactionResponse = await simpleFetch<{
|
|
43
39
|
result?: string;
|
|
@@ -131,11 +127,15 @@ export class BackgroundTxEthereumService {
|
|
|
131
127
|
chainId: string,
|
|
132
128
|
txHash: string
|
|
133
129
|
): Promise<EthTxReceipt | null> {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
if (
|
|
130
|
+
const modularChainInfo =
|
|
131
|
+
this.chainsService.getModularChainInfoOrThrow(chainId);
|
|
132
|
+
if (
|
|
133
|
+
modularChainInfo.type !== "evm" &&
|
|
134
|
+
modularChainInfo.type !== "ethermint"
|
|
135
|
+
) {
|
|
137
136
|
return null;
|
|
138
137
|
}
|
|
138
|
+
const evmInfo = modularChainInfo.evm;
|
|
139
139
|
|
|
140
140
|
return await retry(
|
|
141
141
|
() => {
|
|
@@ -586,18 +586,16 @@ export class BackgroundTxExecutorService {
|
|
|
586
586
|
typeof browser !== "undefined"
|
|
587
587
|
? new URL(browser.runtime.getURL("/")).origin
|
|
588
588
|
: "extension";
|
|
589
|
-
const
|
|
590
|
-
const evmInfo = ChainsService.getEVMInfo(chainInfo);
|
|
591
|
-
if (!evmInfo) {
|
|
592
|
-
throw new KeplrError("direct-tx-executor", 142, "Not EVM chain");
|
|
593
|
-
}
|
|
589
|
+
const evmInfo = this.chainsService.getEVMInfoOrThrow(tx.chainId);
|
|
594
590
|
|
|
595
591
|
const unsignedTx = await fillUnsignedEVMTx(
|
|
596
592
|
origin,
|
|
597
593
|
evmInfo,
|
|
598
594
|
signer,
|
|
599
595
|
tx.txData,
|
|
600
|
-
tx.feeType ?? "average"
|
|
596
|
+
tx.feeType ?? "average",
|
|
597
|
+
tx.customPriorityFee,
|
|
598
|
+
tx.customGasPrice
|
|
601
599
|
);
|
|
602
600
|
|
|
603
601
|
const result = await this.keyRingEthereumService.signEthereumPreAuthorized(
|
package/src/tx-executor/types.ts
CHANGED
|
@@ -42,9 +42,17 @@ interface BackgroundTxBase {
|
|
|
42
42
|
error?: string;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export
|
|
45
|
+
export type EVMBackgroundTxFeeType = BackgroundTxFeeType | "custom";
|
|
46
|
+
|
|
47
|
+
interface EVMBackgroundTxBase extends Omit<BackgroundTxBase, "feeType"> {
|
|
48
|
+
feeType?: EVMBackgroundTxFeeType;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EVMBackgroundTx extends EVMBackgroundTxBase {
|
|
46
52
|
readonly type: BackgroundTxType.EVM;
|
|
47
53
|
txData: UnsignedTransaction;
|
|
54
|
+
customPriorityFee?: string;
|
|
55
|
+
customGasPrice?: string;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export interface CosmosBackgroundTx extends BackgroundTxBase {
|